Как определить, является ли d_ptr из ElfW (Dyn) из link_map адресом или смещением (c / c ++)? - PullRequest
0 голосов
/ 04 февраля 2019

У меня есть программа на C ++, которая читает link_map, полученную из dlinfo(handle, RTLD_DI_LINKMAP, &link_map);, где дескриптор был получен с помощью dlopen(NULL, RTLD_LAZY);

Программа отображает информацию о динамическом разделе для каждой библиотеки в link_map.Я пытаюсь использовать значение d_ptr из тега DT_SYMTAB (dyn->d_un.d_ptr) для чтения символов из библиотеки.

Одна вещь, которую я не понимаю, - почему этот адрес мал для linux-vdso.so.1.Я обнаружил, что это смещение от loaded_link_map->l_addr.

Я искал информацию во многих местах.(например. Используйте dlinfo для печати всех символов в библиотеке , http://www.sco.com/developers/gabi/latest/ch5.dynamic.html, https://flapenguin.me/2017/05/10/elf-lookup-dt-gnu-hash/, http://www.sco.com/developers/gabi/1998-04-29/ch4.sheader.html, http://s.eresi -project.org / inc /article / elf-rtld.txt )

Я не могу найти ответы на следующие вопросы:

  1. Как определить, является ли d_ptr «виртуальными адресами программы» или"offset fromloaded_link_map-> l_addr"?

  2. Если небольшое значение (offsett) в linux-vdso.so.1 является исключением или ошибкой, или это нормально, и я не понимаю, почему?

Это мой простой программный код:

#include <link.h>
#include <cstdio>

static const char *tag = "dl_util";

const char *dyn_tag_to_name(ElfW(Sxword) d_tag) {
    switch (d_tag) {
        case DT_STRTAB: return("DT_STRTAB");
        case DT_SYMTAB: return("DT_SYMTAB");
        default: return("UNKNOWN");
    }
}

void print_dynamic_sections(const link_map *l) {
    const ElfW(Dyn) *const dyn_start = l->l_ld;
    const ElfW(Addr) load_addr = l->l_addr;

    printf("Dynamic Sections:\n");
    printf("|%-18s|%16s|\n", "Tag", "Ptr");
    for (const ElfW(Dyn) *dyn = dyn_start; dyn->d_tag != DT_NULL; ++dyn) {
        if(dyn->d_tag == DT_STRTAB || dyn->d_tag == DT_SYMTAB)
        printf("|%-18s|%16lx|\n",
              dyn_tag_to_name(dyn->d_tag),
              dyn->d_un.d_val,
              (const void *) (dyn->d_un.d_ptr));

    }
}

int main() {

    void *handle;

    handle = dlopen(NULL, RTLD_LAZY);
    if (!handle) {
        printf("Error[%s]: %s\n", tag, dlerror());
        return 1;
    }

    struct link_map *l;
    int ld_ret = dlinfo(handle, RTLD_DI_LINKMAP,  &l);
    if (ld_ret) {
        printf("Error[%s]: %s\n", tag, dlerror());
        return 1;
    }
    printf("Loaded libraries: handle:0x%lx, prev:0x%lx\n", handle, (void*)l->l_prev);
    do {
        printf("   0x%lx, %s\n", l->l_addr, l->l_name);
        print_dynamic_sections(l);

        l = l->l_next;
    } while (l != NULL);
    return 0;
}

И вывод кода:

Loaded libraries: handle:0x7fb3f5bf7120, prev:0x0
   0x562410906000, 
Dynamic Sections:
|Tag               |             Ptr|
|DT_STRTAB         |    562410906448|
|DT_SYMTAB         |    562410906328|
   0x7fff5978b000, linux-vdso.so.1
Dynamic Sections:
|Tag               |             Ptr|
|DT_STRTAB         |             298|
|DT_SYMTAB         |             1a8|
   0x7fb3f5b55000, /usr/lib/libdl.so.2
Dynamic Sections:
|Tag               |             Ptr|
|DT_STRTAB         |    7fb3f5b557a8|
|DT_SYMTAB         |    7fb3f5b553a0|
   0x7fb3f59c6000, /usr/lib/libstdc++.so.6
Dynamic Sections:
|Tag               |             Ptr|
|DT_STRTAB         |    7fb3f59eef90|
|DT_SYMTAB         |    7fb3f59ce758|

... more libraries
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...