.\" -*- coding: UTF-8 -*- '\" t .\" Copyright (c) 2003, 2017 by Michael Kerrisk .\" .\" SPDX-License-Identifier: Linux-man-pages-copyleft .\" .\"******************************************************************* .\" .\" This file was generated with po4a. Translate the source file. .\" .\"******************************************************************* .TH dl_iterate_phdr 3 "2 мая 2024 г." "Linux man\-pages 6.8" .SH ИМЯ dl_iterate_phdr \- обход списка общих объектов .SH LIBRARY Standard C library (\fIlibc\fP, \fI\-lc\fP) .SH СИНТАКСИС .nf \fB#define _GNU_SOURCE\fP /* см. feature_test_macros(7) */ \fB#include \fP .P \fBint dl_iterate_phdr(\fP \fB int (*\fP\fIcallback\fP\fB)(struct dl_phdr_info *\fP\fIinfo\fP\fB,\fP \fB size_t \fP\fIsize\fP\fB, void *\fP\fIdata\fP\fB),\fP \fB void *\fP\fIdata\fP\fB);\fP .fi .SH ОПИСАНИЕ Функция \fBdl_iterate_phdr\fP() позволяет приложению во время выполнения узнать, какие общие объекты были загружены и их порядок загрузки. .P Функция \fBdl_iterate_phdr\fP() обходит список общих объектов приложения и однократно вызывает функцию \fIcallback\fP для каждого объекта до тех пор, пока или все общие объекты не будут просмотрены, или функция \fIcallback\fP не вернёт ненулевое значение. .P При каждом вызове в \fIcallback\fP передаётся три параметра: \fIinfo\fP (указатель на структуру с информацией об общем объекте), \fIsize\fP (размер структуры, на которую указывает \fIinfo\fP) и \fIdata\fP (копия любого значения, переданного вызывающей программой во втором параметре (также называемом \fIdata\fP) в вызов \fBdl_iterate_phdr\fP(). .P Параметр \fIinfo\fP представляет собой структуру следующего вида: .P .in +4n .EX struct dl_phdr_info { ElfW(Addr) dlpi_addr; /* Base address of object */ const char *dlpi_name; /* (Null\-terminated) name of object */ const ElfW(Phdr) *dlpi_phdr; /* Pointer to array of ELF program headers for this object */ ElfW(Half) dlpi_phnum; /* # of items in \fIdlpi_phdr\fP */ \& /* The following fields were added in glibc 2.4, after the first version of this structure was available. Check the \fIsize\fP argument passed to the dl_iterate_phdr callback to determine whether or not each later member is available. */ \& unsigned long long dlpi_adds; /* Incremented when a new object may have been added */ unsigned long long dlpi_subs; /* Incremented when an object may have been removed */ size_t dlpi_tls_modid; /* If there is a PT_TLS segment, its module ID as used in TLS relocations, else zero */ void *dlpi_tls_data; /* The address of the calling thread\[aq]s instance of this module\[aq]s PT_TLS segment, if it has one and it has been allocated in the calling thread, otherwise a null pointer */ }; .EE .in .P (Макрос \fIElfW\fP() преобразует свой аргумент в имя типа данных ELF, подходящее для аппаратной архитектуры. Например, на 32\-битной платформе \fIElfW(Addr)\fP вернёт имя типа данных \fIElf32_Addr\fP. Дополнительную информацию можно найти в заголовочных файлах \fI\fP и \fI\fP.) .P В поле \fIdlpi_addr\fP указывается базовый адрес общего объекта (т. е., разница между виртуальным адресом памяти общего объекта и смещением до этого объекта в файле, из которого он был загружен). Поле \fIdlpi_name\fP представляет собой строку с null на конце, определяющую путь, из которого был загружен общий объект. .P Чтобы понять назначение полей \fIdlpi_phdr\fP и \fIdlpi_phnum\fP, нам необходимо представлять, что общий объект ELF состоит из набора сегментов, каждый из которых имеет соответствующий программный заголовок, описывающий сегмент. Поле \fIdlpi_phdr\fP представляет собой указатель на массив программных заголовков этого общего объекта. В поле \fIdlpi_phnum\fP задаётся размер этого массива. .P Программные заголовки представляют собой структуры следующего вида: .P .in +4n .EX typedef struct { Elf32_Word p_type; /* тип сегмента */ Elf32_Off p_offset; /* смещение сегмента в файле */ Elf32_Addr p_vaddr; /* виртуальный адрес сегмента */ Elf32_Addr p_paddr; /* физический адрес сегмента */ Elf32_Word p_filesz; /* размер сегмента в файле */ Elf32_Word p_memsz; /* размер сегмента в памяти */ Elf32_Word p_flags; /* флаги сегмента */ Elf32_Word p_align; /* выравнивание сегмента */ } Elf32_Phdr; .EE .in .P Заметим, что мы можем вычислить расположение определённого программного заголовка \fIx\fP в виртуальной памяти по следующей формуле: .P .in +4n .EX addr == info\->dlpi_addr + info\->dlpi_phdr[x].p_vaddr; .EE .in .P Возможными значениями \fIp_type\fP поля могут быть (подробности смотрите в \fI\fP): .P .in +4n .EX .\" For PT_GNU_STACK, see http://www.airs.com/blog/archives/518 #define PT_LOAD 1 /* загружаемый сегмент программы */ #define PT_DYNAMIC 2 /* информация о динамической компоновке */ #define PT_INTERP 3 /* интерпретатор программы */ #define PT_NOTE 4 /* вспомогательная информация */ #define PT_SHLIB 5 /* зарезервировано */ #define PT_PHDR 6 /* сам элемент таблицы заголовков */ #define PT_TLS 7 /* сегмент локального хранилища нити */ #define PT_GNU_EH_FRAME 0x6474e550 /* сегмент GCC .eh_frame_hdr */ #define PT_GNU_STACK 0x6474e551 /* показывает, что стек — исполняемый */ #define PT_GNU_RELRO 0x6474e552 /* только чтения после перемещения */ .EE .in .SH "ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ" Функция \fBdl_iterate_phdr\fP() возвращает значение, которое было получено в результате последнего вызова \fIcallback\fP. .SH АТРИБУТЫ Описание терминов данного раздела смотрите в \fBattributes\fP(7). .TS allbox; lbx lb lb l l l. Интерфейс Атрибут Значение T{ .na .nh \fBdl_iterate_phdr\fP() T} Безвредность в нитях MT\-Safe .TE .SH ВЕРСИИ Various other systems provide a version of this function, although details of the returned \fIdl_phdr_info\fP structure differ. On the BSDs and Solaris, the structure includes the fields \fIdlpi_addr\fP, \fIdlpi_name\fP, \fIdlpi_phdr\fP, and \fIdlpi_phnum\fP in addition to other implementation\-specific fields. .P В будущих версиях библиотеки C в структуре \fIdl_phdr_info\fP могут появиться дополнительные поля; для этого случая предусмотрен аргумент \fIsize\fP, который предоставляет вызываемой функции механизм обнаружения того, что она работает в системе с добавленными полями. .SH СТАНДАРТЫ None. .SH ИСТОРИЯ glibc 2.2.4. .SH ПРИМЕЧАНИЯ Первый объект, просматриваемый \fIcallback\fP, это главная программа. У главной программы поле \fIdlpi_name\fP будет содержать пустую строку. .SH ПРИМЕРЫ Следующая программа выводит список путей общих объектов, из которых они были загружены. Для каждого общего объекта программа выводит информацию из каждого сегмента объектов ELF (виртуальный адрес, размер, флаги и тип). .P В следующем сеансе оболочки показан вывод программы, запущенной в системе с архитектурой x86\-64. Первый показанный общий объект это основная программа (вместо имени пустая строка). .P .in +4n .EX $ \fB./a.out\fP Имя: "" (9 сегментов) 0: [ 0x400040; memsz: 1f8] flags: 0x5; PT_PHDR 1: [ 0x400238; memsz: 1c] flags: 0x4; PT_INTERP 2: [ 0x400000; memsz: ac4] flags: 0x5; PT_LOAD 3: [ 0x600e10; memsz: 240] flags: 0x6; PT_LOAD 4: [ 0x600e28; memsz: 1d0] flags: 0x6; PT_DYNAMIC 5: [ 0x400254; memsz: 44] flags: 0x4; PT_NOTE 6: [ 0x400970; memsz: 3c] flags: 0x4; PT_GNU_EH_FRAME 7: [ (nil); memsz: 0] flags: 0x6; PT_GNU_STACK 8: [ 0x600e10; memsz: 1f0] flags: 0x4; PT_GNU_RELRO Имя: "linux\-vdso.so.1" (4 сегментов) 0: [0x7ffc6edd1000; memsz: e89] flags: 0x5; PT_LOAD 1: [0x7ffc6edd1360; memsz: 110] flags: 0x4; PT_DYNAMIC 2: [0x7ffc6edd17b0; memsz: 3c] flags: 0x4; PT_NOTE 3: [0x7ffc6edd17ec; memsz: 3c] flags: 0x4; PT_GNU_EH_FRAME Имя: "/lib64/libc.so.6" (10 сегментов) 0: [0x7f55712ce040; memsz: 230] flags: 0x5; PT_PHDR 1: [0x7f557145b980; memsz: 1c] flags: 0x4; PT_INTERP 2: [0x7f55712ce000; memsz: 1b6a5c] flags: 0x5; PT_LOAD 3: [0x7f55716857a0; memsz: 9240] flags: 0x6; PT_LOAD 4: [0x7f5571688b80; memsz: 1f0] flags: 0x6; PT_DYNAMIC 5: [0x7f55712ce270; memsz: 44] flags: 0x4; PT_NOTE 6: [0x7f55716857a0; memsz: 78] flags: 0x4; PT_TLS 7: [0x7f557145b99c; memsz: 544c] flags: 0x4; PT_GNU_EH_FRAME 8: [0x7f55712ce000; memsz: 0] flags: 0x6; PT_GNU_STACK 9: [0x7f55716857a0; memsz: 3860] flags: 0x4; PT_GNU_RELRO Имя: "/lib64/ld\-linux\-x86\-64.so.2" (7 сегментов) 0: [0x7f557168f000; memsz: 20828] flags: 0x5; PT_LOAD 1: [0x7f55718afba0; memsz: 15a8] flags: 0x6; PT_LOAD 2: [0x7f55718afe10; memsz: 190] flags: 0x6; PT_DYNAMIC 3: [0x7f557168f1c8; memsz: 24] flags: 0x4; PT_NOTE 4: [0x7f55716acec4; memsz: 604] flags: 0x4; PT_GNU_EH_FRAME 5: [0x7f557168f000; memsz: 0] flags: 0x6; PT_GNU_STACK 6: [0x7f55718afba0; memsz: 460] flags: 0x4; PT_GNU_RELRO .EE .in .SS "Исходный код программы" .\" SRC BEGIN (dl_iterate_phdr.c) \& .EX #define _GNU_SOURCE #include #include #include #include \& static int callback(struct dl_phdr_info *info, size_t size, void *data) { char *type; int p_type; \& printf("Name: \e"%s\e" (%d segments)\en", info\->dlpi_name, info\->dlpi_phnum); \& for (size_t j = 0; j < info\->dlpi_phnum; j++) { p_type = info\->dlpi_phdr[j].p_type; type = (p_type == PT_LOAD) ? "PT_LOAD" : (p_type == PT_DYNAMIC) ? "PT_DYNAMIC" : (p_type == PT_INTERP) ? "PT_INTERP" : (p_type == PT_NOTE) ? "PT_NOTE" : (p_type == PT_INTERP) ? "PT_INTERP" : (p_type == PT_PHDR) ? "PT_PHDR" : (p_type == PT_TLS) ? "PT_TLS" : (p_type == PT_GNU_EH_FRAME) ? "PT_GNU_EH_FRAME" : (p_type == PT_GNU_STACK) ? "PT_GNU_STACK" : (p_type == PT_GNU_RELRO) ? "PT_GNU_RELRO" : NULL; \& printf(" %2zu: [%14p; memsz:%7jx] flags: %#jx; ", j, (void *) (info\->dlpi_addr + info\->dlpi_phdr[j].p_vaddr), (uintmax_t) info\->dlpi_phdr[j].p_memsz, (uintmax_t) info\->dlpi_phdr[j].p_flags); if (type != NULL) printf("%s\en", type); else printf("[other (%#x)]\en", p_type); } \& return 0; } \& int main(void) { dl_iterate_phdr(callback, NULL); \& exit(EXIT_SUCCESS); } .EE .\" SRC END .SH "СМОТРИТЕ ТАКЖЕ" \fBldd\fP(1), \fBobjdump\fP(1), \fBreadelf\fP(1), \fBdladdr\fP(3), \fBdlopen\fP(3), \fBelf\fP(5), \fBld.so\fP(8) .P \fIExecutable and Linking Format Specification\fP в веб. .PP .SH ПЕРЕВОД Русский перевод этой страницы руководства разработал Yuri Kozlov и Иван Павлов . .PP Этот перевод является свободной программной документацией; он распространяется на условиях общедоступной лицензии GNU (GNU General Public License - GPL, .UR https://www.gnu.org/licenses/gpl-3.0.html .UE версии 3 или более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ. .PP Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите об этом разработчику по его адресу электронной почты или по адресу .MT списка рассылки русских переводчиков .ME .