我有一个共享库,可以通过调用以下函数来初始化:
extern "C" {
int pa__init(pa_module *m) {
m->userdata = new PAModule(m);
return 0;
}
} // extern "C"
它被编译成这个(地址是编译时间偏移):
0000000000064717 <pa__init>:
[...]
64726: bf 40 00 00 00 mov $0x40,%edi
6472b: e8 e0 cb ff ff callq 61310 <operator new(unsigned long)@plt>
64730: 48 89 c3 mov %rax,%rbx
64733: 48 8b 45 d8 mov -0x28(%rbp),%rax
64737: 48 89 c6 mov %rax,%rsi
6473a: 48 89 df mov %rbx,%rdi
6473d: e8 2e e1 ff ff callq 62870 <PAModule::PAModule(pa_module*)@plt>
[...]
这是在编译时偏移61310
:
0000000000061310 <operator new(unsigned long)@plt>:
61310: ff 25 a2 c1 66 00 jmpq *0x66c1a2(%rip) # 6cd4b8 <operator new(unsigned long)@@Base+0x57f708>
61316: 68 94 02 00 00 pushq $0x294
6131b: e9 a0 d6 ff ff jmpq 5e9c0 <.plt>
当我加载库并调用此方法时,我在编译时偏移61310
得到段错误:
#0 0x0000000000061316 in ?? ()
#1 0x00007fd9faae9730 in pa__init (m=0x55f1a750d850) at pa_module.cpp:24
[...]
GOT在编译时偏移6cd4b8
(在运行时重新定位到例如0x7fced7ffa4b8
)的值是
0x7fced7ffa4b8: 0x00061316
处理器尝试跳转到该位置。但是,这仍然是编译时间偏移(指向无效内存),这就是程序段错误的原因。
加载我的库时,为什么GOT中的条目没有被重新定位的任何想法?
非常感谢!
答案 0 :(得分:1)
我的图书馆被证明有未定义的符号。
这阻止了动态链接加载程序成功更新GOT,并且编译时偏移量保留在内存中。在运行时,这些地址无效并导致段错误。