RFC: generating a header using the linker (ASCII, ASCIZ commands)
Ulf Samuelsson
binutils@emagii.com
Tue Feb 14 18:12:06 GMT 2023
Den 2023-02-14 kl. 17:06, skrev Nick Clifton:
> Hi Ulf,
>
>>>> Note that if the linker can call an external tool to compute the CRC
>>>> based on the extracted text segment, and insert that into the
>>>> resulting ELF file.
>>>> then this is superior to running a utility afterwards.
>>>
>>> Actually -- there might be a way to do this: A linker plugin. The
>>> linker already
>>> has the architecture to support plugins, and you could create a new
>>> one which would
>>> scan the text section, compute a CRC and then insert the value into
>>> a header in the
>>> linked image...
>>>
>> OK, tell me more!
>
> Sure. The linker has the ability to run plugins via the use of the
> "-plugin <name>"
> command line option. Currently there are two known plugins for the
> linker. One is
> used to process the dependencies of static archives
> (ld/libdep_plugin.c in the
> binutils sources) and one is used to pass LTO enabled object files
> back to the compiler
> for recompilation (lto-plugin/ in the gcc sources).
>
> The big problem with linker plugins however is the total lack of
> documentation
> on how to write them. Until the day comes when somebody writes a
> manual the
> only documentation is the source code itself. The place to start is the
> include/plugin-api.h file which defines the interface between plugins
> and the
> linker. Then take a look at the plugin sources mentioned above and
> the ld/plugin.c
> source file which is the linker's side of the coin.
I think I can read the code, but:
What I would need help with is to extract the information from the
linker data.
1) Assume I created a variable, how do I pass the value of that variable
to the plugin?
2) The plugin needs to run after the linking process is complete, but
before it is emitted.
Which callback to use?
3) What is the data structure that contains the linked code, and how do
I pass it to the plugin.
4) If I have pointers to an expression, is there a function that returns
the calculated result.
======================
This is my idea of a CRC implementation:
I am thinking of generating a directive "CRC64" with parameters.
CRC64 ISO ',' <startaddress> ',' <endaddress>
CRC64 ECMA ',' <startaddress> ',' <endaddress>
CRC64 POLY '(' INT64 ')' ',' <startaddress> ',' <endaddress>
Only one such directive is allowed in a linker command file.
The command should:
* Check that the plugin is available
* immediately calculate the table used for CRC generation (2kB of data).
* Reserve room for a 64-bit word in the image (containing the CRC).
* Save the program counter for this word.
* Save <startaddress> and <endaddress> expressions in global pointers
======================
MOTIVATION
Once the linking process is completed, the <startaddress> and
<endaddress> needs to be computed
and passed to the plugin together with the <pc>.
I think you want your linker command file to look like:
startaddress = .;
.text {}
. = ALIGN(0x10000)
endaddress = .;
You always specify the startaddress as a parameter.
The second parameter can be the address of:
The byte following the segment: => CRC64 ISO , <startaddress> ,
<endaddress>
The last byte of the segment: => CRC64 ISO , <startaddress> ,
<endaddress> - 1
The size of the segment: => CRC64 ISO , <startaddress> ,
<endaddress> - <startaddress>
It seems that the first alternative means less writing for the user, so
this is what I plan to use.
Best Regards
Ulf Samuelsson
> In essence what a plugin does is provide a selection of callback
> functions to
> the linker. These functions are called at various stages of the link,
> and can do
> pretty much anything. Since plugins are shared objects, they have
> full access to
> the linker's run-time memory space and can muck about as they please.
> Of course
> plugins are expected to behave nicely.
>
> Cheers
> Nick
>
More information about the Binutils
mailing list