プロセスは共有ライブラリのアドレスをどのように知ることができますか?

プロセスは共有ライブラリのアドレスをどのように知ることができますか?

私が理解したのは、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.6lddlibc.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.6Cライブラリを選択していることがわかります。したがって、環境変数LD_LIBRARY_PATHは、動的リンクに実際に使用されるファイルを決定するために非常に重要です。

あなたができるもう一つのことは次のとおりですstrace

strace -o cat.trace /usr/bin/cat /etc/motd

このファイルは、cat.traceテーマプロセスで実行されたシステムコールを記録します。これらのいくつかはmmap()動的リンクとして表示されるファイルです。 Google経由で検索してください。lddmmap

追加データ: man ld.so

readelfコマンドがインストールされていること、インストールできること、またはコンパイルできることを確認してください。ランニングreadelf -a /usr/bin/cat。実際にELF仕様私が見るには理解できないようですが、一部 いいねELF形式情報そこに。それを探してください。

お持ちの場合musl libcmusl libcでコンパイルされた単純な実行可能ファイルに対して上記と同じ実験を実行して、それをインストールまたはインストールできることは非常に有益です。動的接続のように複雑なものでさえ、同じオペレーティングシステムで2つの異なる有効な実装を持つことができます。

おすすめ記事