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.
|
// variable to the metadata struct.
|
||||||
StructType *LivenessTy = StructType::get(IntptrTy, IntptrTy, nullptr);
|
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++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
GlobalVariable *Metadata = new GlobalVariable(
|
GlobalVariable *Metadata = new GlobalVariable(
|
||||||
M, GlobalStructTy, false, GlobalVariable::InternalLinkage,
|
M, GlobalStructTy, false, GlobalVariable::InternalLinkage,
|
||||||
|
@ -1637,10 +1641,38 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) {
|
||||||
Initializers[i]->getAggregateElement(0u),
|
Initializers[i]->getAggregateElement(0u),
|
||||||
ConstantExpr::getPointerCast(Metadata, IntptrTy),
|
ConstantExpr::getPointerCast(Metadata, IntptrTy),
|
||||||
nullptr);
|
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(
|
GlobalVariable *Liveness = new GlobalVariable(
|
||||||
M, LivenessTy, false, GlobalVariable::InternalLinkage,
|
M, LivenessTy, false, GlobalVariable::InternalLinkage, LivenessBinder,
|
||||||
LivenessBinder, "");
|
Twine("__asan_binder_") + GVName);
|
||||||
Liveness->setSection("__DATA,__asan_liveness,regular,live_support");
|
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 {
|
} else {
|
||||||
// On all other platfoms, we just emit an array of global metadata
|
// 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
|
; CHECK: [[METADATA:@[0-9]+]] = internal global {{.*}} @global {{.*}} section "__DATA,__asan_globals,regular", align 1
|
||||||
|
|
||||||
; Find the liveness binder for @global and its metadata:
|
; 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:
|
; Test that __asan_register_image_globals is invoked from the constructor:
|
||||||
; CHECK-LABEL: define internal void @asan.module_ctor
|
; CHECK-LABEL: define internal void @asan.module_ctor
|
||||||
|
|
Loading…
Reference in New Issue