Skip to content

Commit d76e62f

Browse files
committed
[AddressSanitizer] Don't use weak linkage for __{start,stop}_asan_globals
It should not be necessary to use weak linkage for these. Doing so implies interposablity and thus PIC generates indirections and dynamic relocations, which are unnecessary and suboptimal. Aside from this, ASan instrumentation never introduces GOT indirection relocations where there were none before--only new absolute relocs in RELRO sections for metadata, which are less problematic for special linkage situations that take pains to avoid GOT generation. Patch By: mcgrathr Differential Revision: https://reviews.llvm.org/D80605
1 parent e5158b5 commit d76e62f

File tree

2 files changed

+31
-11
lines changed

2 files changed

+31
-11
lines changed

llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2072,10 +2072,23 @@ void ModuleAddressSanitizer::InstrumentGlobalsELF(
20722072
SetComdatForGlobalMetadata(G, Metadata, UniqueModuleId);
20732073
}
20742074

2075+
// This should never be called when there are no globals, by the logic that
2076+
// computes the UniqueModuleId string, which is "" when there are no globals.
2077+
// It's important that this path is only used when there are actually some
2078+
// globals, because that means that there will certainly be a live
2079+
// `asan_globals` input section at link time and thus `__start_asan_globals`
2080+
// and `__stop_asan_globals` symbols will definitely be defined at link time.
2081+
// This means there's no need for the references to them to be weak, which
2082+
// enables better code generation because ExternalWeakLinkage implies
2083+
// isInterposable() and thus requires GOT indirection for PIC. Since these
2084+
// are known-defined hidden/dso_local symbols, direct PIC accesses without
2085+
// dynamic relocation are always sufficient.
2086+
assert(!MetadataGlobals.empty());
2087+
assert(!UniqueModuleId.empty());
2088+
20752089
// Update llvm.compiler.used, adding the new metadata globals. This is
20762090
// needed so that during LTO these variables stay alive.
2077-
if (!MetadataGlobals.empty())
2078-
appendToCompilerUsed(M, MetadataGlobals);
2091+
appendToCompilerUsed(M, MetadataGlobals);
20792092

20802093
// RegisteredFlag serves two purposes. First, we can pass it to dladdr()
20812094
// to look up the loaded image that contains it. Second, we can store in it
@@ -2088,15 +2101,18 @@ void ModuleAddressSanitizer::InstrumentGlobalsELF(
20882101
ConstantInt::get(IntptrTy, 0), kAsanGlobalsRegisteredFlagName);
20892102
RegisteredFlag->setVisibility(GlobalVariable::HiddenVisibility);
20902103

2091-
// Create start and stop symbols.
2092-
GlobalVariable *StartELFMetadata = new GlobalVariable(
2093-
M, IntptrTy, false, GlobalVariable::ExternalWeakLinkage, nullptr,
2094-
"__start_" + getGlobalMetadataSection());
2095-
StartELFMetadata->setVisibility(GlobalVariable::HiddenVisibility);
2096-
GlobalVariable *StopELFMetadata = new GlobalVariable(
2097-
M, IntptrTy, false, GlobalVariable::ExternalWeakLinkage, nullptr,
2098-
"__stop_" + getGlobalMetadataSection());
2099-
StopELFMetadata->setVisibility(GlobalVariable::HiddenVisibility);
2104+
// Create start and stop symbols. These are known to be defined by
2105+
// the linker, see comment above.
2106+
auto MakeStartStopGV = [&](const char *Prefix) {
2107+
GlobalVariable *StartStop =
2108+
new GlobalVariable(M, IntptrTy, false, GlobalVariable::ExternalLinkage,
2109+
nullptr, Prefix + getGlobalMetadataSection());
2110+
StartStop->setVisibility(GlobalVariable::HiddenVisibility);
2111+
assert(StartStop->isImplicitDSOLocal());
2112+
return StartStop;
2113+
};
2114+
GlobalVariable *StartELFMetadata = MakeStartStopGV("__start_");
2115+
GlobalVariable *StopELFMetadata = MakeStartStopGV("__stop_");
21002116

21012117
// Create a call to register the globals with the runtime.
21022118
IRB.CreateCall(AsanRegisterElfGlobals,

llvm/test/Instrumentation/AddressSanitizer/global_metadata.ll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ target triple = "x86_64-unknown-linux-gnu"
2828
; during LTO.
2929
; CHECK: @llvm.compiler.used {{.*}} @__asan_global_global {{.*}} section "llvm.metadata"
3030

31+
; Check that start and stop symbols will be accessed as dso_local.
32+
; CHECK: @__start_asan_globals = external hidden global i64
33+
; CHECK: @__stop_asan_globals = external hidden global i64
34+
3135
; Check that location descriptors and global names were passed into __asan_register_globals:
3236
; CHECK: call void @__asan_register_elf_globals(i64 ptrtoint (i64* @___asan_globals_registered to i64), i64 ptrtoint (i64* @__start_asan_globals to i64), i64 ptrtoint (i64* @__stop_asan_globals to i64))
3337

0 commit comments

Comments
 (0)