私は単純な共有ライブラリを書きました:
extern void some_func(void);
void
function(void)
{
some_func();
}
コンパイル/ビルド:
gcc -fPIC -mcmodel=large -c test.c -o test.o
gcc -fPIC -shared test.o -o libtest.so
some_func がどのように参照されているかを確認するために、逆アセンブルします。
$ objdump -d libtest.so
00000000000006a0 <function>:
6a0: 55 push %rbp
6a1: 48 89 e5 mov %rsp,%rbp
6a4: 41 57 push %r15
6a6: 48 83 ec 08 sub $0x8,%rsp
6aa: 48 8d 05 f9 ff ff ff lea -0x7(%rip),%rax # 6aa <function+0xa>
6b1: 49 bb 56 09 20 00 00 movabs $0x200956,%r11
6b8: 00 00 00
6bb: 4c 01 d8 add %r11,%rax
6be: 49 89 c7 mov %rax,%r15
6c1: 48 ba 80 f5 df ff ff movabs $0xffffffffffdff580,%rdx
6c8: ff ff ff
6cb: 48 01 c2 add %rax,%rdx
6ce: ff d2 callq *%rdx
6d0: 90 nop
6d1: 48 83 c4 08 add $0x8,%rsp
6d5: 41 5f pop %r15
6d7: 5d pop %rbp
6d8: c3 retq
どこ.got.plt
にあるかを見た:
$ readelf -S libtest.so
...
[21] .got.plt PROGBITS 0000000000201000 00001000
0000000000000020 0000000000000008 WA 0 0 8
...
移転とは:
$ readelf -r libtest.so
Relocation section '.rela.plt' at offset 0x538 contains 1 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000201018 000400000007 R_X86_64_JUMP_SLO 0000000000000000 some_func + 0
6aa
-で6bb
GOT の絶対位置を取得します: 6aa + 0x200956 = 0x201000readelf -S libtest.so
の出力と一致します。
GOT (関数関連) で予約済みの 3 バイトをスキップし、実行時に some_func の絶対アドレスが +0x18 (GOT から 4 番目のバイト) オフセットにあると判断します。
それは と一致しreadelf -r libtest.so
ます。
しかし、objdump の逆アセンブリの 6c1 命令は次のように表示されます。
movabs $0xfff...dff580, %rdx
ソース オペランドが+0x18
(GOT からのオフセット、そのアドレスは にあるrax
) 保持されると予想していますが、代わりに大きな負の数が含まれています。
その数字が何を示しているのか説明していただけます0x18
か?