簡體   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