PLT代码中的Segfault。有什么想法吗?

时间:2017-11-19 23:30:09

标签: c++ c assembly shared-libraries

我有一个共享库,可以通过调用以下函数来初始化:

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

的PLT函数的反汇编
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中的条目没有被重新定位的任何想法?

非常感谢!

1 个答案:

答案 0 :(得分:1)

我的图书馆被证明有未定义的符号。

这阻止了动态链接加载程序成功更新GOT,并且编译时偏移量保留在内存中。在运行时,这些地址无效并导致段错误。