Я написал простую общую библиотеку:
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 = 0x201000 Это согласуется с выводом readelf -S libtest.so
.
Мы пропускаем 3 зарезервированных байта в GOT (связанные с функциями) и определяем, что абсолютный адрес some_func должен быть найден со смещением +0x18 (четвертый байт из GOT) во время выполнения.
Это согласуется с readelf -r libtest.so
.
Но инструкция 6c1 по дизассемблированию objdump показывает:
movabs $0xfff...dff580, %rdx
Я ожидаю, что исходный операнд будет содержать +0x18
(смещение от GOT, его адрес находится в rax
), но вместо этого он имеет какое-то большое отрицательное число.
Не могли бы вы объяснить, что он показывает это число, но не 0x18
?
objdump -dR libtest.so
проверить отсутствие перемещений в.text
. Ваш случай не просто GOT, это GOT + PLT; поэтому должен быть какой-то код для доступа к таблице PLT. Вы также можете проверить значения времени выполнения и код после загрузки библиотеки с помощью rtld с помощью gdb. - person osgx   schedule 04.10.2016