为什么dladdr在arm-linux上返回位置无关代码上的可执行文件的路径?

时间:2014-06-04 18:40:43

标签: c++ c arm fpic dladdr

我在我的一些代码中遇到了dladdr的问题,我使用Emdebian的g ++ - 4.7交叉编译器为armhf交叉编译arm-linux。问题似乎是,如果传递给dladdr的函数指针是一个也在可执行文件中调用的函数,dli_fname将返回可执行文件的路径,而不是符号来自的共享库。

通过以下方式编译的示例:

/ usr / bin / arm-linux-gnueabihf-g ++ - 4.7 main.cpp -o main -ldl -fPIC

#include <dlfcn.h>
#include <iostream>
#include <stdio.h>
#include <string>

std::string findLibName(void* funcPtr) {
  Dl_info info;
  if (dladdr(funcPtr,&info) != 0) {
    return std::string(info.dli_fname);
  } else {
    return ""; 
  }   
}

int main() {    
  printf("printf comes from %s\n",findLibName((void*)printf).c_str());
  return 0;
}

结果:printf来自./main

如果我将main()的主体更改为

int main() {    
  std::cout<<"printf comes from "<<findLibName((void*)printf)<<"\n";
  return 0;
}

结果:printf来自/lib/arm-linux-gnueabihf/libc.so.6

我注意到如果在可执行文件中调用了传递给dladdr的函数指针的函数,那么就是

的条目。
Relocation section '.rel.plt' at offset 0x63c contains 14 entries:
Offset     Info    Type            Sym.Value  Sym. Name
00010be8  00000d16 R_ARM_JUMP_SLOT   00008730   printf

是在可执行文件的.rel.plt部分创建的,看来dladdr正在从PLT中找到printf的这个地址,而不是通过GOT找到的libc.so.6中的正确地址。 dladdr man page建议将代码编译为位置无关应该解决这个问题,但这似乎不是这个编译器的情况。作为参考,上面显示的相同代码在使用g ++ - 4.7的x86_64 Linux上按预期工作。

0 个答案:

没有答案