This is the mail archive of the
mailing list for the binutils project.
Changing version of dynsym symbols in an executable
- From: Alex Bligh <alex at alex dot org dot uk>
- To: binutils at sourceware dot org
- Cc: Alex Bligh <alex at alex dot org dot uk>
- Date: Fri, 10 Jan 2014 15:57:34 +0000
- Subject: Changing version of dynsym symbols in an executable
- Authentication-results: sourceware.org; auth=none
- Reply-to: Alex Bligh <alex at alex dot org dot uk>
I am trying to change the version number of undefined symbols referencing a
shared library in an ELF executable I am building.
An example is below. objtest.c is built against openssl 1.0.0. I want to
run the same objtest binary on several different systems (or at least
build multiple versions on the same build system). Though the DT_NEEDED
versioning is compatible (in fact the ABI is identical), the packagers
in their wisdom have each used a different version name on the
*SYMBOLS* under 3 different linux distributions. This results in a
warning every time the C utility is run, plus various bogus package
dependency problems from packaging scripts. I can get around the latter,
but not the former.
My first approach was to try to rename the symbols post link by using
objcopy --redefine-sym. However, unfortunately this does not redefine
symbols within the .dynsym table, only the .symtab table. Mailing list
archives suggest this is unlikely to be fixed and is hard.
My next approach was to attempt to rewrite the /required/ symbol versions,
but --version-script only seems to control the /exported/ symbol versions.
Another approach would be .symver and --wrap, but that doesn't sound
very practical for a library as large as openssl.
I have also tried (without success) various __asm__ symver statements
aliasing (e.g.) __COMPAT__SSL_new to SSL_new@ (i.e. an unversioned label),
but this then errors on link that the SSL_new@ does not exist.
The ideal solution would allow me to remove symbol versioning from specific
undefined symbols within the executable, or change them to a different
version at link time (i.e. generate 3 binaries with different versions).
A suboptimal but useful solution would remove all symbol versioning at
link time (note this would be needed at link time, or compile time for
objtest.c, not at compile time for the library).
Any ideas on how I can get around this? Changing the installed libraries
is not an option. Neither is static linking.
$ cat objtest.c
/* compile with gcc -o objtest objtest.c -lssl */
int main(char **argv, int argc)
SSL_CTX *ctx = SSL_CTX_new (SSLv23_method ());
SSL *ssl = SSL_new(ctx);
$ gcc -o objtest objtest.c -lssl
$ objdump -T objtest
objtest: file format elf64-x86-64
DYNAMIC SYMBOL TABLE:
0000000000000000 w D *UND* 0000000000000000 __gmon_start__
0000000000000000 w D *UND* 0000000000000000
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5
0000000000000000 DF *UND* 0000000000000000 OPENSSL_1.0.0 SSLv23_method
0000000000000000 DF *UND* 0000000000000000 OPENSSL_1.0.0 SSL_new
0000000000000000 DF *UND* 0000000000000000 OPENSSL_1.0.0 SSL_CTX_new