cat > a.s <<e .globl _start; _start: ret .section .rodata.bar, "a" .global bar; bar: .quad 0x1122334455667788 e echo 'x = bar;' > a.t echo 'PROVIDE(x = bar);' > b.t # not used, but worth testing as a.s -o a.o ld.lld --gc-sections a.o a.t -o a.lld ld.bfd --gc-sections a.o a.t -o a.bfd ld.gold --gc-sections a.o a.t -o a.gold In gold and lld, the symbol assignment `x = bar;` retains .rodata.bar while BFD doesn't: ld.bfd: removing unused section '.rodata.bar' in file 'a.o' Perhaps gold and lld's behavior make more sense?
(In reply to Fangrui Song from comment #0) > Perhaps gold and lld's behavior make more sense? No. There is no use of x or bar in your testcase. If you change it to cat > a.s <<e .globl _start; _start: .dc.a x .section .rodata.bar, "a" .global bar; bar: .quad 0x1122334455667788 e echo 'x = bar;' > a.t ld.bfd --gc-sections a.o a.t -o a.bfd then .rodata.bar is kept. I believe that is the proper behaviour, and the other linkers wrong.
Interesting. BFD's behavior depends on whether the assigned symbol is referenced. Let's enhance the test. cat > a.s <<e .globl _start, y1, y2 _start: .dc.a x1 .section .rodata.y1, "a"; y1: .quad 0x1122334455667788 .section .rodata.y2, "a"; y2: .quad 0x1122334455667788 e echo 'x1 = y1; x2 = y2;' > a.t as a.s -o a.o ld.lld --gc-sections a.o a.t -o a.lld ld.bfd --gc-sections a.o a.t -o a.gc.bfd ld.bfd a.o a.t -o a.nogc.bfd ld.gold --gc-sections a.o a.t -o a.gold % readelf -Ws a.nogc.bfd | grep '[xy]' Symbol table '.symtab' contains 9 entries: Num: Value Size Type Bind Vis Ndx Name 1: 0000000000402008 0 NOTYPE GLOBAL DEFAULT 2 y2 2: 0000000000402008 0 NOTYPE GLOBAL DEFAULT 2 x2 5: 0000000000402000 0 NOTYPE GLOBAL DEFAULT 2 x1 8: 0000000000402000 0 NOTYPE GLOBAL DEFAULT 2 y1 % readelf -Ws a.gc.bfd | grep '[xy]' Symbol table '.symtab' contains 8 entries: Num: Value Size Type Bind Vis Ndx Name 1: 0000000000000000 0 NOTYPE GLOBAL DEFAULT ABS x2 4: 0000000000402000 0 NOTYPE GLOBAL DEFAULT 2 x1 7: 0000000000402000 0 NOTYPE GLOBAL DEFAULT 2 y1 x2 is non-zero in a GC link and zero in a no-GC link. There appears unusual: a live symbol's value can be very different when GC is enabled. Or, is this a clever trick to check whether a section is GCed?
I would say it's a minor bug that x2 is not removed along with y2. I don't care to fix that though.