Option to ignore symbol versioning?

Fangrui Song i@maskray.me
Wed Dec 25 23:14:00 GMT 2019


On 2019-12-24, Jeffrey Walton wrote:
>I want to avoid the memcpy/memmove workaround and "GLIBC_2.2.5 not
>defined in file". The system should have a new enough version of Glibc
>so the problem does not exist.
>
>I'm looking@the ld.so(8) man page options, but I don't see a env
>var to tell the linker to ignored it. (I'm looking for something like
>LD_IGNORE_SYMBOL_VERSIONS).
>
>How do I load the executable without those cursed versioned symbols?
>
>Jeff

Just A couple of days ago I noticed /DISCARD/ : { *(.gnu_version*) } in
the Linux kernel (arch/powerpc/kernel/vmlinux.lds.S).
For its use case, no .gnu.version* will actually be synthesized, but the
author added /DISCARD/ to suppress --orphan-handling=warn warnings:

   ld.bfd: warning: orphan section `.gnu.version_d' from `a.o' being placed in section `.gnu.version_d'
   ld.bfd: warning: orphan section `.gnu.version' from `a.o' being placed in section `.gnu.version'

I added support for lld (https://reviews.llvm.org/D71819).



For your use case, if we allow GNU ld to discard .gnu.version_r (it
currently doesn't)

   % cat a.c
   #include <string.h>
   char a[1];
   int main() { memcpy(a, a, 1); }
   
   % gcc -fuse-ld=bfd  a.c -Wl,-T,a.lds -o a -fno-builtin-memcpy   
   /usr/bin/ld.bfd: could not find section .gnu.version_r
   /usr/bin/ld.bfd: final link failed: nonrepresentable section on output
   collect2: error: ld returned 1 exit status

Run ld.bfd --verbose > a.lds to get the internal linker script, apply the following patch,
and the resulting executable should work.

@@ -21,3 +20,0 @@
-  .gnu.version    : { *(.gnu.version) }
-  .gnu.version_d  : { *(.gnu.version_d) }
-  .gnu.version_r  : { *(.gnu.version_r) }
@@ -239 +236 @@
-  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
+  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.gnu.version*) }

With my lld patch (https://reviews.llvm.org/D71819), the following
command succeeds.

% clang -fuse-ld=lld a.c -Wl,-T,a.lds -o a -fno-builtin-memcpy && ./a
% readelf -V a

No version information found in this file.

The gotcha is that all symbols will be bound to the default version
definition. If libc upgrades and some symbols' default versions change,
the resolved definitions may change. If such ABI issues are not a
concern, this scheme should work.



More information about the Binutils mailing list