ld: rebinding refs to A to symbol B
Richard Earnshaw (lists)
Richard.Earnshaw@arm.com
Wed Jan 29 10:45:56 GMT 2025
Some background first.
Older implementations of the Arm architecture lack primitives for synchronizing reads and writes across CPUs (there was no multi-processor concept back then). This was addressed with the introduction of multi-processor cores, but even then it wasn't done in a way compatible with the current architecture. For compiler support of __sync_synchronize we therefore need to chose, potentially at link time, which implementation to use.
The code to handle this is built into libgcc, which provides four sync primitives: __sync_synchronize_none, __sync_synchronize_cp15dmb and __sync_synchronize_dmb provide the specific implementations for each architecture variant (the first is only usable in apps that do not have threading, but that's enough for many simple programs); the fourth function, __sync_synchronize itself, will use a DMB if that's available, but otherwise will be a stub that creates a link time warning telling the user to chose something specific:
.section .gnu.warning.__sync_synchronize
.align 0
.ascii "This implementation of __sync_synchronize is a stub with "
.ascii "no effect. Relink with\n"
.ascii " -specs=sync-{none,dmb,cp15dmb}.specs\n"
.ascii "to specify exactly which barrier format to use and avoid "
.ascii "this warning\0"
and then we provide some simple specs files that will do the rebinding. These specs files contain something like:
%rename link sync_sync_link
*link:
%{!nostdlib|lgcc: --defsym=__sync_synchronize=__sync_synchronize_none} %(sync_sync_link)
Which has the effect of overriding the options to the linker so that it passes --defsym... whenever libgcc is linked into the binary.
This all works fine except for one minor issue. The defsym creates a symbol entry and reference in the image even if the function is never needed, which wastes (a small amount of) space in the final image.
So finally, to my question: is there a better way of doing this, such that the rebinding does not create an unresolved reference? I looked at --wrap, but that isn't really suitable here as I need to be able to pick from three target functions, and being forced to have __wrap in the name isn't really desirable either.
I guess what I'm looking for is something like --rename=A=B, which would operate very much like defsym but would be ignored if A is never referenced in the link set.
Do we have anything like that?
R.
More information about the Binutils
mailing list