dlinfo(3) Library Functions Manual dlinfo(3)

ИМЯ

dlinfo - возвращает информацию о динамически загруженном объекте

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 показан в скобках):

Возвратить ID списка карты связи (link-map list, пространство имён), в который загружен handle.
Возвратить указатель на структуру 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 */
};

Скопировать путь источника общего объекта соответствующего handle в место, указанное info.
Возвратить пути поиска библиотек общего объекта, на который указывает 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 в настоящее время не используется и всегда равно нулю.
Заполнить поля dls_size и dls_cnt структуры Dl_serinfo, на которую указывает info, значениями, подходящими для выделения буфера, который будет использоваться в последующем запросе RTLD_DI_SERINFO.
Получить ID модуля сегмента TLS (локальное хранилище нити) общего объекта, которое используется в перемещениях TLS. Если этот объект не задаёт сегмент TLS, то в *info помещается ноль.
Получить указатель на блок 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 версии 3 или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на man-pages-ru-talks@lists.sourceforge.net.

31 октября 2023 г. Linux man-pages 6.06