Using gcc and ld on x86_64 linux I need to link against a newer version of a library (glibc 2.14) but the executable needs to run on a system with an older version (2.5). Since the only incompatible symbol is memcpy (needing memcpy@GLIBC_2.2.5 but the library providing memcpy@GLIBC_2.14), I would like to tell the linker that instead of taking the default version for memcpy, it should take an old version I specify.
I found a quite arkward way to do it: simply specify a copy of the old .so file at the linker command line. This works fine, but I don't like the idea of having multiple .so files (I could only make it work by specifying all old libraries I link to that also have references to memcpy) checked into the svn and needed by my build system.
So I am searching for a way to tell the linker to take the old versioned symbol.
Alternatives that don't work (well) for me are:
When thinking about all the jobs a linker does, it doesn't seem like a hard thing to imlpement, after all it has some code to figure out the default version of a symbol too.
Any other ideas that are on the same complexity level as a simple linker command line (like creating a simple linker script etc.) are welcome too, as long as they are not weird hacks like editing the resulting binary...
edit:
To conserve this for the future readers, additionally to the below ideas I found the option --wrap
to the linker, which might be useful sometimes too.
I found the following working solution. First create file memcpy.c:
#include <string.h>
/* some systems do not have newest memcpy@@GLIBC_2.14 - stay with old good one */
asm (".symver memcpy, memcpy@GLIBC_2.2.5");
void *__wrap_memcpy(void *dest, const void *src, size_t n)
{
return memcpy(dest, src, n);
}
No additional CFLAGS needed to compile this file. Then link your program with -Wl,--wrap=memcpy.