I am working on a project that uses the ftdi D2XX drivers to interface with the ENTTEC DMX usb pro device. The ftdi drivers (libftdi2xx.so.1.1.12 stored in /usr/local/lib/) are compiled against a version of glibc v2.14 or higher.
I am developing on debian 7 which only supports up to glibc v2.13. When executing the C code I have written (that makes calls to the ftdi drivers) it gives an error:
./a.out: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.14' not found (required by /usr/local/lib/libftd2xx.so)
This makes sense, knowing that the glibc version is incompatible. I have downloaded and installed the newest version of glibc (v2.17) to a temporary directory ('~/glibc-testing/install/lib/') on my computer and by using the call:
~/glibc-testing/install/lib/ld-linux-x86-64.so.2 --library-path ~/glibc-testing/install/lib/ ./a.out
With this call, I am able to run the C-code successfully.
I would like to compile this C-code to a shared library. It will be used to interface with the DMX device and will be called by a main application developed on C#.
I am not sure how to move forward. What it seems like I need to do is to tell the fdti driver to always use the newer glibc while letting the rest of the application use the normal libraries. The ftdi 2DXX drivers are only available precompiled (no source code available). Is there a way to link this pre-compiled program to the new library?
I have looked into options where I export LD_LIBRARY_PATH=/home/.../glibc/install/lib/ and I have had little success.
Thank you!
You can provide the missing functions in your own code, but note those are versioned, you can either provide a map file or do everything along with the code. Example:
#define SYMVER(ver, sym) __asm__(".symver " #sym "," #sym "@" #ver "\n")
SYMVER(GLIBC_2.14, foo);
int foo(int a, char *b)
{
return 4;
}
In order to figure out what to implement, you can use readelf:
readelf -s /usr/local/lib/libftd2xx.so | grep '@GLIBC_2\.14'
That's it, as far as functions go.
Now the tricky part is making the loader to believe it got the right library (unless you want to implement your own loader), for that you need to patch the library to remove the reference to GLIBC_2.14
, because it is going to look on the libc specifically.
There's several ways to proceed; by far the simplest is to replace GLIBC_2.14
with GLIBC_2.13
, just keep in mind that you need to define your symbols with the replacement version (i.e. GLIBC_2.13
), because versions are stored by reference.
With that your program should run.
Now, theoretically you could instead:
Parse the ELF file, find the the DYNAMIC
type entry in the program
headers, there search for a VERNEED
entry, and finally following
that one you should find the table of requirements where you can trim
the reference (also you can use the .gnu.version_r
section header
to get there if available).
Alternatively, you could write a loader that chains the standard
loader but uses ptrace
to override the lookup.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With