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