Нахождение адреса загрузки разделяемой библиотеки в Linux - PullRequest
8 голосов
/ 08 июля 2011

Во время выполнения мне нужно распечатать адрес, а затем найти, к какой функции относится этот адрес. Функции находятся в общей библиотеке, поэтому не по фиксированному адресу. Мой файл карты, очевидно, просто показывает относительные смещения для каждой функции общей библиотеки. Можно ли во время выполнения запрашивать, куда загружена библиотека, чтобы я мог вычесть это значение из своего адреса, чтобы получить правильное смещение файла карты?

В настоящее время я делаю немного хакерский подход, при котором я также распечатываю адрес одной функции в библиотеке, затем нахожу эту функцию в файле карты, чтобы выяснить, где должен быть адрес загрузки. Я предпочел бы иметь универсальный метод, который не требует, чтобы вы называли ссылочную функцию.

(GDB недоступен в моей настройке). Спасибо.

Ответы [ 5 ]

7 голосов
/ 16 февраля 2012

dladdr делает это, конец. : -)

Более подробно, dladdr возьмет адрес и определит, какой библиотеке и символу он соответствует ... и затем даст вам имя библиотеки, название символа и базовые адреса каждого. Лично я думаю, что это изящно, это также облегчает мою текущую работу по отладке.

Надеюсь, это поможет!

4 голосов
/ 08 июля 2011

В недавнем Linux вы можете использовать dl_iterate_phdr, чтобы узнать адреса общих библиотек.

3 голосов
/ 26 сентября 2011

Попробуйте взглянуть на файл / proc / [PID] / maps. Он должен содержать адрес отображения библиотеки в адресном пространстве памяти процесса.

Если вы хотите достичь исполняемой части, используйте readelf в вашей библиотеке и найдите смещение секции .text.

2 голосов
/ 05 февраля 2014

Проверьте Система 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, что удобно.

1 голос
/ 08 июля 2011

GNU backtrace библиотека?

Я бы не стал полагаться на хакерские подходы к чему-то подобному. Я не думаю, что есть какая-либо гарантия, что содержимое библиотек загружается в непрерывную память.

...