forked from OSchip/llvm-project
[ELF] Default to -z start-stop-gc with a glibc "__libc_" special case
Change the default to facilitate GC for metadata section usage, so that they don't need SHF_LINK_ORDER or SHF_GROUP just to drop the unhelpful rule (if they want to be unconditionally retained, use SHF_GNU_RETAIN (`__attribute__((retain))`) or linker script `KEEP`). The dropped SHF_GROUP special case makes the behavior of -z start-stop-gc and -z nostart-stop-gc closer to GNU ld>=2.37 (https://sourceware.org/PR27451). However, we default to -z start-stop-gc (which actually matches more closely to GNU ld before 2015-10 https://sourceware.org/PR19167), which is different from modern GNU ld (which has the unhelpful rule to work around glibc). As a compensation, we special case `__libc_` sections as a workaround for glibc<2.34 (https://sourceware.org/PR27492). Since -z start-stop-gc as the default actually matches the traditional GNU ld behavior, there isn't much to be aware of. There was a systemd usage which has been fixed by https://github.com/systemd/systemd/pull/19144
This commit is contained in:
parent
5c729750a6
commit
6d2d3bd0a6
|
@ -1133,7 +1133,7 @@ static void readConfigs(opt::InputArgList &args) {
|
|||
config->zShstk = hasZOption(args, "shstk");
|
||||
config->zStackSize = args::getZOptionValue(args, OPT_z, "stack-size", 0);
|
||||
config->zStartStopGC =
|
||||
getZFlag(args, "start-stop-gc", "nostart-stop-gc", false);
|
||||
getZFlag(args, "start-stop-gc", "nostart-stop-gc", true);
|
||||
config->zStartStopVisibility = getZStartStopVisibility(args);
|
||||
config->zText = getZFlag(args, "text", "notext", true);
|
||||
config->zWxneeded = hasZOption(args, "wxneeded");
|
||||
|
|
|
@ -270,8 +270,11 @@ template <class ELFT> void MarkLive<ELFT>::run() {
|
|||
|
||||
if (isReserved(sec) || script->shouldKeep(sec)) {
|
||||
enqueue(sec, 0);
|
||||
} else if (!config->zStartStopGC && isValidCIdentifier(sec->name) &&
|
||||
!sec->nextInSectionGroup) {
|
||||
} else if ((!config->zStartStopGC || sec->name.startswith("__libc_")) &&
|
||||
isValidCIdentifier(sec->name)) {
|
||||
// As a workaround for glibc libc.a before 2.34
|
||||
// (https://sourceware.org/PR27492), retain __libc_atexit and similar
|
||||
// sections regardless of zStartStopGC.
|
||||
cNamedSections[saver.save("__start_" + sec->name)].push_back(sec);
|
||||
cNamedSections[saver.save("__stop_" + sec->name)].push_back(sec);
|
||||
}
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
# LINK_ORDER cnamed sections are not kept alive by the __start_* reference.
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
|
||||
# RUN: ld.lld --gc-sections %t.o -o %t
|
||||
# RUN: llvm-objdump --section-headers -t %t | FileCheck %s
|
||||
# RUN: ld.lld --gc-sections -z start-stop-gc -z nostart-stop-gc %t.o -o %t
|
||||
# RUN: llvm-objdump --section-headers -t %t | FileCheck %s
|
||||
|
||||
## With -z start-stop-gc, non-SHF_LINK_ORDER non-SHF_GROUP C identifier name
|
||||
## With -z start-stop-gc (default), non-SHF_LINK_ORDER C identifier name
|
||||
## sections are not retained by __start_/__stop_ references.
|
||||
# RUN: ld.lld --gc-sections %t.o -o %t
|
||||
# RUN: llvm-readelf -S -s %t | FileCheck %s --check-prefix=GC
|
||||
# RUN: ld.lld --gc-sections -z start-stop-gc %t.o -o %t1
|
||||
# RUN: llvm-readelf -S -s %t1 | FileCheck %s --check-prefix=GC
|
||||
|
||||
|
@ -44,4 +44,3 @@ _start:
|
|||
|
||||
.section yy,"ao",@progbits,.foo
|
||||
.quad 0
|
||||
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
## 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.
|
||||
## Check that group members are retained or discarded as a unit.
|
||||
|
||||
# REQUIRES: x86
|
||||
|
||||
|
@ -10,24 +8,40 @@
|
|||
|
||||
# RUN: echo ".global __start___data; __start___data:" > %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 -shared %t2.o --soname=t2 -o %t2.so
|
||||
# RUN: ld.lld %t.o --gc-sections -o %t2 %t2.so
|
||||
# RUN: llvm-readelf -s %t2 | FileCheck %s
|
||||
|
||||
## The referenced __data is retained.
|
||||
# CHECK: [[#%x,ADDR:]] {{.*}} __start___data
|
||||
# CHECK: [[#ADDR + 8]] {{.*}} __stop___data
|
||||
## __libc_atexit is retained even if there is no reference, as a workaround for
|
||||
## glibc<2.34 (BZ #27492).
|
||||
# CHECK: [[#%x,ADDR:]] {{.*}} __start___libc_atexit
|
||||
# CHECK: [[#ADDR + 8]] {{.*}} __stop___libc_atexit
|
||||
# CHECK: _start
|
||||
# CHECK: f
|
||||
# CHECK-NOT: g
|
||||
|
||||
## If -z nostart-stop-gc, sections whose names are C identifiers are retained by
|
||||
## __start_/__stop_ references.
|
||||
# RUN: ld.lld %t.o %t2.so --gc-sections -z nostart-stop-gc -o %t3
|
||||
# RUN: llvm-readelf -s %t3 | FileCheck %s --check-prefix=NOGC
|
||||
# NOGC: [[#%x,ADDR:]] {{.*}} __start___data
|
||||
# NOGC: [[#ADDR + 16]] {{.*}} __stop___data
|
||||
|
||||
.weak __start___data
|
||||
.weak __stop___data
|
||||
.weak __start___libc_atexit
|
||||
.weak __stop___libc_atexit
|
||||
|
||||
.section .text,"ax",@progbits
|
||||
.global _start
|
||||
_start:
|
||||
.quad __start___data - .
|
||||
.quad __stop___data - .
|
||||
.quad __start___libc_atexit - .
|
||||
.quad __stop___libc_atexit - .
|
||||
call f
|
||||
|
||||
.section __data,"axG",@progbits,f
|
||||
|
@ -45,3 +59,6 @@ f:
|
|||
.global g
|
||||
g:
|
||||
nop
|
||||
|
||||
.section __libc_atexit,"a",@progbits
|
||||
.quad 0
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# RUN: used_in_script : { *(used_in_script) } \
|
||||
# RUN: .text : { *(.text) } \
|
||||
# RUN: }" > %t.script
|
||||
# RUN: ld.lld -T %t.script -o %t.so %t.o --gc-sections
|
||||
# RUN: ld.lld -T %t.script -o %t.so %t.o --gc-sections -z nostart-stop-gc
|
||||
# RUN: llvm-objdump -h %t.so | FileCheck %s
|
||||
|
||||
# CHECK: Idx Name Size VMA Type
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
; RUN: llvm-as %s -o %t.o
|
||||
; RUN: ld.lld %t.o -o %t.so -shared
|
||||
; RUN: llvm-readelf -S %t.so | FileCheck %s
|
||||
; RUN: ld.lld %t.o -o %t.so -shared --gc-sections
|
||||
; RUN: ld.lld %t.o -o %t.so -shared --gc-sections -z nostart-stop-gc
|
||||
; RUN: llvm-readelf -S %t.so | FileCheck --check-prefix=GC %s
|
||||
|
||||
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
## If .text is retained, its referenced qux and .fred are retained as well.
|
||||
## fred_und is used (by .fred) and thus emitted.
|
||||
## Note, GNU ld does not retain qux.
|
||||
# RUN: ld.lld -r --gc-sections -e _start %t.o -o %tstart.ro
|
||||
# RUN: ld.lld -r --gc-sections -z nostart-stop-gc -e _start %t.o -o %tstart.ro
|
||||
# RUN: llvm-readelf -Ss %tstart.ro | FileCheck %s --check-prefix=KEEP_START
|
||||
|
||||
# KEEP_START: [ 1] .text
|
||||
|
|
Loading…
Reference in New Issue