共有ライブラリファイルの場合、シンボルの定義のファイルオフセットと仮想アドレスをどのように変換するのですか? ELF文書でファイルオフセットと共有ライブラリの仮想アドレス
、シンボルテーブル内のシンボルのために、実行可能ファイルと共有オブジェクトファイルで
、
st_value
は仮想アドレスを保持しています。これらのファイルのシンボルをダイナミックリンカにとってより便利にするために、セクションオフセット(ファイル解釈)は、セクション番号が無関係な仮想アドレス(メモリ解釈)に影響します。
しかし、どのようにファイル内のオフセットを取得できますか?または、オフセットを与えられた場合、どのようにして仮想アドレス(メモリ解釈に対するファイル解釈)を計算できますか?
このようなシナリオを想像してみてください。プロセスの実行中に、共有ライブラリに実装されている関数、例えばlibx.soを使用していて、ライブラリファイルがvma
で表される領域にマップされているとします。
//addr holds the value of PC
offset = (vma->vm_pgoff << PAGE_SIZE) + addr -vma->vm_start;
私が今理解しているように、offset
は、ライブラリファイル内の命令のオフセットを保持しています。このオフセットを考えると、関数名を知りたいと思います。 1つの方法は、offset
に対応する仮想アドレスを計算し、その仮想アドレスをシンボルテーブルのst_value
と比較することです。 st_value
が昇順に格納されるように処理された場合、st_value_1 < virtual_address < st_value_2
はst_name_1が私が探しているものであることを意味します。ですから問題は変換にあります。
参考のために、シンボル・テーブル・エントリのデータ構造は以下の通りである:
typedef struct{
Elf32_Word st_name;
Elf32_Addr st_value;
Elf32_Word st_size;
unsigned char st_info;
unsigned char st_other;
Elf32_Half st_shndx;
}Elf32_Sym;
あなたはGOTとPLTを認識していますか?あなたの正確な質問は分かりませんが、[htwsl](https://software.intel.com/sites/default/files/m/a/1/e/dsohowto.pdf)の講義は、 –
"st_valuesが昇順に格納されるように処理された場合、st_value_1
ysdx
@ysdx ELFのドキュメントによると、データオブジェクトの場合、st_sizeはオブジェクトに含まれるバイト数です。st_value1とst_value2の間には他のものがあります(suymbolテーブルには存在しません)。しかし、ルールは機能のために成立しないと私は思う。関数であるシンボルの場合、st_sizeは信頼できず、関数のサイズを取得する方法を見つけることができません。 – dudu