0

共有ライブラリファイルの場合、シンボルの定義のファイルオフセットと仮想アドレスをどのように変換するのですか? 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; 
+0

あなたはGOTとPLTを認識していますか?あなたの正確な質問は分かりませんが、[htwsl](https://software.intel.com/sites/default/files/m/a/1/e/dsohowto.pdf)の講義は、 –

+0

"st_valuesが昇順に格納されるように処理された場合、st_value_1 ysdx

+0

@ysdx ELFのドキュメントによると、データオブジェクトの場合、st_sizeはオブジェクトに含まれるバイト数です。st_value1とst_value2の間には他のものがあります(suymbolテーブルには存在しません)。しかし、ルールは機能のために成立しないと私は思う。関数であるシンボルの場合、st_sizeは信頼できず、関数のサイズを取得する方法を見つけることができません。 – dudu

答えて

0

プログラム・ヘッダ・テーブルPT_LOADエントリは、ローダ/リンカーは、仮想アドレス空間内のELFファイルの部分をマッピングすることが期待される方法を定義します。例えば

 
~$ readelf -l /lib/i386-linux-gnu/libc-2.24.so 

Elf file type is DYN (Shared object file) 
Entry point 0x18400 
There are 10 program headers, starting at offset 52 

Program Headers: 
    Type   Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align 
    PHDR   0x000034 0x00000034 0x00000034 0x00140 0x00140 R E 0x4 
    INTERP   0x166374 0x00166374 0x00166374 0x00013 0x00013 R 0x4 
     [Requesting program interpreter: /lib/ld-linux.so.2] 
    LOAD   0x000000 0x00000000 0x00000000 0x1b01c8 0x1b01c8 R E 0x1000 
    LOAD   0x1b0260 0x001b1260 0x001b1260 0x02c74 0x0579c RW 0x1000 
    DYNAMIC  0x1b1db0 0x001b2db0 0x001b2db0 0x000f0 0x000f0 RW 0x4 
    NOTE   0x000174 0x00000174 0x00000174 0x00044 0x00044 R 0x4 
    TLS   0x1b0260 0x001b1260 0x001b1260 0x00008 0x00048 R 0x4 
    GNU_EH_FRAME 0x166388 0x00166388 0x00166388 0x061ec 0x061ec R 0x4 
    GNU_STACK  0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x10 
    GNU_RELRO  0x1b0260 0x001b1260 0x001b1260 0x01da0 0x01da0 R 0x1 

それだ(相対)仮想アドレスが0x0005df80あるこのシンボル

 
    Num: Value Size Type Bind Vis  Ndx Name 
    188: 0005df80 35 FUNC GLOBAL DEFAULT 13 [email protected]@GLIBC_2.1 

を考慮し、:あなたがファイル・オフセットと(相対)仮想メモリアドレスとの間で変換したい場合は、これを使用する必要があります。最初のPT_LOADエントリに属し、相対仮想メモリの範囲は0x00000000から0x00000000 + 0x1b01c8です。セグメント内のオフセットはValue - VirtAddr = 0x00000000です。ファイル内でオフセットされているので、PhysAddr + (Value - VirtAddr) = 0005df80です。

関連する問題