From db7c82231c32074440d5426870051228435c6bce Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 21 Nov 2022 20:51:52 +0000 Subject: [PATCH] Restore global descriptor demangling after D138095 "[asan] Keep Itanium mangled names in global metadata" This amends commit 00be3578e0841dd9abe408e5b4946180de0bf46b to demangle symbol names in global descriptors. We keep the mangled name for the `__odr_gen_asan_*` variables and the runtime __cxa_demangle call site change (which fixed possible leaks for other scenarios: non-fatal diagnostics). compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp uses an undefined weak `__cxa_demangle` which does not pull in an archive definition. A -static-libstdc++ executable link does not get demangled names. Unfortunately this means we cannot rely on runtime demangling. See compiler-rt/test/asan/TestCases/global-demangle.cpp --- compiler-rt/lib/asan/asan_globals.cpp | 4 ++-- compiler-rt/test/asan/TestCases/Linux/odr_indicators.cpp | 4 ++-- llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp | 9 ++++----- llvm/test/Instrumentation/AddressSanitizer/local_alias.ll | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/compiler-rt/lib/asan/asan_globals.cpp b/compiler-rt/lib/asan/asan_globals.cpp index 69b64dc..2b4a9e0 100644 --- a/compiler-rt/lib/asan/asan_globals.cpp +++ b/compiler-rt/lib/asan/asan_globals.cpp @@ -148,7 +148,7 @@ static void CheckODRViolationViaIndicator(const Global *g) { for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) { if (g->odr_indicator == l->g->odr_indicator && (flags()->detect_odr_violation >= 2 || g->size != l->g->size) && - !IsODRViolationSuppressed(MaybeDemangleGlobalName(g->name))) + !IsODRViolationSuppressed(g->name)) ReportODRViolation(g, FindRegistrationSite(g), l->g, FindRegistrationSite(l->g)); } @@ -164,7 +164,7 @@ static void CheckODRViolationViaPoisoning(const Global *g) { for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) { if (g->beg == l->g->beg && (flags()->detect_odr_violation >= 2 || g->size != l->g->size) && - !IsODRViolationSuppressed(MaybeDemangleGlobalName(g->name))) + !IsODRViolationSuppressed(g->name)) ReportODRViolation(g, FindRegistrationSite(g), l->g, FindRegistrationSite(l->g)); } diff --git a/compiler-rt/test/asan/TestCases/Linux/odr_indicators.cpp b/compiler-rt/test/asan/TestCases/Linux/odr_indicators.cpp index cef6b99..583f6e6 100644 --- a/compiler-rt/test/asan/TestCases/Linux/odr_indicators.cpp +++ b/compiler-rt/test/asan/TestCases/Linux/odr_indicators.cpp @@ -11,11 +11,11 @@ int test_global_1; // INDICATOR1-DAG: Added Global{{.*}} name=test_global_1{{.*}} odr_indicator={{0x0*[^0]+.*$}} static int test_global_2; -// CHECK-DAG: Added Global{{.*}} name=_ZL13test_global_2 {{.*}} odr_indicator={{0xf+$}} +// CHECK-DAG: Added Global{{.*}} name=test_global_2{{.*}} odr_indicator={{0xf+$}} namespace { static int test_global_3; -// CHECK-DAG: Added Global{{.*}} name=_ZN12_GLOBAL__N_113test_global_3E {{.*}} odr_indicator={{0xf+$}} +// CHECK-DAG: Added Global{{.*}} name={{.*}}::test_global_3{{.*}} odr_indicator={{0xf+$}} } // namespace int main() { diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index bc8823a..a4d4cc7 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -2264,13 +2264,12 @@ bool ModuleAddressSanitizer::InstrumentGlobals(IRBuilder<> &IRB, Module &M, if (G->hasSanitizerMetadata()) MD = G->getSanitizerMetadata(); - // ASan runtime demangles Itanium mangled names, so keep the original name - // to prevent unneeded size increase of the string table. + // The runtime library tries demangling symbol names in the descriptor but + // functionality like __cxa_demangle may be unavailable (e.g. + // -static-libstdc++). So we demangle the symbol names here. std::string NameForGlobal = G->getName().str(); - if (!StringRef(NameForGlobal).startswith("_Z")) - NameForGlobal = llvm::demangle(NameForGlobal); GlobalVariable *Name = - createPrivateGlobalForString(M, NameForGlobal, + createPrivateGlobalForString(M, llvm::demangle(NameForGlobal), /*AllowMerging*/ true, kAsanGenPrefix); Type *Ty = G->getValueType(); diff --git a/llvm/test/Instrumentation/AddressSanitizer/local_alias.ll b/llvm/test/Instrumentation/AddressSanitizer/local_alias.ll index 550c2f1..ada8120 100644 --- a/llvm/test/Instrumentation/AddressSanitizer/local_alias.ll +++ b/llvm/test/Instrumentation/AddressSanitizer/local_alias.ll @@ -20,7 +20,7 @@ target triple = "x86_64-unknown-linux-gnu" ; CHECK-NOALIAS-NOT: private alias ; CHECK-INDICATOR: @___asan_gen_.1 = private unnamed_addr constant [2 x i8] c"a\00", align 1 ; CHECK-INDICATOR: @__odr_asan_gen_a = global i8 0, align 1 -; CHECK-INDICATOR: @___asan_gen_.4 = private unnamed_addr constant [6 x i8] c"_ZL1d\00", align 1 +; CHECK-INDICATOR: @___asan_gen_.4 = private unnamed_addr constant [2 x i8] c"d\00", align 1 ; CHECK-INDICATOR: @__odr_asan_gen__ZL1d = global i8 0, align 1 ; CHECK-ALIAS: @0 = private alias { [2 x i32], [24 x i8] }, ptr @a -- 2.7.4