语法

#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 - Linux手册页

Linux程序员手册 第3部分
更新日期: 2020-08-13

BUGS

有时,传递给dladdr()的函数指针可能会让您感到惊讶。在某些体系结构(尤其是i386和x86-64)上,即使用作参数的函数应该来自动态链接库,dli_fname和dli_fbase可能最终指向您调用dladdr()的对象。

问题在于,函数指针仍将在编译时解析,而仅指向原始对象的plt(过程链接表)部分(在要求动态链接器解析符号后分派调用)。要解决此问题,您可以尝试将代码编译为与位置无关的代码:然后,编译器无法在编译时准备指针,并且gcc(1)将生成代码,该代码只会从got(全局偏移量表)在运行时传递给dladdr()。

说明

函数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不可抢占,不导出

出版信息

这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/

版本

dladdr()存在于glibc 2.0及更高版本中。 dladdr1()首先出现在glibc 2.3.3中。

返回值

成功执行后,这些函数将返回非零值。如果addr中指定的地址可以与共享库而不是共享库中的符号匹配,则info-> dli_sname和info-> dli_saddr字段将设置为NULL。

如果addr中指定的地址无法与共享库匹配,则这些函数将返回0。在这种情况下,无法通过dlerror(3)获得错误消息。

名称

dladdr,dladdr1-将地址转换为符号信息

属性

有关本节中使用的术语的说明,请参见attribute(7)。

InterfaceAttributeValue
dladdr(),dladdr1()Thread safetyMT-Safe

遵循规范

这些功能是Solaris上也存在的非标准GNU扩展。

另外参见

dl_iterate_phdr(3),dlinfo(3),dlopen(3),dlsym(3),ld.so(8)

日期:2019-08-20 18:00:07 来源:oir作者:oir