mirror of
https://github.com/freebsd/freebsd-src
synced 2024-07-09 04:36:31 +00:00
Merge commit 9f85bc834b07 from llvm-project (by Nikita Popov):
[PPCMergeStringPool] Only replace constant once (#92996) In #88846 I changed this code to use RAUW to perform the replacement instead of manual updates -- but kept the outer loop, which means we try to perform RAUW once per user. However, some of the users might be freed by the RAUW operation, resulting in use-after-free. The case where this happens is constant users where the replacement might result in the destruction of the original constant. Fixes https://github.com/llvm/llvm-project/issues/92991. This fixes a possible crash when building crypto/openssh/sshkey.c for PowerPC targets. Reported by: cperciva PR: 276104 MFC after: 3 days
This commit is contained in:
parent
ff7de3b4d3
commit
f30188c468
|
@ -290,13 +290,6 @@ bool PPCMergeStringPool::mergeModuleStringPool(Module &M) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool userHasOperand(User *TheUser, GlobalVariable *GVOperand) {
|
||||
for (Value *Op : TheUser->operands())
|
||||
if (Op == GVOperand)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// For pooled strings we need to add the offset into the pool for each string.
|
||||
// This is done by adding a Get Element Pointer (GEP) before each user. This
|
||||
// function adds the GEP.
|
||||
|
@ -307,29 +300,13 @@ void PPCMergeStringPool::replaceUsesWithGEP(GlobalVariable *GlobalToReplace,
|
|||
Indices.push_back(ConstantInt::get(Type::getInt32Ty(*Context), 0));
|
||||
Indices.push_back(ConstantInt::get(Type::getInt32Ty(*Context), ElementIndex));
|
||||
|
||||
// Need to save a temporary copy of each user list because we remove uses
|
||||
// as we replace them.
|
||||
SmallVector<User *> Users;
|
||||
for (User *CurrentUser : GlobalToReplace->users())
|
||||
Users.push_back(CurrentUser);
|
||||
|
||||
for (User *CurrentUser : Users) {
|
||||
// The user was not found so it must have been replaced earlier.
|
||||
if (!userHasOperand(CurrentUser, GlobalToReplace))
|
||||
continue;
|
||||
|
||||
// We cannot replace operands in globals so we ignore those.
|
||||
if (isa<GlobalValue>(CurrentUser))
|
||||
continue;
|
||||
|
||||
Constant *ConstGEP = ConstantExpr::getInBoundsGetElementPtr(
|
||||
PooledStructType, GPool, Indices);
|
||||
LLVM_DEBUG(dbgs() << "Replacing this global:\n");
|
||||
LLVM_DEBUG(GlobalToReplace->dump());
|
||||
LLVM_DEBUG(dbgs() << "with this:\n");
|
||||
LLVM_DEBUG(ConstGEP->dump());
|
||||
GlobalToReplace->replaceAllUsesWith(ConstGEP);
|
||||
}
|
||||
Constant *ConstGEP =
|
||||
ConstantExpr::getInBoundsGetElementPtr(PooledStructType, GPool, Indices);
|
||||
LLVM_DEBUG(dbgs() << "Replacing this global:\n");
|
||||
LLVM_DEBUG(GlobalToReplace->dump());
|
||||
LLVM_DEBUG(dbgs() << "with this:\n");
|
||||
LLVM_DEBUG(ConstGEP->dump());
|
||||
GlobalToReplace->replaceAllUsesWith(ConstGEP);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
Loading…
Reference in New Issue
Block a user