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