First of all, consider the following case.
Below is a program:
// test.cppextern "C" void printf(const char*, ...);int main() { printf("Hello");}
Below is a library:
// ext.cpp (the external library)#include <iostream>extern "C" void printf(const char* p, ...);void printf(const char* p, ...) { std::cout << p << " World!\n";}
Now I can compile the above program and library in two different ways.
The first way is to compile the program without linking the external library:
$ g++ test.cpp -o test$ ldd test linux-gate.so.1 => (0xb76e8000) libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7518000) /lib/ld-linux.so.2 (0xb76e9000)
If I run the above program, it will print:
$ ./test Hello
The second way is to compile the program with a link to the external library:
$ g++ -shared -fPIC ext.cpp -o libext.so$ g++ test.cpp -L./ -lext -o test$ export LD_LIBRARY_PATH=./$ ldd test linux-gate.so.1 => (0xb773e000) libext.so => ./libext.so (0xb7738000) libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb756b000) libstdc++.so.6 => /usr/lib/i386-linux-gnu/libstdc++.so.6 (0xb7481000) /lib/ld-linux.so.2 (0xb773f000) libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xb743e000) libgcc_s.so.1 => /lib/i386-linux-gnu/libgcc_s.so.1 (0xb7421000)$ ./testHello World!
As you can see, in the first case the program uses printf
from libc.so
, while in the second case it uses printf
from libext.so
.
My question is: from the executable obtained as in the first case and the object code of libext (either as .so or .o), is it possible to obtain an executable like in the second case? In other words, is it possible to replace the link to libc.so
with a link to libext.so
for all symbols defined in the latter?
**Note that interposition via LD_PRELOAD is not what I want. I want to obtain an exectuable which is directly linked to the libraries I need. I underline again that fact the I only have access to the first binary and to the external object I want to "statically" interpose **