diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp --- a/lld/ELF/MarkLive.cpp +++ b/lld/ELF/MarkLive.cpp @@ -270,7 +270,11 @@ if (isReserved(sec) || script->shouldKeep(sec)) { enqueue(sec, 0); - } else if (isValidCIdentifier(sec->name)) { + } else if (sec->getSize() == 0 && sec->name.startswith("__llvm_prf_")) { + // libclang_rt-profile-* need GCC 11/Clang 13 to mark zero size + // __llvm_prf_* SHF_GNU_RETAIN. Without this workaround, + // -fprofile-generate/-fprofile-instr-generate linked programs may have + // spurious 'undefined hidden symbol: __start___llvm_prf_vnds' errors. cNamedSections[saver.save("__start_" + sec->name)].push_back(sec); cNamedSections[saver.save("__stop_" + sec->name)].push_back(sec); } diff --git a/lld/test/ELF/gc-sections-metadata-startstop.s b/lld/test/ELF/gc-sections-metadata-startstop.s --- a/lld/test/ELF/gc-sections-metadata-startstop.s +++ b/lld/test/ELF/gc-sections-metadata-startstop.s @@ -5,13 +5,13 @@ # RUN: ld.lld --gc-sections %t.o -o %t # RUN: llvm-objdump --section-headers -t %t | FileCheck %s +## Note: we used to retain C identifier name section xx due to __start_/__stop_. # CHECK: Sections: -# CHECK-NOT: yy -# CHECK: xx {{.*}} DATA +# CHECK-NOT: xx # CHECK-NOT: yy # CHECK: SYMBOL TABLE: -# CHECK: xx 0000000000000000 .protected __start_xx +# CHECK: w *UND* 0000000000000000 __start_xx # CHECK: w *UND* 0000000000000000 __start_yy .weak __start_xx diff --git a/lld/test/ELF/linkerscript/sections-gc2.s b/lld/test/ELF/linkerscript/sections-gc2.s --- a/lld/test/ELF/linkerscript/sections-gc2.s +++ b/lld/test/ELF/linkerscript/sections-gc2.s @@ -10,7 +10,6 @@ # CHECK: Idx Name Size VMA Type # CHECK-NEXT: 0 -# CHECK-NEXT: used_in_reloc # CHECK-NEXT: .text # CHECK-NEXT: .comment # CHECK-NEXT: .symtab diff --git a/lld/test/ELF/lto/section-name.ll b/lld/test/ELF/lto/section-name.ll --- a/lld/test/ELF/lto/section-name.ll +++ b/lld/test/ELF/lto/section-name.ll @@ -28,8 +28,7 @@ ; CHECK-NEXT: bar_section PROGBITS ; CHECK-NOT: zed_section +;; Note: we used to retain foo_section/bar_section due to __start_/__stop_. ; GC-NOT: zed_section ; GC-NOT: foo_section -; GC: bar_section PROGBITS -; GC-NOT: zed_section -; GC-NOT: foo_section +; GC-NOT: bar_section diff --git a/lld/test/ELF/relocatable-gc.s b/lld/test/ELF/relocatable-gc.s --- a/lld/test/ELF/relocatable-gc.s +++ b/lld/test/ELF/relocatable-gc.s @@ -47,18 +47,16 @@ # KEEP_START: [ 1] .text # KEEP_START-NEXT: [ 2] .rela.text -# KEEP_START-NEXT: [ 3] qux -# KEEP_START-NEXT: [ 4] .group -# KEEP_START-NEXT: [ 5] .fred -# KEEP_START-NEXT: [ 6] .rela.fred -# KEEP_START-NEXT: [ 7] .note.GNU-stack +# KEEP_START-NEXT: [ 3] .group +# KEEP_START-NEXT: [ 4] .fred +# KEEP_START-NEXT: [ 5] .rela.fred +# KEEP_START-NEXT: [ 6] .note.GNU-stack -# KEEP_START: Symbol table '.symtab' contains 10 entries: -# KEEP_START: 5: {{.*}} SECTION -# KEEP_START-NEXT: 6: {{.*}} 1 _start -# KEEP_START-NEXT: 7: {{.*}} 5 fred -# KEEP_START-NEXT: 8: {{.*}} UND __start_qux -# KEEP_START-NEXT: 9: {{.*}} UND fred_und +# KEEP_START: Symbol table '.symtab' contains 9 entries: +# KEEP_START: 5: {{.*}} 1 _start +# KEEP_START-NEXT: 6: {{.*}} 4 fred +# KEEP_START-NEXT: 7: {{.*}} UND __start_qux +# KEEP_START-NEXT: 8: {{.*}} UND fred_und .section qux,"a",@progbits .byte 0 diff --git a/lld/test/ELF/startstop-gccollect.s b/lld/test/ELF/startstop-gccollect.s --- a/lld/test/ELF/startstop-gccollect.s +++ b/lld/test/ELF/startstop-gccollect.s @@ -8,14 +8,17 @@ ## Check that foo and bar sections are not garbage collected, ## we do not want to reclaim sections if they are referred ## by __start_* and __stop_* symbols. -# RUN: ld.lld %t --gc-sections -o %tout -# RUN: llvm-objdump -d %tout | FileCheck --check-prefix=DISASM %s +# RUN: not ld.lld %t --gc-sections -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR1 --implicit-check-not=error: + +# ERR1: error: undefined symbol: __start_foo +# ERR1: error: undefined symbol: __stop_bar # RUN: echo ".global __start_foo; __start_foo:" > %t2.s # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t2.s -o %t2.o # RUN: ld.lld -shared %t2.o -o %t2.so -# RUN: ld.lld %t --gc-sections -o %tout %t2.so -# RUN: llvm-objdump -d %tout | FileCheck --check-prefix=DISASM %s +# RUN: not ld.lld %t %t2.so --gc-sections -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR2 --implicit-check-not=error: + +# ERR2: error: undefined symbol: __stop_bar # DISASM: <_start>: # DISASM-NEXT: callq {{.*}} <__start_foo>