From c8a1430e025ce942b6a1850fa6924bd23b732dd2 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 17 Feb 2021 19:22:25 -0800 Subject: [PATCH 1/3] [profile] Add __attribute__((used)) to zero size dummy sections D14468 added these dummy sections. This patch adds `__attribute__((used))` so that when compiled by GCC>=11 or (expected, D96838) Clang>=13 on some ELF platforms, these sections will get SHF_GNU_RETAIN to make sure they will not be discarded by ld --gc-sections. We are trying to get rid of LLD's "__start_/__stop_ references retain C identifier name sections" rule. If LLD drops the rule in the future (we will retain compatibility for `__llvm_prf_*` for a while), `__llvm_prf_*` will need to have the SHF_GNU_RETAIN flag, otherwise: ``` // __llvm_prf_cnts/__llvm_prf_data usually exist, but {names,vnds} may not exist. // Such diagnostics will happen with {cnts,data} as well if no input object file is instrumented. % clang++ -fprofile-generate a.cc -fuse-ld=lld -Wl,--gc-sections ld.lld: error: undefined hidden symbol: __start___llvm_prf_names >>> referenced by InstrProfilingPlatformLinux.c >>> InstrProfilingPlatformLinux.c.o:(__llvm_profile_begin_names) in archive /tmp/RelA/lib/clang/13.0.0/lib/linux/libclang_rt.profile-x86_64.a ... ``` Differential Revision: https://reviews.llvm.org/D96902 --- .../lib/profile/InstrProfilingPlatformLinux.c | 22 +++++++++++-------- compiler-rt/lib/profile/InstrProfilingPort.h | 2 ++ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c index c9fb481f8e90c..1d11eae421eff 100644 --- a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c +++ b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c @@ -36,15 +36,19 @@ extern char PROF_NAME_STOP COMPILER_RT_VISIBILITY; extern ValueProfNode PROF_VNODES_START COMPILER_RT_VISIBILITY; extern ValueProfNode PROF_VNODES_STOP COMPILER_RT_VISIBILITY; -/* Add dummy data to ensure the section is always created. */ -__llvm_profile_data - __prof_data_sect_data[0] COMPILER_RT_SECTION(INSTR_PROF_DATA_SECT_NAME); -uint64_t - __prof_cnts_sect_data[0] COMPILER_RT_SECTION(INSTR_PROF_CNTS_SECT_NAME); -uint32_t - __prof_orderfile_sect_data[0] COMPILER_RT_SECTION(INSTR_PROF_ORDERFILE_SECT_NAME); -const char __prof_nms_sect_data[0] COMPILER_RT_SECTION(INSTR_PROF_NAME_SECT_NAME); -ValueProfNode __prof_vnodes_sect_data[0] COMPILER_RT_SECTION(INSTR_PROF_VNODES_SECT_NAME); +/* Add dummy data to ensure the section is always created. Add used attribute so + * that they are linker GC roots on supported ELF platforms. + */ +__llvm_profile_data __prof_data_sect_data[0] COMPILER_RT_SECTION( + INSTR_PROF_DATA_SECT_NAME) COMPILER_RT_USED; +uint64_t __prof_cnts_sect_data[0] COMPILER_RT_SECTION(INSTR_PROF_CNTS_SECT_NAME) + COMPILER_RT_USED; +uint32_t __prof_orderfile_sect_data[0] COMPILER_RT_SECTION( + INSTR_PROF_ORDERFILE_SECT_NAME) COMPILER_RT_USED; +const char __prof_nms_sect_data[0] COMPILER_RT_SECTION( + INSTR_PROF_NAME_SECT_NAME) COMPILER_RT_USED; +ValueProfNode __prof_vnodes_sect_data[0] COMPILER_RT_SECTION( + INSTR_PROF_VNODES_SECT_NAME) COMPILER_RT_USED; COMPILER_RT_VISIBILITY const __llvm_profile_data * __llvm_profile_begin_data(void) { diff --git a/compiler-rt/lib/profile/InstrProfilingPort.h b/compiler-rt/lib/profile/InstrProfilingPort.h index cb66c5964ad1c..ed0905cc5f202 100644 --- a/compiler-rt/lib/profile/InstrProfilingPort.h +++ b/compiler-rt/lib/profile/InstrProfilingPort.h @@ -23,6 +23,7 @@ #define COMPILER_RT_FTRUNCATE(f,l) _chsize(_fileno(f),l) #define COMPILER_RT_ALWAYS_INLINE __forceinline #define COMPILER_RT_CLEANUP(x) +#define COMPILER_RT_USED #elif __GNUC__ #ifdef _WIN32 #define COMPILER_RT_FTRUNCATE(f, l) _chsize(fileno(f), l) @@ -37,6 +38,7 @@ #define COMPILER_RT_ALLOCA __builtin_alloca #define COMPILER_RT_ALWAYS_INLINE inline __attribute((always_inline)) #define COMPILER_RT_CLEANUP(x) __attribute__((cleanup(x))) +#define COMPILER_RT_USED __attribute__((used)) #endif #if defined(__APPLE__) From a13403d85ff83dbabd8e5a8a392ceef8e581c46f Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Wed, 17 Feb 2021 23:33:13 -0800 Subject: [PATCH 2/3] [profile] Make {__start_,__stop_}__llvm_prf_* symbols undefined weak To make a kind of metadata section usage work, we want to drop the `__start_/__stop_ references retain C identifier name sections` rule from LLD (see D96914). If an application has no `__llvm_prf_data` input section surviving --gc-sections, LLD will error for undefined hidden `{__start_,__stop_}__llvm_prf_*` from `libclang_rt.profile-*`. Other `__llvm_prf_*` sections have similar issues. Making the references weak can address the problem. This probably enables the opportunity to drop zero size dummy sections in `InstrProfilingPlatformLinux.c`. Reviewed By: davidxl Differential Revision: https://reviews.llvm.org/D96936 --- .../lib/profile/InstrProfilingPlatformLinux.c | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c index 1d11eae421eff..b63b4d40ac91e 100644 --- a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c +++ b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c @@ -26,15 +26,17 @@ /* Declare section start and stop symbols for various sections * generated by compiler instrumentation. */ -extern __llvm_profile_data PROF_DATA_START COMPILER_RT_VISIBILITY; -extern __llvm_profile_data PROF_DATA_STOP COMPILER_RT_VISIBILITY; -extern uint64_t PROF_CNTS_START COMPILER_RT_VISIBILITY; -extern uint64_t PROF_CNTS_STOP COMPILER_RT_VISIBILITY; -extern uint32_t PROF_ORDERFILE_START COMPILER_RT_VISIBILITY; -extern char PROF_NAME_START COMPILER_RT_VISIBILITY; -extern char PROF_NAME_STOP COMPILER_RT_VISIBILITY; -extern ValueProfNode PROF_VNODES_START COMPILER_RT_VISIBILITY; -extern ValueProfNode PROF_VNODES_STOP COMPILER_RT_VISIBILITY; +extern __llvm_profile_data PROF_DATA_START COMPILER_RT_VISIBILITY + COMPILER_RT_WEAK; +extern __llvm_profile_data PROF_DATA_STOP COMPILER_RT_VISIBILITY + COMPILER_RT_WEAK; +extern uint64_t PROF_CNTS_START COMPILER_RT_VISIBILITY COMPILER_RT_WEAK; +extern uint64_t PROF_CNTS_STOP COMPILER_RT_VISIBILITY COMPILER_RT_WEAK; +extern uint32_t PROF_ORDERFILE_START COMPILER_RT_VISIBILITY COMPILER_RT_WEAK; +extern char PROF_NAME_START COMPILER_RT_VISIBILITY COMPILER_RT_WEAK; +extern char PROF_NAME_STOP COMPILER_RT_VISIBILITY COMPILER_RT_WEAK; +extern ValueProfNode PROF_VNODES_START COMPILER_RT_VISIBILITY COMPILER_RT_WEAK; +extern ValueProfNode PROF_VNODES_STOP COMPILER_RT_VISIBILITY COMPILER_RT_WEAK; /* Add dummy data to ensure the section is always created. Add used attribute so * that they are linker GC roots on supported ELF platforms. From 9a83ae9312135e4117f7cbed303e0385ae2993a7 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Sun, 28 Feb 2021 21:07:30 -0800 Subject: [PATCH 3/3] [profile] Delete zero-size dummy sections They were added so that if no metadata section is present, `__start_llvm_prf_*` references would not cause "undefined symbol" errors. By switching to undefined weak symbols in D96936, the dummy sections are not needed. This patch is also needed to work around https://sourceware.org/bugzilla/show_bug.cgi?id=27490 Differential Revision: https://reviews.llvm.org/D97648 --- .../lib/profile/InstrProfilingPlatformLinux.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c index b63b4d40ac91e..07f3578dc43b1 100644 --- a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c +++ b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c @@ -38,20 +38,6 @@ extern char PROF_NAME_STOP COMPILER_RT_VISIBILITY COMPILER_RT_WEAK; extern ValueProfNode PROF_VNODES_START COMPILER_RT_VISIBILITY COMPILER_RT_WEAK; extern ValueProfNode PROF_VNODES_STOP COMPILER_RT_VISIBILITY COMPILER_RT_WEAK; -/* Add dummy data to ensure the section is always created. Add used attribute so - * that they are linker GC roots on supported ELF platforms. - */ -__llvm_profile_data __prof_data_sect_data[0] COMPILER_RT_SECTION( - INSTR_PROF_DATA_SECT_NAME) COMPILER_RT_USED; -uint64_t __prof_cnts_sect_data[0] COMPILER_RT_SECTION(INSTR_PROF_CNTS_SECT_NAME) - COMPILER_RT_USED; -uint32_t __prof_orderfile_sect_data[0] COMPILER_RT_SECTION( - INSTR_PROF_ORDERFILE_SECT_NAME) COMPILER_RT_USED; -const char __prof_nms_sect_data[0] COMPILER_RT_SECTION( - INSTR_PROF_NAME_SECT_NAME) COMPILER_RT_USED; -ValueProfNode __prof_vnodes_sect_data[0] COMPILER_RT_SECTION( - INSTR_PROF_VNODES_SECT_NAME) COMPILER_RT_USED; - COMPILER_RT_VISIBILITY const __llvm_profile_data * __llvm_profile_begin_data(void) { return &PROF_DATA_START;