まず、次のケースを考えてみましょう。
以下はプログラムです:
// test.cpp
extern "C" void printf(const char*, ...);
int main() {
printf("Hello");
}
以下はライブラリです。
// ext.cpp (the external library)
#include <iostream>
extern "C" void printf(const char* p, ...);
void printf(const char* p, ...) {
std::cout << p << " World!\n";
}
これで、上記のプログラムとライブラリを 2 つの異なる方法でコンパイルできます。
最初の方法は、外部ライブラリをリンクせずにプログラムをコンパイルすることです:
$ 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)
上記のプログラムを実行すると、次のように出力されます。
$ ./test
Hello
2 番目の方法は、外部ライブラリへのリンクを使用してプログラムをコンパイルすることです。
$ 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)
$ ./test
Hello World!
ご覧のとおり、最初のケースではプログラムはprintf
fromlibc.so
を使用しますが、2 番目のケースではprintf
fromを使用しlibext.so
ます。
私の質問は、最初のケースのように取得した実行可能ファイルと libext のオブジェクト コード (.so または .o のいずれか) から、2 番目のケースのように実行可能ファイルを取得することは可能ですか? 言い換えれば、後者で定義されているすべてのシンボルに対して、へのlibc.so
リンクをへのリンクに置き換えることは可能ですか?libext.so
**LD_PRELOAD による挿入は、私が望んでいるものではないことに注意してください。必要なライブラリに直接リンクされている実行可能ファイルを取得したい。最初のバイナリと、「静的に」挿入したい外部オブジェクトにしかアクセスできないという事実にもう一度下線を引きます **