繁体   English   中英

在Linux中查找共享库的加载地址

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM