linker script, /DISCARD/ section and SHT_GROUP
Fangrui Song
i@maskray.me
Thu Nov 14 18:14:00 GMT 2019
On 2019-11-14, Serge Guelton wrote:
>On Thu, Nov 14, 2019@12:30:00PM +0000, Nick Clifton wrote:
>> Hi Serge,
>>
>> > I find this behavior relatively strange with respect to group semantic: we end
>> > up with a group with one of its member stripped, and the others happily living
>> > around.
>> >
>> > Surely, the /DISCARD/ section is incomplete, but I would have expected a
>> > warning, if not an error, in that case.
>> >
>> > Is my understanding correct or am I missing something?
>>
>> No this is a bug, or possibly a feature. Either the linker documentation
>> needs to be updated to say that the /DISCARD/ section is allowed to break
>> ELF section group semantics (a bad idea imho), or else we need to fix the
>> linker to generate either an error or a warning.
>>
>> My feeling is that the correct behaviour would be to discard the entire
>> group, but to also generate a warning indicating that only part of the
>> group was covered by the /DISCARD/ section.
>
>That's my feeling too. Or an error and suggest to discard the group?
>
>> But there is another complication. What should happen if one or more
>> of the sections are explicitly kept ? Ie:
>>
>> % cat b.script
>> SECTIONS
>> {
>> /DISCARD/ : { *(.myanote.foo) }
>> .mytext.foo : { KEEP (*(.mytext.foo)) }
>> .mynote.foo : { *(.mynote.foo) }
>> }
>>
>> % ld -T b.script a.o
>>
>> Now we have one section in the group that is deliberately discarded,
>> one that is deliberately kept, one that can be discarded if it is not
>> referenced, and one that is an orphan. What is the poor linker to do ?
>>
>> Complain to the user and say that the script cannot be honoured would
>> be my suggestion, but what do you think ?
>
>Yeah, an error looks like the way to go.
I'd consider it more of a feature. The ELF specification is written
without garbage collection in mind. With the reading that garbage
collection is *orthogonal* to section group selection, we can address some
use cases where particular sections need to be stripped. For example,
cat > a.s <<e
.globl anote_foo, foo, bss_foo, note_foo
.section .myanote.foo,"aG",%note,foo,comdat
anote_foo:
.byte 0
.section .mytext.foo,"axG",%progbits,foo,comdat
foo:
.fnstart
.cantunwind
bx lr
.fnend
.section .mybss.foo,"awG",%nobits,foo,comdat
bss_foo:
.byte 0
.section .mynote.foo,"G",%note,foo,comdat
note_foo:
.byte 0
e
cat > a.script <<e
SECTIONS { /DISCARD/ : { *(.ARM.exidx*) }}
e
# a.o -> a.o
ld --gc-sections a.o -T a.script -e foo -o a
The intention is to have no .ARM.exidx* in the output, though input
object files may include them.
If we place .debug_info or other metadata (whether or not have the
SHF_ALLOC flag) in the group, we can strip them individually without
affecting the whole group.
I am in favor of not having a warning or error, so that such use cases
can work out-of-the-box. Such information could probably be moved to
the --verbose output, if we do find that useful.
More information about the Binutils
mailing list