У меня есть программа на 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 )
Я не могу найти ответы на следующие вопросы:
Как определить, является ли d_ptr «виртуальными адресами программы» или"offset fromloaded_link_map-> l_addr"?
Если небольшое значение (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