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 at‐
126 tributes(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 li‐
144 brary search path list for the library. Here is an example of what we
145 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
166 if (argc != 2) {
167 fprintf(stderr, "Usage: %s <libpath>\n", argv[0]);
168 exit(EXIT_FAILURE);
169 }
170
171 /* Obtain a handle for shared object specified on command line */
172
173 handle = dlopen(argv[1], RTLD_NOW);
174 if (handle == NULL) {
175 fprintf(stderr, "dlopen() failed: %s\n", dlerror());
176 exit(EXIT_FAILURE);
177 }
178
179 /* Discover the size of the buffer that we must pass to
180 RTLD_DI_SERINFO */
181
182 if (dlinfo(handle, RTLD_DI_SERINFOSIZE, &serinfo) == -1) {
183 fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\n", dlerror());
184 exit(EXIT_FAILURE);
185 }
186
187 /* Allocate the buffer for use with RTLD_DI_SERINFO */
188
189 sip = malloc(serinfo.dls_size);
190 if (sip == NULL) {
191 perror("malloc");
192 exit(EXIT_FAILURE);
193 }
194
195 /* Initialize the 'dls_size' and 'dls_cnt' fields in the newly
196 allocated buffer */
197
198 if (dlinfo(handle, RTLD_DI_SERINFOSIZE, sip) == -1) {
199 fprintf(stderr, "RTLD_DI_SERINFOSIZE failed: %s\n", dlerror());
200 exit(EXIT_FAILURE);
201 }
202
203 /* Fetch and print library search list */
204
205 if (dlinfo(handle, RTLD_DI_SERINFO, sip) == -1) {
206 fprintf(stderr, "RTLD_DI_SERINFO failed: %s\n", dlerror());
207 exit(EXIT_FAILURE);
208 }
209
210 for (int j = 0; j < serinfo.dls_cnt; j++)
211 printf("dls_serpath[%d].dls_name = %s\n",
212 j, sip->dls_serpath[j].dls_name);
213
214 exit(EXIT_SUCCESS);
215 }
216
218 dl_iterate_phdr(3), dladdr(3), dlerror(3), dlopen(3), dlsym(3),
219 ld.so(8)
220
222 This page is part of release 5.10 of the Linux man-pages project. A
223 description of the project, information about reporting bugs, and the
224 latest version of this page, can be found at
225 https://www.kernel.org/doc/man-pages/.
226
227
228
229Linux 2020-11-01 DLINFO(3)