1DLINFO(3) Linux Programmer's Manual DLINFO(3)
2
3
4
6 dlinfo - obtain information about a dynamically loaded object
7
9 #define _GNU_SOURCE
10 #include <link.h>
11 #include <dlfcn.h>
12
13 int dlinfo(void *handle, int request, void *info);
14
15 Link with -ldl.
16
18 The dlinfo() function obtains information about the dynamically loaded
19 object referred to by handle (typically obtained by an earlier call to
20 dlopen(3) or dlmopen(3)). The request argument specifies which infor‐
21 mation is to be returned. The info argument is a pointer to a buffer
22 used to store information returned by the call; the type of this argu‐
23 ment depends on request.
24
25 The following values are supported for request (with the corresponding
26 type for info shown in parentheses):
27
28 RTLD_DI_LMID (Lmid_t *)
29 Obtain the ID of the link-map list (namespace) in which handle
30 is loaded.
31
32 RTLD_DI_LINKMAP (struct link_map **)
33 Obtain a pointer to the link_map structure corresponding to han‐
34 dle. The info argument points to a pointer to a link_map struc‐
35 ture, defined in <link.h> as:
36
37 struct link_map {
38 ElfW(Addr) l_addr; /* Difference between the
39 address in the ELF file and
40 the address in memory */
41 char *l_name; /* Absolute pathname where
42 object was found */
43 ElfW(Dyn) *l_ld; /* Dynamic section of the
44 shared object */
45 struct link_map *l_next, *l_prev;
46 /* Chain of loaded objects */
47
48 /* Plus additional fields private to the
49 implementation */
50 };
51
52 RTLD_DI_ORIGIN (char *)
53 Copy the pathname of the origin of the shared object correspond‐
54 ing to handle to the location pointed to by info.
55
56 RTLD_DI_SERINFO (Dl_serinfo *)
57 Obtain the library search paths for the shared object referred
58 to by handle. The info argument is a pointer to a Dl_serinfo
59 that contains the search paths. Because the number of search
60 paths may vary, the size of the structure pointed to by info can
61 vary. The RTLD_DI_SERINFOSIZE request described below allows
62 applications to size the buffer suitably. The caller must per‐
63 form the following steps:
64
65 1. Use a RTLD_DI_SERINFOSIZE request to populate a Dl_serinfo
66 structure with the size (dls_size) of the structure needed
67 for the subsequent RTLD_DI_SERINFO request.
68
69 2. Allocate a Dl_serinfo buffer of the correct size (dls_size).
70
71 3. Use a further RTLD_DI_SERINFOSIZE request to populate the
72 dls_size and dls_cnt fields of the buffer allocated in the
73 previous step.
74
75 4. Use a RTLD_DI_SERINFO to obtain the library search paths.
76
77 The Dl_serinfo structure is defined as follows:
78
79 typedef struct {
80 size_t dls_size; /* Size in bytes of
81 the whole buffer */
82 unsigned int dls_cnt; /* Number of elements
83 in 'dls_serpath' */
84 Dl_serpath dls_serpath[1]; /* Actually longer,
85 'dls_cnt' elements */
86 } Dl_serinfo;
87
88 Each of the dls_serpath elements in the above structure is a
89 structure of the following form:
90
91 typedef struct {
92 char *dls_name; /* Name of library search
93 path directory */
94 unsigned int dls_flags; /* Indicates where this
95 directory came from */
96 } Dl_serpath;
97
98 The dls_flags field is currently unused, and always contains
99 zero.
100
101 RTLD_DI_SERINFOSIZE (Dl_serinfo *)
102 Populate the dls_size and dls_cnt fields of the Dl_serinfo
103 structure pointed to by info with values suitable for allocating
104 a buffer for use in a subsequent RTLD_DI_SERINFO request.
105
106 RTLD_DI_TLS_MODID (size_t *, since glibc 2.4)
107 Obtain the module ID of this shared object's TLS (thread-local
108 storage) segment, as used in TLS relocations. If this object
109 does not define a TLS segment, zero is placed in *info.
110
111 RTLD_DI_TLS_DATA (void **, since glibc 2.4)
112 Obtain a pointer to the calling thread's TLS block corresponding
113 to this shared object's TLS segment. If this object does not
114 define a PT_TLS segment, or if the calling thread has not allo‐
115 cated a block for it, NULL is placed in *info.
116
118 On success, dlinfo() returns 0. On failure, it returns -1; the cause
119 of the error can be diagnosed using dlerror(3).
120
122 dlinfo() first appeared in glibc 2.3.3.
123
125 For an explanation of the terms used in this section, see
126 attributes(7).
127
128 ┌──────────┬───────────────┬─────────┐
129 │Interface │ Attribute │ Value │
130 ├──────────┼───────────────┼─────────┤
131 │dlinfo() │ Thread safety │ MT-Safe │
132 └──────────┴───────────────┴─────────┘
134 This function is a nonstandard GNU extension.
135
137 This function derives from the Solaris function of the same name and
138 also appears on some other systems. The sets of requests supported by
139 the various implementations overlaps only partially.
140
142 The program below opens a shared objects using dlopen(3) and then uses
143 the RTLD_DI_SERINFOSIZE and RTLD_DI_SERINFO requests to obtain the
144 library search path list for the library. Here is an example of what
145 we might see when running the program:
146
147 $ ./a.out /lib64/libm.so.6
148 dls_serpath[0].dls_name = /lib64
149 dls_serpath[1].dls_name = /usr/lib64
150
151 Program source
152
153 #define _GNU_SOURCE
154 #include <dlfcn.h>
155 #include <link.h>
156 #include <stdio.h>
157 #include <stdlib.h>
158
159 int
160 main(int argc, char *argv[])
161 {
162 void *handle;
163 Dl_serinfo serinfo;
164 Dl_serinfo *sip;
165 int j;
166
167 if (argc != 2) {
168 fprintf(stderr, "Usage: %s <libpath>\n", argv[0]);
169 exit(EXIT_FAILURE);
170 }
171
172 /* Obtain a handle for shared objects specified on command line */
173
174 handle = dlopen(argv[1], RTLD_NOW);
175 if (handle == NULL) {
176 fprintf(stderr, "dlopen() failed: %s\n", dlerror());
177 exit(EXIT_FAILURE);
178 }
179
180 /* Discover the size of the buffer that we must pass to
181 RTLD_DI_SERINFO */
182
183 if (dlinfo(handle, RTLD_DI_SERINFOSIZE, &serinfo) == -1) {
184 fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\n", dlerror());
185 exit(EXIT_FAILURE);
186 }
187
188 /* Allocate the buffer for use with RTLD_DI_SERINFO */
189
190 sip = malloc(serinfo.dls_size);
191 if (sip == NULL) {
192 perror("malloc");
193 exit(EXIT_FAILURE);
194 }
195
196 /* Initialize the 'dls_size' and 'dls_cnt' fields in the newly
197 allocated buffer */
198
199 if (dlinfo(handle, RTLD_DI_SERINFOSIZE, sip) == -1) {
200 fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\n", dlerror());
201 exit(EXIT_FAILURE);
202 }
203
204 /* Fetch and print library search list */
205
206 if (dlinfo(handle, RTLD_DI_SERINFO, sip) == -1) {
207 fprintf(stderr, "RTLD_DI_SERINFO failed: %s\n", dlerror());
208 exit(EXIT_FAILURE);
209 }
210
211 for (j = 0; j < serinfo.dls_cnt; j++)
212 printf("dls_serpath[%d].dls_name = %s\n",
213 j, sip->dls_serpath[j].dls_name);
214
215 exit(EXIT_SUCCESS);
216 }
217
219 dl_iterate_phdr(3), dladdr(3), dlerror(3), dlopen(3), dlsym(3),
220 ld.so(8)
221
223 This page is part of release 4.16 of the Linux man-pages project. A
224 description of the project, information about reporting bugs, and the
225 latest version of this page, can be found at
226 https://www.kernel.org/doc/man-pages/.
227
228
229
230Linux 2017-09-15 DLINFO(3)