http://www.helplib.net/s/linux.die/65_1099/man-3-dl-iterate-phdr.shtml
dl_iterate_phdr(3)linux man page
名称
dl_iterate_phdr 遍历共享对象列表
staging 模块
# define _gnu_source /*看到feature_test_macros(7)*/ # include<<a href="http://linux.die.net/include/link.h" rel="nofollow">link.h> int dl_iterate_phdr( int(*回调)(struct dl_phdr_info *info , size_t 大小, void *数据), void *数据);
描述
在dl_iterate_phdr()函数允许在运行一个查询时间来找出哪个已加载的共享对象.
在dl_iterate_phdr()通过一个共享的对象列表函数教每个对象,并调用函数回调后 ,, 直到所有共享对象已被处理或回调返回一个非零值.
每个回调接收三个参数 :info ,它是指向一个结构包含共享信息的对象;的结构的大小,这个大小是通过信息;和数据,而这是作为参数传递的任何值由调用程序的副本(还可以访问数据)在调用 dl_iterate_phdr().
info 参数是以下类型的结构:
-
struct dl_phdr_info{ elfw(addr)dlpi_addr ;/ *基对象的地址 */ const char *dlpi_name ;/ *(null 结尾)名称 对象 */ const elfw(phdr)*dlpi_phdr ;/ *指针数组 elf 程序头 对于此对象 */ elfw(半)dlpi_phnum ;/ *# 在 dlpi_phdr */ };
(在elfw()宏定义打开它的参数到适合的硬件架构的 elf 数据类型的名称.例如,在一个 32 位平台上,elfw(addr)产生的数据类型名称 elf32_addr .这种类型的进一步信息,可在和头文件 .)
-
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 ==信息>dlpi_addr+ info>dlpi_phdr[x].p_vaddr;
dlpi_addr 字段指示基地址共享对象(即,的共享内存的虚拟地址之间的差异.和该对象在它加载的偏移).在 dlpi_name 字段是 null 结尾字符串给定路径名从其中加载的共享对象.
为了理解 dlpi_phdr 和 dlpi_phnum 字段的含义,我们需要知道 elf 对象共享由一个线段数目,每个成员都有一个相应的程序头描述该线段.此共享的程序头的字段是一个指针数组 dlpi_phdr 对象.在 dlpi_phnum 字段指示此数组的大小.
这些程序头结构采用以下格式:
返回值
在dl_iterate_phdr()回调函数返回的最后调用返回的任何值.
版本
dl_iterate_phdr()已自版本的 glibc 2.2.4.
符合
在dl_iterate_phdr()函数是 linux 特定的应避免在便携应用的.
示例
下面的程序中显示的工作列表已加载的共享对象.为每个共享的对象,该程序列出的地址空间和虚拟对象的 elf 段加载.
#定义 _gnu_source # include<<a href="http://linux.die.net/include/link.h" rel="nofollow">link.h> # include<<a href="http://linux.die.net/include/stdlib.h" rel="nofollow">stdlib.h> # include<<a href="http://linux.die.net/include/3.3.3" rel="nofollow">3.3.3> static int 回调(struct dl_phdr_info *info , size_t 大小, void *数据) { int j; printf(" name =%s(段% d) n", info>dlpi_name . info>dlpi_phnum); 对于(j=0 ;jdlpi_phnum ;j + +) printf("tt% 2d :地址=% 10p n",j. (void *)(info>dlpi_addr + info>dlpi_phdr[j].p_vaddr)); return 0; } int 主(int argc , char *argv[]) { dl_iterate_phdr(callback , null); 退出(exit_success); }