dl_iterate_phdr(3) Library Functions Manual dl_iterate_phdr(3) dl_iterate_phdr - LIBRARY Standard C library (libc, -lc) #define _GNU_SOURCE /* . feature_test_macros(7) */ #include int dl_iterate_phdr( int (*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data); dl_iterate_phdr() , . dl_iterate_phdr() callback , , callback . callback : info ( ), size ( , info) data ( , ( data) dl_iterate_phdr(). info : 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 dlpi_phdr */ /* The following fields were added in glibc 2.4, after the first version of this structure was available. Check the size 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's instance of this module's PT_TLS segment, if it has one and it has been allocated in the calling thread, otherwise a null pointer */ }; ( ElfW() ELF, . , 32- ElfW(Addr) Elf32_Addr. .) dlpi_addr (. ., , ). dlpi_name null , , . dlpi_phdr dlpi_phnum, , ELF , , . dlpi_phdr . dlpi_phnum . : 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; , x : addr == info->dlpi_addr + info->dlpi_phdr[x].p_vaddr; p_type ( ): #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 /* */ dl_iterate_phdr() , callback. attributes(7). +----------------------------+----------------------------------------------------------+--------------------------+ | | | | +----------------------------+----------------------------------------------------------+--------------------------+ |dl_iterate_phdr() | | MT-Safe | +----------------------------+----------------------------------------------------------+--------------------------+ Various other systems provide a version of this function, although details of the returned dl_phdr_info structure differ. On the BSDs and Solaris, the structure includes the fields dlpi_addr, dlpi_name, dlpi_phdr, and dlpi_phnum in addition to other implementation-specific fields. C dl_phdr_info ; size, , . None. glibc 2.2.4. , callback, . dlpi_name . , . ELF ( , , ). , x86-64. ( ). $ ./a.out : "" (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 #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: \"%s\" (%d segments)\n", 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\n", type); else printf("[other (%#x)]\n", p_type); } return 0; } int main(void) { dl_iterate_phdr(callback, NULL); exit(EXIT_SUCCESS); } . ldd(1), objdump(1), readelf(1), dladdr(3), dlopen(3), elf(5), ld.so(8) Executable and Linking Format Specification . Yuri Kozlov ; GNU 3 , . . , , . Linux man-pages 6.06 31 2023 . dl_iterate_phdr(3)