DLADDR - Linux手册页
Linux程序员手册 第3部分
更新日期: 2020-08-13
名称
dladdr,dladdr1-将地址转换为符号信息
语法
#define _GNU_SOURCE #include <dlfcn.h> int dladdr(void *addr, Dl_info *info); int dladdr1(void *addr, Dl_info *info, void **extra_info, int flags); Link with -ldl.
说明
函数dladdr()确定addr中指定的地址是否位于调用应用程序加载的共享对象之一中。如果是,则dladdr()返回有关共享对象和与addr重叠的符号的信息。此信息以Dl_info结构返回:
typedef struct { const char *dli_fname; /* Pathname of shared object that contains address */ void *dli_fbase; /* Base address at which shared object is loaded */ const char *dli_sname; /* Name of symbol whose definition overlaps addr */ void *dli_saddr; /* Exact address of symbol named in dli_sname */ } Dl_info;
如果找不到与addr匹配的符号,则dli_sname和dli_saddr设置为NULL。
函数dladdr1()与dladdr()类似,但是通过参数extra_info返回其他信息。返回的信息取决于标志中指定的值,这些标志可以具有以下值之一:
- RTLD_DL_LINKMAP
- 获取指向匹配文件的链接映射的指针。 extra_info参数指向一个指向link_map结构(即struct link_map **)的指针,其定义如下:
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_DL_SYMENT
- 获取指向匹配符号的ELF符号表条目的指针。 extra_info参数是指向符号指针的指针:const ElfW(Sym)**。 ElfW()宏定义将其参数转换为适合硬件体系结构的ELF数据类型的名称。例如,在64位平台上,ElfW(Sym)产生数据类型名称Elf64_Sym,其定义为:
typedef struct { Elf64_Word st_name; /* Symbol name */ unsigned char st_info; /* Symbol type and binding */ unsigned char st_other; /* Symbol visibility */ Elf64_Section st_shndx; /* Section index */ Elf64_Addr st_value; /* Symbol value */ Elf64_Xword st_size; /* Symbol size */ } Elf64_Sym;
- st_name字段是字符串表的索引。
- st_info字段对符号的类型和绑定进行编码。可以使用宏ELF64_ST_TYPE(st_info)(或在32位平台上为ELF32_ST_TYPE())提取类型,它产生以下值之一:ValueDescription STT_NOTYPE符号类型未指定 STT_OBJECTSymbol是一个数据对象 STT_FUNCSymbol是一个代码对象 与节关联的STT_SECTIONSymbol STT_FILESymbol的名称是文件名 STT_COMMONSymbol是公共数据对象 STT_TLSSymbol是线程本地数据对象 STT_GNU_IFUNCSymbol是间接代码对象
- 可以使用宏ELF64_ST_BIND(st_info)(或在32位平台上为ELF32_ST_BIND())从st_info字段中提取符号绑定,这将产生以下值之一:ValueDescription STB_LOCAL本地符号 STB_GLOBAL全局符号 STB_WEAK弱符号 STB_GNU_UNIQUE唯一符号
- st_other字段包含符号的可见性,可以使用宏ELF64_ST_VISIBILITY(st_info)(或在32位平台上为ELF32_ST_VISIBILITY())提取该符号的可见性,它产生以下值之一:ValueDescription STV_DEFAULT默认符号可见性规则 STV_INTERNAL特定于处理器的隐藏类 STV_HIDDENS符号在其他模块中不可用 STV_PROTECTED不可抢占,不导出
返回值
成功执行后,这些函数将返回非零值。如果addr中指定的地址可以与共享库而不是共享库中的符号匹配,则info-> dli_sname和info-> dli_saddr字段将设置为NULL。
如果addr中指定的地址无法与共享库匹配,则这些函数将返回0。在这种情况下,无法通过dlerror(3)获得错误消息。
版本
dladdr()存在于glibc 2.0及更高版本中。 dladdr1()首先出现在glibc 2.3.3中。
属性
有关本节中使用的术语的说明,请参见attribute(7)。
Interface | Attribute | Value |
dladdr(),dladdr1() | Thread safety | MT-Safe |
遵循规范
这些功能是Solaris上也存在的非标准GNU扩展。
BUGS
有时,传递给dladdr()的函数指针可能会让您感到惊讶。在某些体系结构(尤其是i386和x86-64)上,即使用作参数的函数应该来自动态链接库,dli_fname和dli_fbase可能最终指向您调用dladdr()的对象。
问题在于,函数指针仍将在编译时解析,而仅指向原始对象的plt(过程链接表)部分(在要求动态链接器解析符号后分派调用)。要解决此问题,您可以尝试将代码编译为与位置无关的代码:然后,编译器无法在编译时准备指针,并且gcc(1)将生成代码,该代码只会从got(全局偏移量表)在运行时传递给dladdr()。
另外参见
dl_iterate_phdr(3),dlinfo(3),dlopen(3),dlsym(3),ld.so(8)
出版信息
这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/。