dlinfo(3) | Library Functions Manual | dlinfo(3) |
ИМЯ
dlinfo - возвращает информацию о динамически загруженном объекте
LIBRARY
Dynamic linking library (libdl, -ldl)
СИНТАКСИС
#define _GNU_SOURCE #include <link.h> #include <dlfcn.h>
int dlinfo(void *restrict handle, int request, void *restrict info);
ОПИСАНИЕ
Функция dlinfo() возвращает информацию о динамически загруженном объекте, на который указывает handle (обычно полученный ранее вызовом dlopen(3) или dlmopen(3)). В аргументе request указывается какую информацию нужно получить. Аргумент info — указатель на буфер для хранения информации, возвращаемой вызовом; тип данного аргумента зависит от request.
Для request поддерживаются следующие значения (соответствующий тип info показан в скобках):
- RTLD_DI_LMID (Lmid_t *)
- Возвратить ID списка карты связи (link-map list, пространство имён), в который загружен handle.
- RTLD_DI_LINKMAP (struct link_map **)
- Возвратить указатель на структуру link_map, соответствующую handle. Аргумент info указывает на указатель на структуру link_map, определённую в <link.h> следующим образом:
-
struct link_map { ElfW(Addr) l_addr; /* Difference between the address in the ELF file and the address in memory */ char *l_name; /* Absolute pathname where object was found */ ElfW(Dyn) *l_ld; /* Dynamic section of the shared object */ struct link_map *l_next, *l_prev; /* Chain of loaded objects */ /* Plus additional fields private to the implementation */ };
- RTLD_DI_ORIGIN (char *)
- Скопировать путь источника общего объекта соответствующего handle в место, указанное info.
- RTLD_DI_SERINFO (Dl_serinfo *)
- Возвратить пути поиска библиотек общего объекта, на который указывает handle. Аргумент info — указатель на Dl_serinfo с путями поиска. Так как количество путей поиска может быть разным, то размер структуры, на которую указывает info, может быть различным. Запрос RTLD_DI_SERINFOSIZE, описанный далее, позволяет приложению установить подходящий размер. Вызывающий должен выполнить следующие шаги:
- (1)
- Использовать запрос RTLD_DI_SERINFOSIZE для заполнения структуры Dl_serinfo размером (dls_size) структуры, необходимой для последующего запроса RTLD_DI_SERINFO.
- (2)
- Выделить буфер Dl_serinfo правильного размера (dls_size).
- (3)
- Использовать запрос RTLD_DI_SERINFOSIZE для заполнения полей dls_size и dls_cnt буфера, выделенного на предыдущем шаге.
- (4)
- Использовать RTLD_DI_SERINFO для получения путей поиска библиотек.
- Структура Dl_serinfo определена следующим образом:
-
typedef struct { size_t dls_size; /* Size in bytes of the whole buffer */ unsigned int dls_cnt; /* Number of elements in 'dls_serpath' */ Dl_serpath dls_serpath[1]; /* Actually longer, 'dls_cnt' elements */ } Dl_serinfo;
- Каждый из элементов dls_serpath, в упомянутой выше структуре, представляет собой структуру следующего вида:
-
typedef struct { char *dls_name; /* имя каталога в путях поиска библиотек */ unsigned int dls_flags; /* показывает, откуда возник каталог */ } Dl_serpath;
- Поле dls_flags в настоящее время не используется и всегда равно нулю.
- RTLD_DI_SERINFOSIZE (Dl_serinfo *)
- Заполнить поля dls_size и dls_cnt структуры Dl_serinfo, на которую указывает info, значениями, подходящими для выделения буфера, который будет использоваться в последующем запросе RTLD_DI_SERINFO.
- RTLD_DI_TLS_MODID (size_t *, начиная с glibc 2.4)
- Получить ID модуля сегмента TLS (локальное хранилище нити) общего объекта, которое используется в перемещениях TLS. Если этот объект не задаёт сегмент TLS, то в *info помещается ноль.
- RTLD_DI_TLS_DATA (void **, начиная с glibc 2.4)
- Получить указатель на блок TLS вызывающей нити, соответствующий этому сегменту TLS общего объекта. Если этот объект не задаёт сегмент PT_TLS, или если у вызывающей нити для этого не выделен блок, то в *info помещается NULL.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении dlinfo() возвращает 0. При ошибке возвращается -1; причину ошибки можно узнать с помощью dlerror(3).
АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).
Интерфейс | Атрибут | Значение |
dlinfo() | Безвредность в нитях | MT-Safe |
ВЕРСИИ
The sets of requests supported by the various implementations overlaps only partially.
СТАНДАРТЫ
GNU.
ИСТОРИЯ
glibc 2.3.3. Solaris.
ПРИМЕРЫ
Программа, показанная ниже, открывает общие объекты с помощью dlopen(3), а затем использует запросы RTLD_DI_SERINFOSIZE и RTLD_DI_SERINFO для получения библиотеки из списка путей поиска библиотек. Пример вывода работы программы:
$ ./a.out /lib64/libm.so.6 dls_serpath[0].dls_name = /lib64 dls_serpath[1].dls_name = /usr/lib64
Исходный код программы
#define _GNU_SOURCE #include <dlfcn.h> #include <link.h> #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { void *handle; Dl_serinfo serinfo; Dl_serinfo *sip; if (argc != 2) { fprintf(stderr, "Usage: %s <libpath>\n", argv[0]); exit(EXIT_FAILURE); } /* Obtain a handle for shared object specified on command line. */ handle = dlopen(argv[1], RTLD_NOW); if (handle == NULL) { fprintf(stderr, "dlopen() failed: %s\n", dlerror()); exit(EXIT_FAILURE); } /* Discover the size of the buffer that we must pass to RTLD_DI_SERINFO. */ if (dlinfo(handle, RTLD_DI_SERINFOSIZE, &serinfo) == -1) { fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\n", dlerror()); exit(EXIT_FAILURE); } /* Allocate the buffer for use with RTLD_DI_SERINFO. */ sip = malloc(serinfo.dls_size); if (sip == NULL) { perror("malloc"); exit(EXIT_FAILURE); } /* Initialize the 'dls_size' and 'dls_cnt' fields in the newly allocated buffer. */ if (dlinfo(handle, RTLD_DI_SERINFOSIZE, sip) == -1) { fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\n", dlerror()); exit(EXIT_FAILURE); } /* Fetch and print library search list. */ if (dlinfo(handle, RTLD_DI_SERINFO, sip) == -1) { fprintf(stderr, "RTLD_DI_SERINFO failed: %s\n", dlerror()); exit(EXIT_FAILURE); } for (size_t j = 0; j < serinfo.dls_cnt; j++) printf("dls_serpath[%zu].dls_name = %s\n", j, sip->dls_serpath[j].dls_name); exit(EXIT_SUCCESS); }
СМОТРИТЕ ТАКЖЕ
dl_iterate_phdr(3), dladdr(3), dlerror(3), dlopen(3), dlsym(3), ld.so(8)
ПЕРЕВОД
Русский перевод этой страницы руководства разработал Yuri Kozlov <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>
Этот перевод является свободной программной документацией; он распространяется на условиях общедоступной лицензии GNU (GNU General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.
Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом разработчику по его адресу электронной почты или по адресу списка рассылки русских переводчиков.
2 мая 2024 г. | Linux man-pages 6.8 |