私が理解したのは、Cソースコードをコンパイルすると、GCC / LDはコンパイル時にアドレスバインディングを実行します。通常、このアドレスは0から始まります。共有ライブラリから関数を呼び出すとき、コンパイラは共有ライブラリのアドレスをどのように事前に知ることができますか?私は共有ライブラリがロードされたときにアドレスを取得することを知っています。間違っていたら訂正してください。
ベストアンサー1
これを理解するのに役立ついくつかのことがあります。
ldd /usr/bin/cat
私のラップトップでは、出力は次のようになります。
1771 % ldd /usr/bin/cat
linux-vdso.so.1 (0x00007ffc37fba000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f1ea7018000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1ea73bc000)
動的接続のための実際のパスが何であるかを示す正規化されたパスがないことlinux-vdso.so.1
がわかります。libc.so.6
ldd
libc.so.6
やり直して確認して学ぶことができますが、ldd
少し変形すると次のようになります。
1790 % export LD_LIBRARY_PATH=/lib
1791 % ldd /usr/bin/cat
linux-vdso.so.1 (0x00007fff0a5a0000)
libc.so.6 => /lib/libc.so.6 (0x00007fa257535000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa2578d9000)
/lib64/ld-linux-x86-64.so.2
詳しく見ると、ダイナミックリンカー(この場合)が/lib/libc.so.6
Cライブラリを選択していることがわかります。したがって、環境変数LD_LIBRARY_PATHは、動的リンクに実際に使用されるファイルを決定するために非常に重要です。
あなたができるもう一つのことは次のとおりですstrace
。
strace -o cat.trace /usr/bin/cat /etc/motd
このファイルは、cat.trace
テーマプロセスで実行されたシステムコールを記録します。これらのいくつかはmmap()
動的リンクとして表示されるファイルです。 Google経由で検索してください。ldd
mmap
追加データ: man ld.so
。
readelf
コマンドがインストールされていること、インストールできること、またはコンパイルできることを確認してください。ランニングreadelf -a /usr/bin/cat
。実際にELF仕様私が見るには理解できないようですが、一部 いいねELF形式情報そこに。それを探してください。
お持ちの場合musl libc
musl libcでコンパイルされた単純な実行可能ファイルに対して上記と同じ実験を実行して、それをインストールまたはインストールできることは非常に有益です。動的接続のように複雑なものでさえ、同じオペレーティングシステムで2つの異なる有効な実装を持つことができます。