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

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.

RTLD_DI_PHDR (const ElfW(Phdr *), since glibc 2.34.1)
    Obtain the address of this shared object's program header and place it in *info. This dlinfo call returns the number of program headers in the shared object.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
On success, dlinfo() returns 0 (if not specified explicitly), or a positive value corresponding to the request. On failure, it returns -1; the error can be diagnosed using 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> и Kirill Rekhov <krekhov.dev@gmail.com>

Этот перевод является свободной программной документацией; он распространяется на условиях общедоступной лицензии GNU (GNU General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.

Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом разработчику(ам) по его(их) адресу(ам) электронной почты или по адресу списка рассылки русских переводчиков (<debian-l10n-russian@lists.debian.org>).