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,7 @@ if (isReserved(sec) || script->shouldKeep(sec)) { enqueue(sec, 0); - } else if (isValidCIdentifier(sec->name)) { + } else if (isValidCIdentifier(sec->name) && !sec->nextInSectionGroup) { 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-group-startstop.s b/lld/test/ELF/gc-sections-group-startstop.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/gc-sections-group-startstop.s @@ -0,0 +1,51 @@ +# REQUIRES: x86 +## Check that group members are retained or discarded as a unit, and +## sections whose names are C identifiers aren't considered roots if +## they're members of a group. + +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o +# RUN: ld.lld --gc-sections %t.o -o %t +# RUN: llvm-readelf -s %t | FileCheck %s + +# CHECK: aaa +# CHECK: meta_aaa +# CHECK: bbb +# CHECK: meta_bbb +# CHECK-NOT: ccc +# CHECK-NOT: meta_ccc +# CHECK: [[#%x,ADDR:]] {{.*}} __start_meta +# CHECK: [[#ADDR + 2]] {{.*}} __stop_meta + +.hidden __start_meta +.hidden __stop_meta +.global _start +.text +_start: + call __start_meta + call __stop_meta + call aaa + +.section meta,"axG",@progbits,aaa +meta_aaa: + nop + +.section .text.aaa,"ax",@progbits +aaa: + .long meta_aaa - . + call bbb + +.section meta,"axG",@progbits,bbb +meta_bbb: + nop + +.section .text.bbb,"ax",@progbits +bbb: + .long meta_bbb - . + +.section meta,"axG",@progbits,ccc +meta_ccc: + nop + +.section .text.ccc,"ax",@progbits +ccc: + .long meta_ccc - .