gold linker: add custom output section
Christian Eggers
ceggers@gmx.de
Mon Nov 20 15:12:13 GMT 2023
Hi Nick,
On Monday, 20 November 2023, 15:42:35 CET, Nick Clifton wrote:
> Hi Christian,
>
> > In an application where I use the gold linker, I would like to add an extra section
> > in the executable file, where I could later "stamp" the build id (incremented number)
> > of our CI server (not to confuse with GNU build-id).
> >
> > I am looking for another method where I could do this after linking (e.g. by overwriting
> > a "dummy" default build id which has been inserted during compiling).
>
> You can use the objcopy command to add extra sections to an already linked
> executable. This will work regardless of which linker was used. eg
>
> objcopy --add-section .ci.buildid=/etc/build-id a.out a.new
I already considered this approach (because it sounds easy), but ...
> > The application
> > should then by able to read the stamped value at runtime.
>
> This might be an issue however. The problem is how to locate
> the new section. If it is the application itself that wants
> to read its own buildid then it is going to need some way to
> find the new section. Since loaders rarely load all of an
> executable file into memory you may find that things like
> the section header table are not present at run time.
... the application would need to open its own binary for reading (e.g.
using libbfd) and then locate the section with the build id (instead
of de-referencing a pointer to it). But libbfd is under GPL3, I cannot
use it in my (proprietary) application. Maybe elfcpp would fit?
> > While adding extra section is a well documented task for the BFD linker, I couldn't
> > find useful information for the gold linker. I already tried to insert a new section
> > in an object file generated by the compiler (like in [1]) or via the assembler
> > (like in [2]). In both cases in can see the newly created section in the object files
> > (via objdump -h), but they don't appear in the executable file created by ld.gold.
>
> This is probably happening because these new section(s) do not
> have the necessary attributes to mark them as being needed at
> run time. Thus gold thinks that they are not necessary and
> just omits from the final image.
>
> Try setting the ALLOC and LOAD flags on the new section(s) when
> you create them. The gold should recognise them as being needed.
It seems that I cannot set section flags with GCC (taken from [1]),
but ALLOC and LOAD are already set:
...
3 .note.foo 00000018 00000000 00000000 00000034 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
...
The same is for the ASM version (taken from [2]):
3 .swift2_protocol_conformances 00000000 00000000 00000000 00000034 2**0
CONTENTS, ALLOC, LOAD, CODE
Aarrgh. I made a mistake! I put both object files into a static library
(because this is how our application usually does). As nothing referenced
these object files (yet), they of course didn't go into the executable...
After providing the two objects files directly, both new section also
appear in the executable.
1 .note.foo 00000018 000001cc 000001cc 000001cc 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
29 .swift2_protocol_conformances 00000000 006d198c 006d198c 006d098c 2**0
CONTENTS, ALLOC, LOAD, CODE
Regarding my original question this means that I don't need to do anything special
for getting my custom sections linked into the final executable. And stamping the
real build id into the file should work simply with "objcopy --update-section <file-with-build-id>".
Final question: Is there anything I should consider regarding section naming
and type? Is it advisable to create a .note.COMPANY section (like in [1]),
or can a choose this freely. For stamping the build id using a shell script,
having only a (zero terminated) string in the section looks easier.
regards,
Christian
[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77609
[2] https://bugzilla.redhat.com/show_bug.cgi?id=927573#c17
More information about the Binutils
mailing list