1DLOPEN(3) Linux Programmer's Manual DLOPEN(3)
2
3
4
6 dladdr, dlclose, dlerror, dlopen, dlsym, dlvsym - programming interface
7 to dynamic linking loader
8
10 #include <dlfcn.h>
11
12 void *dlopen(const char *filename, int flag);
13
14 char *dlerror(void);
15
16 void *dlsym(void *handle, const char *symbol);
17
18 int dlclose(void *handle);
19
20 Link with -ldl.
21
23 The four functions dlopen(), dlsym(), dlclose(), dlerror() implement
24 the interface to the dynamic linking loader.
25
26 dlerror()
27 The function dlerror() returns a human readable string describing the
28 most recent error that occurred from dlopen(), dlsym() or dlclose()
29 since the last call to dlerror(). It returns NULL if no errors have
30 occurred since initialization or since it was last called.
31
32 dlopen()
33 The function dlopen() loads the dynamic library file named by the null-
34 terminated string filename and returns an opaque "handle" for the
35 dynamic library. If filename is NULL, then the returned handle is for
36 the main program. If filename contains a slash ("/"), then it is
37 interpreted as a (relative or absolute) pathname. Otherwise, the
38 dynamic linker searches for the library as follows (see ld.so(8) for
39 further details):
40
41 o (ELF only) If the executable file for the calling program contains
42 a DT_RPATH tag, and does not contain a DT_RUNPATH tag, then the
43 directories listed in the DT_RPATH tag are searched.
44
45 o If, at the time that the program was started, the environment vari‐
46 able LD_LIBRARY_PATH was defined to contain a colon-separated list
47 of directories, then these are searched. (As a security measure
48 this variable is ignored for set-user-ID and set-group-ID pro‐
49 grams.)
50
51 o (ELF only) If the executable file for the calling program contains
52 a DT_RUNPATH tag, then the directories listed in that tag are
53 searched.
54
55 o The cache file /etc/ld.so.cache (maintained by ldconfig(8)) is
56 checked to see whether it contains an entry for filename.
57
58 o The directories /lib and /usr/lib are searched (in that order).
59
60 If the library has dependencies on other shared libraries, then these
61 are also automatically loaded by the dynamic linker using the same
62 rules. (This process may occur recursively, if those libraries in turn
63 have dependencies, and so on.)
64
65 One of the following two values must be included in flag:
66
67 RTLD_LAZY
68 Perform lazy binding. Only resolve symbols as the code that
69 references them is executed. If the symbol is never referenced,
70 then it is never resolved. (Lazy binding is only performed for
71 function references; references to variables are always immedi‐
72 ately bound when the library is loaded.)
73
74 RTLD_NOW
75 If this value is specified, or the environment variable
76 LD_BIND_NOW is set to a non-empty string, all undefined symbols
77 in the library are resolved before dlopen() returns. If this
78 cannot be done, an error is returned.
79
80 Zero of more of the following values may also be ORed in flag:
81
82 RTLD_GLOBAL
83 The symbols defined by this library will be made available for
84 symbol resolution of subsequently loaded libraries.
85
86 RTLD_LOCAL
87 This is the converse of RTLD_GLOBAL, and the default if neither
88 flag is specified. Symbols defined in this library are not made
89 available to resolve references in subsequently loaded
90 libraries.
91
92 RTLD_NODELETE (since glibc 2.2)
93 Do not unload the library during dlclose(). Consequently, the
94 library's static variables are not reinitialized if the library
95 is reloaded with dlopen() at a later time. This flag is not
96 specified in POSIX.1-2001.
97
98 RTLD_NOLOAD (since glibc 2.2)
99 Don't load the library. This can be used to test if the library
100 is already resident (dlopen() returns NULL if it is not, or the
101 library's handle if it is resident). This flag can also be used
102 to promote the flags on a library that is already loaded. For
103 example, a library that was previously loaded with RTLD_LOCAL
104 can be re-opened with RTLD_NOLOAD | RTLD_GLOBAL. This flag is
105 not specified in POSIX.1-2001.
106
107 RTLD_DEEPBIND (since glibc 2.3.4)
108 Place the lookup scope of the symbols in this library ahead of
109 the global scope. This means that a self-contained library will
110 use its own symbols in preference to global symbols with the
111 same name contained in libraries that have already been loaded.
112 This flag is not specified in POSIX.1-2001.
113
114 If filename is a NULL pointer, then the returned handle is for the main
115 program. When given to dlsym(), this handle causes a search for a sym‐
116 bol in the main program, followed by all shared libraries loaded at
117 program startup, and then all shared libraries loaded by dlopen() with
118 the flag RTLD_GLOBAL.
119
120 External references in the library are resolved using the libraries in
121 that library's dependency list and any other libraries previously
122 opened with the RTLD_GLOBAL flag. If the executable was linked with
123 the flag "-rdynamic" (or, synonymously, "--export-dynamic"), then the
124 global symbols in the executable will also be used to resolve refer‐
125 ences in a dynamically loaded library.
126
127 If the same library is loaded again with dlopen(), the same file handle
128 is returned. The dl library maintains reference counts for library
129 handles, so a dynamic library is not deallocated until dlclose() has
130 been called on it as many times as dlopen() has succeeded on it. The
131 _init() routine, if present, is only called once. But a subsequent
132 call with RTLD_NOW may force symbol resolution for a library earlier
133 loaded with RTLD_LAZY.
134
135 If dlopen() fails for any reason, it returns NULL.
136
137 dlsym()
138 The function dlsym() takes a "handle" of a dynamic library returned by
139 dlopen() and the null-terminated symbol name, returning the address
140 where that symbol is loaded into memory. If the symbol is not found,
141 in the specified library or any of the libraries that were automati‐
142 cally loaded by dlopen() when that library was loaded, dlsym() returns
143 NULL. (The search performed by dlsym() is breadth first through the
144 dependency tree of these libraries.) Since the value of the symbol
145 could actually be NULL (so that a NULL return from dlsym() need not
146 indicate an error), the correct way to test for an error is to call
147 dlerror() to clear any old error conditions, then call dlsym(), and
148 then call dlerror() again, saving its return value into a variable, and
149 check whether this saved value is not NULL.
150
151 There are two special pseudo-handles, RTLD_DEFAULT and RTLD_NEXT. The
152 former will find the first occurrence of the desired symbol using the
153 default library search order. The latter will find the next occurrence
154 of a function in the search order after the current library. This
155 allows one to provide a wrapper around a function in another shared
156 library.
157
158 dlclose()
159 The function dlclose() decrements the reference count on the dynamic
160 library handle handle. If the reference count drops to zero and no
161 other loaded libraries use symbols in it, then the dynamic library is
162 unloaded.
163
164 The function dlclose() returns 0 on success, and non-zero on error.
165
166 The obsolete symbols _init() and _fini()
167 The linker recognizes special symbols _init and _fini. If a dynamic
168 library exports a routine named _init(), then that code is executed
169 after the loading, before dlopen() returns. If the dynamic library
170 exports a routine named _fini(), then that routine is called just
171 before the library is unloaded. In case you need to avoid linking
172 against the system startup files, this can be done by using the gcc(1)
173 -nostartfiles command-line option.
174
175 Using these routines, or the gcc -nostartfiles or -nostdlib options, is
176 not recommended. Their use may result in undesired behavior, since the
177 constructor/destructor routines will not be executed (unless special
178 measures are taken).
179
180 Instead, libraries should export routines using the __attribute__((con‐
181 structor)) and __attribute__((destructor)) function attributes. See
182 the gcc info pages for information on these. Constructor routines are
183 executed before dlopen() returns, and destructor routines are executed
184 before dlclose() returns.
185
186 Glibc extensions: dladdr() and dlvsym()
187 Glibc adds two functions not described by POSIX, with prototypes
188
189 #define _GNU_SOURCE
190 #include <dlfcn.h>
191
192 int dladdr(void *addr, Dl_info *info);
193
194 void *dlvsym(void *handle, char *symbol, char *version);
195
196 The function dladdr() takes a function pointer and tries to resolve
197 name and file where it is located. Information is stored in the
198 Dl_info structure:
199
200 typedef struct {
201 const char *dli_fname; /* Pathname of shared object that
202 contains address */
203 void *dli_fbase; /* Address at which shared object
204 is loaded */
205 const char *dli_sname; /* Name of nearest symbol with address
206 lower than addr */
207 void *dli_saddr; /* Exact address of symbol named
208 in dli_sname */
209 } Dl_info;
210
211 If no symbol matching addr could be found, then dli_sname and dli_saddr
212 are set to NULL.
213
214 dladdr() returns 0 on error, and non-zero on success.
215
216 The function dlvsym(), provided by glibc since version 2.1, does the
217 same as dlsym() but takes a version string as an additional argument.
218
220 POSIX.1-2001 describes dlclose(), dlerror(), dlopen(), and dlsym().
221
223 The symbols RTLD_DEFAULT and RTLD_NEXT are defined by <dlfcn.h> only
224 when _GNU_SOURCE was defined before including it.
225
226 Since glibc 2.2.3, atexit(3) can be used to register an exit handler
227 that is automatically called when a library is unloaded.
228
229 History
230 The dlopen interface standard comes from SunOS. That system also has
231 dladdr(), but not dlvsym().
232
234 Sometimes, the function pointers you pass to dladdr() may surprise you.
235 On some architectures (notably i386 and x86_64), dli_fname and
236 dli_fbase may end up pointing back at the object from which you called
237 dladdr(), even if the function used as an argument should come from a
238 dynamically linked library.
239
240 The problem is that the function pointer will still be resolved at com‐
241 pile time, but merely point to the plt (Procedure Linkage Table) sec‐
242 tion of the original object (which dispatches the call after asking the
243 dynamic linker to resolve the symbol). To work around this, you can
244 try to compile the code to be position-independent: then, the compiler
245 cannot prepare the pointer at compile time anymore and today's gcc(1)
246 will generate code that just loads the final symbol address from the
247 got (Global Offset Table) at run time before passing it to dladdr().
248
250 Load the math library, and print the cosine of 2.0:
251
252 #include <stdio.h>
253 #include <stdlib.h>
254 #include <dlfcn.h>
255
256 int
257 main(int argc, char **argv)
258 {
259 void *handle;
260 double (*cosine)(double);
261 char *error;
262
263 handle = dlopen("libm.so", RTLD_LAZY);
264 if (!handle) {
265 fprintf(stderr, "%s\n", dlerror());
266 exit(EXIT_FAILURE);
267 }
268
269 dlerror(); /* Clear any existing error */
270
271 /* Writing: cosine = (double (*)(double)) dlsym(handle, "cos");
272 would seem more natural, but the C99 standard leaves
273 casting from "void *" to a function pointer undefined.
274 The assignment used below is the POSIX.1-2003 (Technical
275 Corrigendum 1) workaround; see the Rationale for the
276 POSIX specification of dlsym(). */
277
278 *(void **) (&cosine) = dlsym(handle, "cos");
279
280 if ((error = dlerror()) != NULL) {
281 fprintf(stderr, "%s\n", error);
282 exit(EXIT_FAILURE);
283 }
284
285 printf("%f\n", (*cosine)(2.0));
286 dlclose(handle);
287 exit(EXIT_SUCCESS);
288 }
289
290 If this program were in a file named "foo.c", you would build the pro‐
291 gram with the following command:
292
293 gcc -rdynamic -o foo foo.c -ldl
294
295 Libraries exporting _init() and _fini() will want to be compiled as
296 follows, using bar.c as the example name:
297
298 gcc -shared -nostartfiles -o bar bar.c
299
301 ld(1), ldd(1), dl_iterate_phdr(3), feature_test_macros(7), rtld-
302 audit(7), ld.so(8), ldconfig(8), ld.so info pages, gcc info pages, ld
303 info pages
304
306 This page is part of release 3.22 of the Linux man-pages project. A
307 description of the project, and information about reporting bugs, can
308 be found at http://www.kernel.org/doc/man-pages/.
309
310
311
312Linux 2008-12-06 DLOPEN(3)