forked from OSchip/llvm-project
[ASAN] Add the binder globals on Darwin to llvm.compiler.used to avoid LTO dead-stripping
The binder is in a specific section that "reverse" the edges in a regular dead-stripping: the binder is live as long as a global it references is live. This is a big hammer that prevents LLVM from dead-stripping these, while still allowing linker dead-stripping (with special knowledge of the section). Differential Revision: https://reviews.llvm.org/D24673 llvm-svn: 282988
This commit is contained in:
parent
9d4ed262ef
commit
6610b01a27
|
@ -1626,6 +1626,10 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) {
|
|||
// variable to the metadata struct.
|
||||
StructType *LivenessTy = StructType::get(IntptrTy, IntptrTy, nullptr);
|
||||
|
||||
// Keep the list of "Liveness" GV created to be added to llvm.compiler.used
|
||||
SmallVector<Constant *, 16> LivenessGlobals;
|
||||
LivenessGlobals.reserve(n);
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
GlobalVariable *Metadata = new GlobalVariable(
|
||||
M, GlobalStructTy, false, GlobalVariable::InternalLinkage,
|
||||
|
@ -1637,10 +1641,38 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) {
|
|||
Initializers[i]->getAggregateElement(0u),
|
||||
ConstantExpr::getPointerCast(Metadata, IntptrTy),
|
||||
nullptr);
|
||||
|
||||
// Recover the name of the variable this global is pointing to
|
||||
StringRef GVName =
|
||||
Initializers[i]->getAggregateElement(0u)->getOperand(0)->getName();
|
||||
|
||||
GlobalVariable *Liveness = new GlobalVariable(
|
||||
M, LivenessTy, false, GlobalVariable::InternalLinkage,
|
||||
LivenessBinder, "");
|
||||
M, LivenessTy, false, GlobalVariable::InternalLinkage, LivenessBinder,
|
||||
Twine("__asan_binder_") + GVName);
|
||||
Liveness->setSection("__DATA,__asan_liveness,regular,live_support");
|
||||
LivenessGlobals.push_back(
|
||||
ConstantExpr::getBitCast(Liveness, IRB.getInt8PtrTy()));
|
||||
}
|
||||
|
||||
if (!LivenessGlobals.empty()) {
|
||||
// Update llvm.compiler.used, adding the new liveness globals. This is
|
||||
// needed so that during LTO these variables stay alive. The alternative
|
||||
// would be to have the linker handling the LTO symbols, but libLTO
|
||||
// current
|
||||
// API does not expose access to the section for each symbol.
|
||||
if (GlobalVariable *LLVMUsed =
|
||||
M.getGlobalVariable("llvm.compiler.used")) {
|
||||
ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
|
||||
for (auto &V : Inits->operands())
|
||||
LivenessGlobals.push_back(cast<Constant>(&V));
|
||||
LLVMUsed->eraseFromParent();
|
||||
}
|
||||
llvm::ArrayType *ATy =
|
||||
llvm::ArrayType::get(IRB.getInt8PtrTy(), LivenessGlobals.size());
|
||||
auto *LLVMUsed = new llvm::GlobalVariable(
|
||||
M, ATy, false, llvm::GlobalValue::AppendingLinkage,
|
||||
llvm::ConstantArray::get(ATy, LivenessGlobals), "llvm.compiler.used");
|
||||
LLVMUsed->setSection("llvm.metadata");
|
||||
}
|
||||
} else {
|
||||
// On all other platfoms, we just emit an array of global metadata
|
||||
|
|
|
@ -22,7 +22,12 @@ target triple = "x86_64-apple-macosx10.11.0"
|
|||
; CHECK: [[METADATA:@[0-9]+]] = internal global {{.*}} @global {{.*}} section "__DATA,__asan_globals,regular", align 1
|
||||
|
||||
; Find the liveness binder for @global and its metadata:
|
||||
; CHECK: @{{[0-9]+}} = internal global {{.*}} @global {{.*}} [[METADATA]] {{.*}} section "__DATA,__asan_liveness,regular,live_support"
|
||||
; CHECK: @__asan_binder_global = internal global {{.*}} @global {{.*}} [[METADATA]] {{.*}} section "__DATA,__asan_liveness,regular,live_support"
|
||||
|
||||
; The binder has to be inserted to llvm.compiler.used to avoid being stripped
|
||||
; during LTO.
|
||||
; CHECK: @llvm.compiler.used {{.*}} @__asan_binder_global {{.*}} section "llvm.metadata"
|
||||
|
||||
|
||||
; Test that __asan_register_image_globals is invoked from the constructor:
|
||||
; CHECK-LABEL: define internal void @asan.module_ctor
|
||||
|
|
Loading…
Reference in New Issue