From afafe70f43dbb614f336ccbede1c4bbb132ec658 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Tue, 6 May 2014 20:32:45 +0000 Subject: [PATCH] Include translation unit filename in global ctor symbol names. This makes it easier to see where a global ctor comes from, and it also makes ASan's init order analyzer output easier to understand. gcc does this too, but only in -fPIC mode for some reason. Don't do this for constructors with explicit init priority. Also prepend "sub_" before the 'I', that way regular constructors stay lexicographically after symbols with init priority (because ord('s') > ord('I')). gold seems to ignore the name of constructor symbols, and ld only looks at the symbol if it includes an init priority, which this patch doesn't change. Before: __GLOBAL_I_a Now: __GLOBAL_sub_I_myfile.cc git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@208128 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGDeclCXX.cpp | 19 ++++++++++++++++--- test/CodeGenCXX/deferred-global-init.cpp | 2 +- test/CodeGenCXX/global-init.cpp | 4 ++-- test/CodeGenCXX/globalinit-loc.cpp | 4 ++-- test/CodeGenCXX/init-priority-attr.cpp | 4 ++-- .../microsoft-abi-static-initializers.cpp | 4 ++-- test/CodeGenCXX/runtimecc.cpp | 2 +- ...ember-variable-explicit-specialization.cpp | 6 +++--- test/CodeGenObjCXX/arc-globals.mm | 2 +- 9 files changed, 30 insertions(+), 17 deletions(-) diff --git a/lib/CodeGen/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp index 5f8e8747ab..59129f6aee 100644 --- a/lib/CodeGen/CGDeclCXX.cpp +++ b/lib/CodeGen/CGDeclCXX.cpp @@ -17,6 +17,7 @@ #include "clang/Frontend/CodeGenOptions.h" #include "llvm/ADT/StringExtras.h" #include "llvm/IR/Intrinsics.h" +#include "llvm/Support/Path.h" using namespace clang; using namespace CodeGen; @@ -362,7 +363,7 @@ CodeGenModule::EmitCXXGlobalInitFunc() { // Compute the function suffix from priority. Prepend with zeroes to make // sure the function names are also ordered as priorities. std::string PrioritySuffix = llvm::utostr(Priority); - // Priority is always <= 65535 (enforced by sema).. + // Priority is always <= 65535 (enforced by sema). PrioritySuffix = std::string(6-PrioritySuffix.size(), '0')+PrioritySuffix; llvm::Function *Fn = CreateGlobalInitOrDestructFunction(*this, FTy, @@ -376,8 +377,20 @@ CodeGenModule::EmitCXXGlobalInitFunc() { } } - llvm::Function *Fn = - CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__I_a"); + // Include the filename in the symbol name. Including "sub_" matches gcc and + // makes sure these symbols appear lexicographically behind the symbols with + // priority emitted above. + SourceManager &SM = Context.getSourceManager(); + SmallString<128> FileName(llvm::sys::path::filename( + SM.getFileEntryForID(SM.getMainFileID())->getName())); + for (size_t i = 0; i < FileName.size(); ++i) { + // Replace everything that's not [a-zA-Z0-9._] with a _. This set happens + // to be the set of C preprocessing numbers. + if (!isPreprocessingNumberBody(FileName[i])) + FileName[i] = '_'; + } + llvm::Function *Fn = CreateGlobalInitOrDestructFunction( + *this, FTy, llvm::Twine("_GLOBAL__sub_I_", FileName)); CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, CXXGlobalInits); AddGlobalCtor(Fn); diff --git a/test/CodeGenCXX/deferred-global-init.cpp b/test/CodeGenCXX/deferred-global-init.cpp index c683ad26fc..f64f507ac9 100644 --- a/test/CodeGenCXX/deferred-global-init.cpp +++ b/test/CodeGenCXX/deferred-global-init.cpp @@ -11,6 +11,6 @@ void* bar() { return a; } // CHECK: load i8** @foo // CHECK: ret void -// CHECK-LABEL: define internal void @_GLOBAL__I_a +// CHECK-LABEL: define internal void @_GLOBAL__sub_I_deferred_global_init.cpp // CHECK: call void @__cxx_global_var_init() // CHECK: ret void diff --git a/test/CodeGenCXX/global-init.cpp b/test/CodeGenCXX/global-init.cpp index 69631c2789..a425923e9f 100644 --- a/test/CodeGenCXX/global-init.cpp +++ b/test/CodeGenCXX/global-init.cpp @@ -195,11 +195,11 @@ namespace test7 { // CHECK-NEXT: sub // CHECK-NEXT: store i32 {{.*}}, i32* @_ZN5test1L1yE -// CHECK: define internal void @_GLOBAL__I_a() section "__TEXT,__StaticInit,regular,pure_instructions" { +// CHECK: define internal void @_GLOBAL__sub_I_global_init.cpp() section "__TEXT,__StaticInit,regular,pure_instructions" { // CHECK: call void [[TEST1_Y_INIT]] // CHECK: call void [[TEST1_Z_INIT]] // rdar://problem/8090834: this should be nounwind -// CHECK-NOEXC: define internal void @_GLOBAL__I_a() [[NUW:#[0-9]+]] section "__TEXT,__StaticInit,regular,pure_instructions" { +// CHECK-NOEXC: define internal void @_GLOBAL__sub_I_global_init.cpp() [[NUW:#[0-9]+]] section "__TEXT,__StaticInit,regular,pure_instructions" { // CHECK-NOEXC: attributes [[NUW]] = { nounwind } diff --git a/test/CodeGenCXX/globalinit-loc.cpp b/test/CodeGenCXX/globalinit-loc.cpp index c6c27e379d..eb39aec94d 100644 --- a/test/CodeGenCXX/globalinit-loc.cpp +++ b/test/CodeGenCXX/globalinit-loc.cpp @@ -4,9 +4,9 @@ // Verify that the global init helper function does not get associated // with any source location. // -// CHECK: define internal void @_GLOBAL__I_a +// CHECK: define internal void @_GLOBAL__sub_I_globalinit_loc.cpp // CHECK: !dbg ![[DBG:.*]] -// CHECK: "_GLOBAL__I_a", i32 0, {{.*}}, i32 0} ; [ DW_TAG_subprogram ] [line 0] [local] [def] +// CHECK: "_GLOBAL__sub_I_globalinit_loc.cpp", i32 0, {{.*}}, i32 0} ; [ DW_TAG_subprogram ] [line 0] [local] [def] // CHECK: ![[DBG]] = metadata !{i32 0, i32 0, # 99 "someheader.h" class A { diff --git a/test/CodeGenCXX/init-priority-attr.cpp b/test/CodeGenCXX/init-priority-attr.cpp index b09c65e9ef..799a6ba20c 100644 --- a/test/CodeGenCXX/init-priority-attr.cpp +++ b/test/CodeGenCXX/init-priority-attr.cpp @@ -27,7 +27,7 @@ public: A C::a = A(); -// CHECK: @llvm.global_ctors = appending global [3 x { i32, void ()* }] [{ i32, void ()* } { i32 200, void ()* @_GLOBAL__I_000200 }, { i32, void ()* } { i32 300, void ()* @_GLOBAL__I_000300 }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }] +// CHECK: @llvm.global_ctors = appending global [3 x { i32, void ()* }] [{ i32, void ()* } { i32 200, void ()* @_GLOBAL__I_000200 }, { i32, void ()* } { i32 300, void ()* @_GLOBAL__I_000300 }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__sub_I_init_priority_attr.cpp }] // CHECK: _GLOBAL__I_000200() // CHECK: _Z3fooi(i32 3) @@ -38,7 +38,7 @@ A C::a = A(); // CHECK-NEXT: _Z3fooi(i32 1) // CHECK-NEXT: ret void -// CHECK: _GLOBAL__I_a() +// CHECK: _GLOBAL__sub_I_init_priority_attr.cpp() // CHECK: _Z3fooi(i32 1) // CHECK-NEXT: _Z3fooi(i32 4) // CHECK-NEXT: ret void diff --git a/test/CodeGenCXX/microsoft-abi-static-initializers.cpp b/test/CodeGenCXX/microsoft-abi-static-initializers.cpp index 0d336cf42c..ebe456a6b4 100644 --- a/test/CodeGenCXX/microsoft-abi-static-initializers.cpp +++ b/test/CodeGenCXX/microsoft-abi-static-initializers.cpp @@ -2,7 +2,7 @@ // CHECK: @llvm.global_ctors = appending global [2 x { i32, void ()* }] // CHECK: [{ i32, void ()* } { i32 65535, void ()* @"\01??__Efoo@?$B@H@@2VA@@A@YAXXZ" -// CHECK: { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }] +// CHECK: { i32, void ()* } { i32 65535, void ()* @_GLOBAL__sub_I_microsoft_abi_static_initializers.cpp }] struct S { S(); @@ -160,7 +160,7 @@ void force_usage() { // CHECK: call x86_thiscallcc void @"\01??1A@@QAE@XZ"{{.*}}foo // CHECK: ret void -// CHECK: define internal void @_GLOBAL__I_a() [[NUW]] { +// CHECK: define internal void @_GLOBAL__sub_I_microsoft_abi_static_initializers.cpp() [[NUW]] { // CHECK: call void @"\01??__Es@@YAXXZ"() // CHECK: ret void diff --git a/test/CodeGenCXX/runtimecc.cpp b/test/CodeGenCXX/runtimecc.cpp index 646c61e0fd..20448838f9 100644 --- a/test/CodeGenCXX/runtimecc.cpp +++ b/test/CodeGenCXX/runtimecc.cpp @@ -45,7 +45,7 @@ namespace test1 { // CHECK: declare arm_aapcscc void @__cxa_throw(i8*, i8*, i8*) -// CHECK-LABEL: define internal arm_aapcscc void @_GLOBAL__I_a() +// CHECK-LABEL: define internal arm_aapcscc void @_GLOBAL__sub_I_runtimecc.cpp() // CHECK: call arm_aapcscc void @__cxx_global_var_init() diff --git a/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp b/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp index 50772bf647..4ba8a37a60 100644 --- a/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp +++ b/test/CodeGenCXX/static-member-variable-explicit-specialization.cpp @@ -19,14 +19,14 @@ template<> int A::a = 10; // CHECK: { i32, void ()* } { i32 65535, void ()* @[[unordered4:[^ ]*]] }, // CHECK: { i32, void ()* } { i32 65535, void ()* @[[unordered5:[^ ]*]] }, // CHECK: { i32, void ()* } { i32 65535, void ()* @[[unordered6:[^ ]*]] }, -// CHECK: { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }] +// CHECK: { i32, void ()* } { i32 65535, void ()* @_GLOBAL__sub_I_static_member_variable_explicit_specialization.cpp }] template int A::a; // Unordered int b = foo(); int c = foo(); int d = A::a; // Unordered -// An explicit specialization is ordered, and goes in __GLOBAL_I_a. +// An explicit specialization is ordered, and goes in __GLOBAL_sub_I_static_member_variable_explicit_specialization.cpp. template<> struct A { static int a; }; int A::a = foo(); @@ -82,7 +82,7 @@ template int b::i; // CHECK: store {{.*}} @_Z1xIcE // CHECK: ret -// CHECK: define internal void @_GLOBAL__I_a() +// CHECK: define internal void @_GLOBAL__sub_I_static_member_variable_explicit_specialization.cpp() // We call unique stubs for every ordered dynamic initializer in the TU. // CHECK: call // CHECK: call diff --git a/test/CodeGenObjCXX/arc-globals.mm b/test/CodeGenObjCXX/arc-globals.mm index 84ea180bca..8ba3fb8f58 100644 --- a/test/CodeGenObjCXX/arc-globals.mm +++ b/test/CodeGenObjCXX/arc-globals.mm @@ -19,7 +19,7 @@ id global_obj = getObject(); // CHECK-NEXT: ret void id global_obj2 = getObject(); -// CHECK-LABEL: define internal void @_GLOBAL__I_a +// CHECK-LABEL: define internal void @_GLOBAL__sub_I_arc_globals.mm // CHECK: call i8* @objc_autoreleasePoolPush() // CHECK-NEXT: call void @__cxx_global_var_init // CHECK-NEXT: call void @__cxx_global_var_init1 -- 2.40.0