История изменений
Исправление
kvpfs,
(текущая версия)
:
Порядок есть, все подгружаемые либы попадают в link map, положение либ в этой структуре и задаёт порядок в котором будут проштудированы либы. Когда встречается неразрешённый символ, то вызывается ld.so, ему передаются искомый символ и link map, который он штудирует с самого начала. В общих чертах так, но есть ещё всякие детали вроде неймспейсов и опций загрузчику. Оставлю небольшой код, которые печатает link map бинаря в консоль, можете поэкспериментировать передавая разные либы линкеру (и в разном порядке) при компиляции, вызывать dlopen() с разными опциями и смотреть на порядок либ.
#define _GNU_SOURCE
#include <link.h>
#include <dlfcn.h>
#include <stdio.h>
int main()
{
static char addr_in_mod;
Dl_info __info;
struct link_map *lm;
if(dladdr1(&addr_in_mod, &__info, (void**)&lm, RTLD_DL_LINKMAP) != 0) {
printf("link_map:\n");
struct link_map *i = lm;
for(; i->l_prev != NULL; i = i->l_prev);
for (; i != NULL; i = i->l_next)
printf("addr diff=%p name=%s%s",(void*)i->l_addr, i->l_name, i==lm?" <--cur\n":"\n");
}
}
Пример выхлопа:
link_map:
addr diff=0x41f000 name= <--current module
addr diff=0xb7fc4000 name=linux-gate.so.1
addr diff=0xb7fa3000 name=/lib/libdl.so.2
addr diff=0xb7dc5000 name=/lib/libc.so.6
addr diff=0xb7fc6000 name=/lib/ld-linux.so.2
Исходная версия
kvpfs,
:
Порядок есть, все подгружаемые либы попадают в link map, положение либ в этой структуре и задаёт порядок в котором будут проштудированы либы. Когда встречается неразрешённый символ, то вызывается ld.so, ему передаются искомый символ и link map, который он штудирует с самого начала. В общих чертах так, но есть ещё всякие детали вроде неймспейсов и опций загрузчику. Оставлю небольшой код, которые печатает link map бинаря в консоль, можете поэкспериментировать передавая разные либы линкеру (и в разном порядке) при компиляции, вызывать dlopen() с разными опциями и смотреть на порядок либ.
#define _GNU_SOURCE
#include <link.h>
#include <dlfcn.h>
#include <stdio.h>
int main()
{
static char addr_in_mod;
Dl_info __info;
struct link_map *lm;
if(dladdr1(&addr_in_mod, &__info, (void**)&lm, RTLD_DL_LINKMAP) != 0) {
printf("link_map:\n");
struct link_map *i = lm;
for(; i->l_prev != NULL; i = i->l_prev);
for (; i != NULL; i = i->l_next)
printf("addr diff=%p name=%s%s",(void*)i->l_addr, i->l_name, i==lm?" <--cur\n":"\n");
}
}