determining output section type

Rasmus Villemoes rasmus.villemoes@prevas.dk
Fri Nov 5 13:11:15 GMT 2021


On 04/11/2021 08.47, Rasmus Villemoes wrote:
> On 04/11/2021 03.01, Alan Modra wrote:
>> On Wed, Nov 03, 2021 at 01:40:52PM +0100, Rasmus Villemoes wrote:
>>> Hi
>>>
> 
>>> Is there some way in the linker script (or otherwise) to force .data to
>>> have type PROGBITS? I'd rather not need a post-processing step editing
>>> the ELF file, even if it could be done with objcopy or similar.
>>
>> No, I think you have already found the only way to get SHT_PROGBITS in
>> this case.  Incidentally, it isn't necessary that the input .data
>> section is non-empty, just that one is present.
>> I used
>>
>>     .data :
>>     {
>>       empty.o*(.data)
>>       ...
>>       .init_array and the like
>>       ...
>>       *(.data)
>>       ...
>>     }
>>
>> That makes the output section SHT_PROGBITS even though empty.o has a
>> zero size .data and I placed empty.o last on the ld command line.
>> This works with 2.35 and current mainline.
> 
> Hm, I wonder why that didn't work for me with an empty .data section and
> moving the whole *(.data) to the beginning...
> 
> Ah, found it: I was using --gc-sections, and obviously an empty input
> doesn't have any references to it. Wrapping the crtbegin.o(.data) in
> KEEP() makes it work.
> 
> Thanks, I think I now have something that will work without modifying
> the build system or the flags passed to ld.

So while implementing this workaround I stumbled on an inconsistency
between ld's documentation and how wildcards actually work (and are used
in linker scripts shipped with binutils itself).

ld/ld.texi [and
https://sourceware.org/binutils/docs/ld/Input-Section-Wildcards.html] says

  When a file name is matched with a wildcard, the wildcard characters
will not match a ‘/’ character

But in various linker script templates (and installed linker scripts)
one finds

    /* gcc uses crtbegin.o to find the start of
       the constructors, so we make sure it is
       first.  Because this is a wildcard, it
       doesn't matter if the user does not
       actually link against crtbegin.o; the
       linker won't look for a file to match a
       wildcard.  The wildcard also means that it
       doesn't matter which directory crtbegin.o
       is in.  */

    KEEP (*crtbegin.o(.ctors))

And that seems to be what is actually implemented; in my case the linker
is given

  /some/long/path/vx_crtbegin.o

and that is matched by the KEEP( *crtbegin.o(.data .data.*)) rule I've
added. So it's not even that there's some special case that a * at the
beginning means "match this filename in any directory".

Rasmus


More information about the Binutils mailing list