1 .\" Copyright (C) 2015 Michael Kerrisk <mtk.manpages@gmail.com>
3 .\" %%%LICENSE_START(VERBATIM)
4 .\" Permission is granted to make and distribute verbatim copies of this
5 .\" manual provided the copyright notice and this permission notice are
6 .\" preserved on all copies.
8 .\" Permission is granted to copy and distribute modified versions of this
9 .\" manual under the conditions for verbatim copying, provided that the
10 .\" entire resulting derived work is distributed under the terms of a
11 .\" permission notice identical to this one.
13 .\" Since the Linux kernel and libraries are constantly changing, this
14 .\" manual page may be incorrect or out-of-date. The author(s) assume no
15 .\" responsibility for errors or omissions, or for damages resulting from
16 .\" the use of the information contained herein. The author(s) may not
17 .\" have taken the same level of care in the production of this manual,
18 .\" which is licensed free of charge, as they might when working
21 .\" Formatted or processed versions of this manual, if unaccompanied by
22 .\" the source, must acknowledge the copyright and authors of this work.
25 .TH DLINFO 3 2021-03-22 "Linux" "Linux Programmer's Manual"
27 dlinfo \- obtain information about a dynamically loaded object
30 .B #define _GNU_SOURCE
34 .BR "int dlinfo(void *restrict " handle ", int " request \
35 ", void *restrict " info );
37 Link with \fI\-ldl\fP.
42 function obtains information about the dynamically loaded object
45 (typically obtained by an earlier call to
51 argument specifies which information is to be returned.
54 argument is a pointer to a buffer used to store information
55 returned by the call; the type of this argument depends on
58 The following values are supported for
60 (with the corresponding type for
62 shown in parentheses):
64 .BR RTLD_DI_LMID " (\fILmid_t *\fP)"
65 Obtain the ID of the link-map list (namespace) in which
69 .BR RTLD_DI_LINKMAP " (\fIstruct link_map **\fP)"
70 Obtain a pointer to the
72 structure corresponding to
76 argument points to a pointer to a
85 ElfW(Addr) l_addr; /* Difference between the
86 address in the ELF file and
87 the address in memory */
88 char *l_name; /* Absolute pathname where
90 ElfW(Dyn) *l_ld; /* Dynamic section of the
92 struct link_map *l_next, *l_prev;
93 /* Chain of loaded objects */
95 /* Plus additional fields private to the
101 .BR RTLD_DI_ORIGIN " (\fIchar *\fP)"
102 Copy the pathname of the origin of the shared object corresponding to
104 to the location pointed to by
107 .BR RTLD_DI_SERINFO " (\fIDl_serinfo *\fP)"
108 Obtain the library search paths for the shared object referred to by
112 argument is a pointer to a
114 that contains the search paths.
115 Because the number of search paths may vary,
116 the size of the structure pointed to by
120 .B RTLD_DI_SERINFOSIZE
121 request described below allows applications to size the buffer suitably.
122 The caller must perform the following steps:
126 .B RTLD_DI_SERINFOSIZE
127 request to populate a
129 structure with the size
131 of the structure needed for the subsequent
137 buffer of the correct size
141 .B RTLD_DI_SERINFOSIZE
142 request to populate the
146 fields of the buffer allocated in the previous step.
150 to obtain the library search paths.
155 structure is defined as follows:
160 size_t dls_size; /* Size in bytes of
162 unsigned int dls_cnt; /* Number of elements
163 in \(aqdls_serpath\(aq */
164 Dl_serpath dls_serpath[1]; /* Actually longer,
165 \(aqdls_cnt\(aq elements */
172 elements in the above structure is a structure of the following form:
177 char *dls_name; /* Name of library search
179 unsigned int dls_flags; /* Indicates where this
180 directory came from */
187 field is currently unused, and always contains zero.
189 .BR RTLD_DI_SERINFOSIZE " (\fIDl_serinfo *\fP)"
196 structure pointed to by
198 with values suitable for allocating a buffer for use in a subsequent
202 .BR RTLD_DI_TLS_MODID " (\fIsize_t *\fP, since glibc 2.4)"
203 Obtain the module ID of this shared object's TLS (thread-local storage)
204 segment, as used in TLS relocations.
205 If this object does not define a TLS segment, zero is placed in
208 .BR RTLD_DI_TLS_DATA " (\fIvoid **\fP, since glibc 2.4)"
209 Obtain a pointer to the calling
210 thread's TLS block corresponding to this shared object's TLS segment.
211 If this object does not define a PT_TLS segment,
212 or if the calling thread has not allocated a block for it,
219 On failure, it returns \-1; the cause of the error can be diagnosed using
223 first appeared in glibc 2.3.3.
225 For an explanation of the terms used in this section, see
233 Interface Attribute Value
236 T} Thread safety MT-Safe
242 This function is a nonstandard GNU extension.
244 This function derives from the Solaris function of the same name
245 and also appears on some other systems.
246 The sets of requests supported by the various implementations
247 overlaps only partially.
249 The program below opens a shared objects using
252 .B RTLD_DI_SERINFOSIZE
255 requests to obtain the library search path list for the library.
256 Here is an example of what we might see when running the program:
260 $ \fB./a.out /lib64/libm.so.6\fP
261 dls_serpath[0].dls_name = /lib64
262 dls_serpath[1].dls_name = /usr/lib64
275 main(int argc, char *argv[])
282 fprintf(stderr, "Usage: %s <libpath>\en", argv[0]);
286 /* Obtain a handle for shared object specified on command line. */
288 handle = dlopen(argv[1], RTLD_NOW);
289 if (handle == NULL) {
290 fprintf(stderr, "dlopen() failed: %s\en", dlerror());
294 /* Discover the size of the buffer that we must pass to
297 if (dlinfo(handle, RTLD_DI_SERINFOSIZE, &serinfo) == \-1) {
298 fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\en", dlerror());
302 /* Allocate the buffer for use with RTLD_DI_SERINFO. */
304 sip = malloc(serinfo.dls_size);
310 /* Initialize the \(aqdls_size\(aq and \(aqdls_cnt\(aq fields in the newly
313 if (dlinfo(handle, RTLD_DI_SERINFOSIZE, sip) == \-1) {
314 fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\en", dlerror());
318 /* Fetch and print library search list. */
320 if (dlinfo(handle, RTLD_DI_SERINFO, sip) == \-1) {
321 fprintf(stderr, "RTLD_DI_SERINFO failed: %s\en", dlerror());
325 for (int j = 0; j < serinfo.dls_cnt; j++)
326 printf("dls_serpath[%d].dls_name = %s\en",
327 j, sip\->dls_serpath[j].dls_name);
333 .BR dl_iterate_phdr (3),