[英]Finding the load address of a shared library in Linux
在运行时,我需要打印出一个地址,然后找到该地址属于哪个 function。 这些函数位于共享库中,因此不在固定地址。 我的 map 文件显然只显示了每个共享库函数的相对偏移量。 是否可以在运行时查询已加载库的位置,以便我可以从地址中减去该值以获得正确的 map 文件偏移量?
目前我正在做一个有点hacky的方法,我还打印出库中一个 function 的地址,然后在 map 中找到 function 以找出加载地址。 我宁愿有一个通用方法,它不需要您命名参考 function。
(GDB 在我的设置中不可用)。 谢谢。
dladdr 这样做,结束。 :-)
更全面地说,dladdr 将获取一个地址并计算出它对应于哪个库和符号……然后它会为您提供库的名称、符号的名称以及每个库的基地址。 就我个人而言,我认为这很漂亮,它也让我目前的调试工作变得更容易了。
希望这可以帮助!
在最近的 linux 上,您可以使用dl_iterate_phdr
找出共享库的地址。
尝试查看 /proc/[PID]/maps 文件。 这应该包含进程 memory 地址空间中的库映射地址。
如果要访问可执行部分,请在库上使用 readelf 并找到.text 部分的偏移量。
检查System V ABI,第 5 章。 对于那些懒惰的人,这里是支持 ELF 二进制格式的系统的标准方法:
#include <link.h>
off_t load_offset;
for (Elf64_Dyn *dyn = _DYNAMIC; dyn->d_tag != DT_NULL; ++dyn) {
if (dyn->d_tag == DT_DEBUG) {
struct r_debug *r_debug = (struct r_debug *) dyn->d_un.d_ptr;
struct link_map *link_map = r_debug->r_map;
while (link_map) {
if (strcmp(link_map->l_name, libname) == 0) {
load_offset = (off_t)link_map->l_addr;
break;
}
link_map = link_map->l_next;
}
break;
}
}
这不依赖于任何 GNU 扩展。
在 GNU 系统上,宏 ElfW(Dyn) 将返回 Elf64_Dyn 或 Elf32_Dyn,这很方便。
GNU 回溯库?
对于这样的事情,我不会依赖 hacky 方法。 我认为不能保证库的内容被加载到连续的 memory 中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.