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