This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: Option to ignore symbol versioning?
- From: Fangrui Song <i at maskray dot me>
- To: Jeffrey Walton <noloader at gmail dot com>
- Cc: Binutils <binutils at sourceware dot org>
- Date: Wed, 25 Dec 2019 15:14:03 -0800
- Subject: Re: Option to ignore symbol versioning?
- References: <CAH8yC8mp8kSrpXtaBUpJvrZbndNBwGPy=G0qt-dVn0aYbxz8HQ@mail.gmail.com>
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.