]>
Commit | Line | Data |
---|---|---|
a1eaacb1 | 1 | '\" t |
2b8adcef MK |
2 | .\" Copyright (C) 2015 Michael Kerrisk <mtk.manpages@gmail.com> |
3 | .\" | |
5fbde956 | 4 | .\" SPDX-License-Identifier: Linux-man-pages-copyleft |
2b8adcef | 5 | .\" |
ab47278f | 6 | .TH DLINFO 3 (date) "Linux man-pages (unreleased)" |
2b8adcef MK |
7 | .SH NAME |
8 | dlinfo \- obtain information about a dynamically loaded object | |
eda8a717 AC |
9 | .SH LIBRARY |
10 | Dynamic linking library | |
11 | .RI ( libdl ", " \-ldl ) | |
2b8adcef MK |
12 | .SH SYNOPSIS |
13 | .nf | |
14 | .B #define _GNU_SOURCE | |
15 | .B #include <link.h> | |
16 | .B #include <dlfcn.h> | |
f90f031e | 17 | .PP |
fbea610b AC |
18 | .BR "int dlinfo(void *restrict " handle ", int " request \ |
19 | ", void *restrict " info ); | |
2b8adcef MK |
20 | .fi |
21 | .SH DESCRIPTION | |
22 | The | |
23 | .BR dlinfo () | |
24 | function obtains information about the dynamically loaded object | |
25 | referred to by | |
1ae6b2c7 | 26 | .I handle |
2b8adcef MK |
27 | (typically obtained by an earlier call to |
28 | .BR dlopen (3) | |
29 | or | |
30 | .BR dlmopen (3)). | |
31 | The | |
32 | .I request | |
33 | argument specifies which information is to be returned. | |
34 | The | |
35 | .I info | |
36 | argument is a pointer to a buffer used to store information | |
37 | returned by the call; the type of this argument depends on | |
38 | .IR request . | |
847e0d88 | 39 | .PP |
2b8adcef | 40 | The following values are supported for |
1ae6b2c7 | 41 | .I request |
2b8adcef | 42 | (with the corresponding type for |
1ae6b2c7 | 43 | .I info |
2b8adcef MK |
44 | shown in parentheses): |
45 | .TP | |
46 | .BR RTLD_DI_LMID " (\fILmid_t *\fP)" | |
47 | Obtain the ID of the link-map list (namespace) in which | |
48 | .I handle | |
49 | is loaded. | |
50 | .TP | |
51 | .BR RTLD_DI_LINKMAP " (\fIstruct link_map **\fP)" | |
52 | Obtain a pointer to the | |
53 | .I link_map | |
54 | structure corresponding to | |
55 | .IR handle . | |
56 | The | |
1ae6b2c7 | 57 | .I info |
2b8adcef MK |
58 | argument points to a pointer to a |
59 | .I link_map | |
60 | structure, defined in | |
61 | .I <link.h> | |
62 | as: | |
847e0d88 | 63 | .IP |
2b8adcef | 64 | .in +4n |
b8302363 | 65 | .EX |
2b8adcef MK |
66 | struct link_map { |
67 | ElfW(Addr) l_addr; /* Difference between the | |
68 | address in the ELF file and | |
69 | the address in memory */ | |
70 | char *l_name; /* Absolute pathname where | |
71 | object was found */ | |
72 | ElfW(Dyn) *l_ld; /* Dynamic section of the | |
73 | shared object */ | |
74 | struct link_map *l_next, *l_prev; | |
75 | /* Chain of loaded objects */ | |
76 | ||
77 | /* Plus additional fields private to the | |
78 | implementation */ | |
79 | }; | |
b8302363 | 80 | .EE |
2b8adcef MK |
81 | .in |
82 | .TP | |
83 | .BR RTLD_DI_ORIGIN " (\fIchar *\fP)" | |
84 | Copy the pathname of the origin of the shared object corresponding to | |
1ae6b2c7 | 85 | .I handle |
2b8adcef MK |
86 | to the location pointed to by |
87 | .IR info . | |
88 | .TP | |
89 | .BR RTLD_DI_SERINFO " (\fIDl_serinfo *\fP)" | |
90 | Obtain the library search paths for the shared object referred to by | |
91 | .IR handle . | |
92 | The | |
93 | .I info | |
94 | argument is a pointer to a | |
95 | .I Dl_serinfo | |
96 | that contains the search paths. | |
97 | Because the number of search paths may vary, | |
98 | the size of the structure pointed to by | |
1ae6b2c7 | 99 | .I info |
2b8adcef MK |
100 | can vary. |
101 | The | |
102 | .B RTLD_DI_SERINFOSIZE | |
103 | request described below allows applications to size the buffer suitably. | |
104 | The caller must perform the following steps: | |
105 | .RS | |
22356d97 | 106 | .IP (1) 5 |
2b8adcef MK |
107 | Use a |
108 | .B RTLD_DI_SERINFOSIZE | |
109 | request to populate a | |
110 | .I Dl_serinfo | |
111 | structure with the size | |
112 | .RI ( dls_size ) | |
113 | of the structure needed for the subsequent | |
114 | .B RTLD_DI_SERINFO | |
115 | request. | |
22356d97 | 116 | .IP (2) |
2b8adcef MK |
117 | Allocate a |
118 | .I Dl_serinfo | |
119 | buffer of the correct size | |
120 | .RI ( dls_size ). | |
22356d97 | 121 | .IP (3) |
2b8adcef MK |
122 | Use a further |
123 | .B RTLD_DI_SERINFOSIZE | |
124 | request to populate the | |
125 | .I dls_size | |
126 | and | |
127 | .I dls_cnt | |
128 | fields of the buffer allocated in the previous step. | |
22356d97 | 129 | .IP (4) |
2b8adcef MK |
130 | Use a |
131 | .B RTLD_DI_SERINFO | |
132 | to obtain the library search paths. | |
2b8adcef MK |
133 | .RE |
134 | .IP | |
135 | The | |
136 | .I Dl_serinfo | |
137 | structure is defined as follows: | |
847e0d88 | 138 | .IP |
2b8adcef | 139 | .in +4n |
b8302363 | 140 | .EX |
2b8adcef MK |
141 | typedef struct { |
142 | size_t dls_size; /* Size in bytes of | |
143 | the whole buffer */ | |
144 | unsigned int dls_cnt; /* Number of elements | |
861d36ba | 145 | in \(aqdls_serpath\(aq */ |
2b8adcef | 146 | Dl_serpath dls_serpath[1]; /* Actually longer, |
861d36ba | 147 | \(aqdls_cnt\(aq elements */ |
2b8adcef | 148 | } Dl_serinfo; |
e646a1ba | 149 | .EE |
2b8adcef | 150 | .in |
e646a1ba | 151 | .IP |
2b8adcef MK |
152 | Each of the |
153 | .I dls_serpath | |
154 | elements in the above structure is a structure of the following form: | |
847e0d88 | 155 | .IP |
2b8adcef | 156 | .in +4n |
b8302363 | 157 | .EX |
2b8adcef MK |
158 | typedef struct { |
159 | char *dls_name; /* Name of library search | |
160 | path directory */ | |
161 | unsigned int dls_flags; /* Indicates where this | |
162 | directory came from */ | |
163 | } Dl_serpath; | |
b8302363 | 164 | .EE |
2b8adcef | 165 | .in |
847e0d88 | 166 | .IP |
2b8adcef MK |
167 | The |
168 | .I dls_flags | |
169 | field is currently unused, and always contains zero. | |
170 | .TP | |
171 | .BR RTLD_DI_SERINFOSIZE " (\fIDl_serinfo *\fP)" | |
172 | Populate the | |
173 | .I dls_size | |
174 | and | |
175 | .I dls_cnt | |
176 | fields of the | |
177 | .I Dl_serinfo | |
178 | structure pointed to by | |
1ae6b2c7 | 179 | .I info |
2b8adcef MK |
180 | with values suitable for allocating a buffer for use in a subsequent |
181 | .B RTLD_DI_SERINFO | |
182 | request. | |
183 | .TP | |
184 | .BR RTLD_DI_TLS_MODID " (\fIsize_t *\fP, since glibc 2.4)" | |
185 | Obtain the module ID of this shared object's TLS (thread-local storage) | |
186 | segment, as used in TLS relocations. | |
187 | If this object does not define a TLS segment, zero is placed in | |
188 | .IR *info . | |
189 | .TP | |
190 | .BR RTLD_DI_TLS_DATA " (\fIvoid **\fP, since glibc 2.4)" | |
191 | Obtain a pointer to the calling | |
192 | thread's TLS block corresponding to this shared object's TLS segment. | |
193 | If this object does not define a PT_TLS segment, | |
194 | or if the calling thread has not allocated a block for it, | |
195 | NULL is placed in | |
196 | .IR *info . | |
197 | .SH RETURN VALUE | |
198 | On success, | |
199 | .BR dlinfo () | |
200 | returns 0. | |
201 | On failure, it returns \-1; the cause of the error can be diagnosed using | |
202 | .BR dlerror (3). | |
203 | .SH VERSIONS | |
204 | .BR dlinfo () | |
205 | first appeared in glibc 2.3.3. | |
51f796a4 MK |
206 | .SH ATTRIBUTES |
207 | For an explanation of the terms used in this section, see | |
208 | .BR attributes (7). | |
c466875e MK |
209 | .ad l |
210 | .nh | |
51f796a4 MK |
211 | .TS |
212 | allbox; | |
c466875e | 213 | lbx lb lb |
51f796a4 MK |
214 | l l l. |
215 | Interface Attribute Value | |
216 | T{ | |
217 | .BR dlinfo () | |
218 | T} Thread safety MT-Safe | |
219 | .TE | |
c466875e MK |
220 | .hy |
221 | .ad | |
222 | .sp 1 | |
3113c7f3 | 223 | .SH STANDARDS |
2b8adcef MK |
224 | This function is a nonstandard GNU extension. |
225 | .SH NOTES | |
226 | This function derives from the Solaris function of the same name | |
227 | and also appears on some other systems. | |
228 | The sets of requests supported by the various implementations | |
229 | overlaps only partially. | |
a14af333 | 230 | .SH EXAMPLES |
2b8adcef | 231 | The program below opens a shared objects using |
95183c2e | 232 | .BR dlopen (3) |
2b8adcef MK |
233 | and then uses the |
234 | .B RTLD_DI_SERINFOSIZE | |
235 | and | |
236 | .B RTLD_DI_SERINFO | |
237 | requests to obtain the library search path list for the library. | |
238 | Here is an example of what we might see when running the program: | |
847e0d88 | 239 | .PP |
2b8adcef | 240 | .in +4n |
b8302363 | 241 | .EX |
2b8adcef MK |
242 | $ \fB./a.out /lib64/libm.so.6\fP |
243 | dls_serpath[0].dls_name = /lib64 | |
244 | dls_serpath[1].dls_name = /usr/lib64 | |
b8302363 | 245 | .EE |
2b8adcef MK |
246 | .in |
247 | .SS Program source | |
248 | \& | |
b0b6ab4e | 249 | .\" SRC BEGIN (dlinfo.c) |
e7d0bb47 | 250 | .EX |
2b8adcef MK |
251 | #define _GNU_SOURCE |
252 | #include <dlfcn.h> | |
253 | #include <link.h> | |
254 | #include <stdio.h> | |
255 | #include <stdlib.h> | |
256 | ||
257 | int | |
258 | main(int argc, char *argv[]) | |
259 | { | |
260 | void *handle; | |
261 | Dl_serinfo serinfo; | |
262 | Dl_serinfo *sip; | |
2b8adcef MK |
263 | |
264 | if (argc != 2) { | |
d1a71985 | 265 | fprintf(stderr, "Usage: %s <libpath>\en", argv[0]); |
2b8adcef MK |
266 | exit(EXIT_FAILURE); |
267 | } | |
268 | ||
46b20ca1 | 269 | /* Obtain a handle for shared object specified on command line. */ |
2b8adcef MK |
270 | |
271 | handle = dlopen(argv[1], RTLD_NOW); | |
272 | if (handle == NULL) { | |
d1a71985 | 273 | fprintf(stderr, "dlopen() failed: %s\en", dlerror()); |
2b8adcef MK |
274 | exit(EXIT_FAILURE); |
275 | } | |
276 | ||
277 | /* Discover the size of the buffer that we must pass to | |
46b20ca1 | 278 | RTLD_DI_SERINFO. */ |
2b8adcef MK |
279 | |
280 | if (dlinfo(handle, RTLD_DI_SERINFOSIZE, &serinfo) == \-1) { | |
d1a71985 | 281 | fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\en", dlerror()); |
2b8adcef MK |
282 | exit(EXIT_FAILURE); |
283 | } | |
284 | ||
46b20ca1 | 285 | /* Allocate the buffer for use with RTLD_DI_SERINFO. */ |
2b8adcef MK |
286 | |
287 | sip = malloc(serinfo.dls_size); | |
288 | if (sip == NULL) { | |
289 | perror("malloc"); | |
290 | exit(EXIT_FAILURE); | |
291 | } | |
292 | ||
293 | /* Initialize the \(aqdls_size\(aq and \(aqdls_cnt\(aq fields in the newly | |
46b20ca1 | 294 | allocated buffer. */ |
2b8adcef MK |
295 | |
296 | if (dlinfo(handle, RTLD_DI_SERINFOSIZE, sip) == \-1) { | |
d1a71985 | 297 | fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\en", dlerror()); |
2b8adcef MK |
298 | exit(EXIT_FAILURE); |
299 | } | |
300 | ||
46b20ca1 | 301 | /* Fetch and print library search list. */ |
2b8adcef MK |
302 | |
303 | if (dlinfo(handle, RTLD_DI_SERINFO, sip) == \-1) { | |
d1a71985 | 304 | fprintf(stderr, "RTLD_DI_SERINFO failed: %s\en", dlerror()); |
2b8adcef MK |
305 | exit(EXIT_FAILURE); |
306 | } | |
307 | ||
b42296e4 AC |
308 | for (size_t j = 0; j < serinfo.dls_cnt; j++) |
309 | printf("dls_serpath[%zu].dls_name = %s\en", | |
d917c31d | 310 | j, sip\->dls_serpath[j].dls_name); |
2b8adcef MK |
311 | |
312 | exit(EXIT_SUCCESS); | |
313 | } | |
e7d0bb47 | 314 | .EE |
b0b6ab4e | 315 | .\" SRC END |
2b8adcef MK |
316 | .SH SEE ALSO |
317 | .BR dl_iterate_phdr (3), | |
318 | .BR dladdr (3), | |
da9356be | 319 | .BR dlerror (3), |
2b8adcef | 320 | .BR dlopen (3), |
273b4e24 | 321 | .BR dlsym (3), |
2b8adcef | 322 | .BR ld.so (8) |