実行時に呼び出される共有ライブラリをロードするために関数を使用dll.c
するソースファイルがあるとします。dlopen
dlsym
F.so
dll.c
見積もりsome_function()
をしてF.so
定義を下げますsome_function()
。
下の図は、次のprog
ようにして取得した実行可能オブジェクトであると仮定します。
linux> gcc -rdynamic -o prog dll.c -ldl
so部分には、プログラムがロードされ、呼び出しを開始するときに解決する必要がある.text
参照が含まれています。some_function()
F.so
some_function()
私の質問は次のとおりです
参照を確認できるように、RAM(実行ファイルがメモリにコピーされる部分)の
.text
一部(含まれている部分)some_function()
を動的リンカーによって変更する必要があるようです。私が理解したことは正しいですか?some_function()
動的リンカーが
.text
RAMの一部を変更する必要がある場合はどうすればよいですか?私が理解したところによると、.text
セクションはRAMの読み取り専用セグメントです。読み取り専用セグメントを読み取り専用とすると、どのように修正しますか?
答え1
図に欠けているELFの2つの機能、GOT(グローバルオフセットテーブル)とPLT(プロシージャ接続テーブル)が動的接続に使用されます。 GOTはさまざまな用途に使用されるオフセットテーブル、PLTは間接ジャンプに使用されるプロシージャスタブテーブルです。 GOTは通常読み書きです。 PLTは読み取り/書き込みまたは読み取り専用です(その後、GOTエントリまたは個々のPLT関連GOTでサポートされています)。
これにより、動的リンカーは読み取り専用データに触れることなくシンボルアドレスを更新できます。
一部の古いバイナリでは、読み取り専用セグメントの再配置データを変更する必要があります。これは動的リンカーでは問題ではありませんが、これはメモリ内の対応するメモリ領域をプロセス間で共有できなくなることを意味します。
バラより共有ライブラリの作成方法もっと学ぶ。
答え2
A.1
.text
CPUによってコードの呼び出し部分はsome_function()
一種の間接呼び出しになります。実行時にアドレスを計算し、効率のために結果をキャッシュすることもできます。これ.text
により、不変性を維持し共有することができます。コードは通常少し大きくて遅いです。
A2
この仮定は間違っているため問題は発生しません。ただし、カーネルがメモリページをコピーし、異なる読み取り/書き込み/実行属性を提供し、新しいページを同じアドレスにマップすることを防ぐことはできません。たとえば、ptrace
システムコールを介してこれを実行したり、デバッガでソフトウェアブレークポイントを設定したりできます。