DLINFO - Linux手册页
Linux程序员手册 第3部分
更新日期: 2020-06-09
名称
dlinfo-获取有关动态加载对象的信息
语法
#define _GNU_SOURCE #include <link.h> #include <dlfcn.h> int dlinfo(void *handle, int request, void *info); Link with -ldl.
说明
dlinfo()函数获取有关句柄引用的动态加载对象的信息(通常是通过对dlopen(3)或dlmopen(3)的较早调用获得的)。 request参数指定要返回的信息。 info参数是一个指向缓冲区的指针,该缓冲区用于存储调用返回的信息。此参数的类型取决于请求。
支持以下值进行请求(括号中显示信息的相应类型):
- RTLD_DI_LMID(Lmid_t *)
- 获取在其中加载了句柄的链接映射列表(名称空间)的ID。
- RTLD_DI_LINKMAP(struct link_map **)
- 获取指向对应于句柄的link_map结构的指针。 info参数指向一个指向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_DI_ORIGIN(char *)
- 将对应于句柄的共享库的原点的路径名复制到info指向的位置。
- RTLD_DI_SERINFO(Dl_serinfo *)
- Obtain the library search paths for the shared object referred to by
handle.
The
infoargument is a pointer to a
Dl_serinfothat contains the search paths.
Because the number of search paths may vary,
the size of the structure pointed to by
infocan vary.
The
RTLD_DI_SERINFOSIZErequest described below allows applications to size the buffer suitably.
The caller must perform the following steps:- 1.
- 使用RTLD_DI_SERINFOSIZE请求以后续RTLD_DI_SERINFO请求所需结构的大小(dls_size)填充Dl_serinfo结构。
- 2.
- 分配正确大小(dls_size)的Dl_serinfo缓冲区。
- 3.
- 使用另一个RTLD_DI_SERINFOSIZE请求填充上一步中分配的缓冲区的dls_size和dls_cnt字段。
- 4.
- 使用RTLD_DI_SERINFO获取库搜索路径。
- Dl_serinfo结构定义如下:
typedef struct { size_t dls_size; /* Size in bytes of the whole buffer */ unsigned int dls_cnt; /* Number of elements in 'dls_serpath' */ Dl_serpath dls_serpath[1]; /* Actually longer, 'dls_cnt' elements */ } Dl_serinfo;
- 上述结构中的每个dls_serpath元素都是以下形式的结构:
typedef struct { char *dls_name; /* Name of library search path directory */ unsigned int dls_flags; /* Indicates where this directory came from */ } Dl_serpath;
- dls_flags字段当前未使用,并且始终包含零。
- RTLD_DI_SERINFOSIZE(Dl_serinfo *)
- 使用适合于分配缓冲区以供后续RTLD_DI_SERINFO请求使用的值,填充info指向的Dl_serinfo结构的dls_size和dls_cnt字段。
- RTLD_DI_TLS_MODID(size_t *, since glibc 2.4)
- 获取此共享对象的TLS(线程本地存储)段的模块ID,如TLS重定位中所使用。如果此对象未定义TLS段,则* info中将置零。
- RTLD_DI_TLS_DATA(void **, since glibc 2.4)
- 获取指向与该共享库的TLS段相对应的调用线程的TLS块的指针。如果此对象未定义PT_TLS段,或者调用线程尚未为其分配块,则将* NULL放置在* info中。
返回值
成功时,dlinfo()返回0。失败时,它返回-1;否则,它返回-1。可以使用dlerror(3)诊断错误原因。
版本
dlinfo()最早出现在glibc 2.3.3中。
属性
有关本节中使用的术语的说明,请参见attribute(7)。
Interface | Attribute | Value |
dlinfo() | Thread safety | MT-Safe |
遵循规范
此函数是非标准的GNU扩展。
备注
该函数源自同名的Solaris函数,并且还出现在某些其他系统上。各种实现所支持的请求集仅部分重叠。
示例
下面的程序使用dlopen(3)打开共享库,然后使用RTLD_DI_SERINFOSIZE和RTLD_DI_SERINFO请求获取库的库搜索路径列表。这是运行程序时可能看到的示例:
$ ./a.out /lib64/libm.so.6 dls_serpath[0].dls_name = /lib64 dls_serpath[1].dls_name = /usr/lib64
Program source
#define _GNU_SOURCE #include <dlfcn.h> #include <link.h> #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { void *handle; Dl_serinfo serinfo; Dl_serinfo *sip; int j; if (argc != 2) { fprintf(stderr, "Usage: %s <libpath>\n", argv[0]); exit(EXIT_FAILURE); } /* Obtain a handle for shared object specified on command line */ handle = dlopen(argv[1], RTLD_NOW); if (handle == NULL) { fprintf(stderr, "dlopen() failed: %s\n", dlerror()); exit(EXIT_FAILURE); } /* Discover the size of the buffer that we must pass to RTLD_DI_SERINFO */ if (dlinfo(handle, RTLD_DI_SERINFOSIZE, &serinfo) == -1) { fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\n", dlerror()); exit(EXIT_FAILURE); } /* Allocate the buffer for use with RTLD_DI_SERINFO */ sip = malloc(serinfo.dls_size); if (sip == NULL) { perror("malloc"); exit(EXIT_FAILURE); } /* Initialize the aqdls_sizeaq and aqdls_cntaq fields in the newly allocated buffer */ if (dlinfo(handle, RTLD_DI_SERINFOSIZE, sip) == -1) { fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\n", dlerror()); exit(EXIT_FAILURE); } /* Fetch and print library search list */ if (dlinfo(handle, RTLD_DI_SERINFO, sip) == -1) { fprintf(stderr, "RTLD_DI_SERINFO failed: %s\n", dlerror()); exit(EXIT_FAILURE); } for (j = 0; j < serinfo.dls_cnt; j++) printf("dls_serpath[%d].dls_name = %s\n", j, sip->dls_serpath[j].dls_name); exit(EXIT_SUCCESS); }
出版信息
这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/。