[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:
Mehdi Amini 2016-10-01 00:05:34 +00:00
parent 9d4ed262ef
commit 6610b01a27
2 changed files with 40 additions and 3 deletions

View File

@ -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

View File

@ -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