mirror of
https://github.com/freebsd/freebsd-src
synced 2024-07-24 11:47:20 +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;
|
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.
|
// 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
|
// This is done by adding a Get Element Pointer (GEP) before each user. This
|
||||||
// function adds the GEP.
|
// 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), 0));
|
||||||
Indices.push_back(ConstantInt::get(Type::getInt32Ty(*Context), ElementIndex));
|
Indices.push_back(ConstantInt::get(Type::getInt32Ty(*Context), ElementIndex));
|
||||||
|
|
||||||
// Need to save a temporary copy of each user list because we remove uses
|
Constant *ConstGEP =
|
||||||
// as we replace them.
|
ConstantExpr::getInBoundsGetElementPtr(PooledStructType, GPool, Indices);
|
||||||
SmallVector<User *> Users;
|
LLVM_DEBUG(dbgs() << "Replacing this global:\n");
|
||||||
for (User *CurrentUser : GlobalToReplace->users())
|
LLVM_DEBUG(GlobalToReplace->dump());
|
||||||
Users.push_back(CurrentUser);
|
LLVM_DEBUG(dbgs() << "with this:\n");
|
||||||
|
LLVM_DEBUG(ConstGEP->dump());
|
||||||
for (User *CurrentUser : Users) {
|
GlobalToReplace->replaceAllUsesWith(ConstGEP);
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
Loading…
Reference in a new issue