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