1 /* $NetBSD: rtld.c,v 1.171 2013/11/20 07:18:23 skrll Exp $ */
4 * Copyright 1996 John D. Polstra.
5 * Copyright 1996 Matt Thomas <matt@3am-software.com>
6 * Copyright 2002 Charles M. Hannum <root@ihack.net>
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by John Polstra.
20 * 4. The name of the author may not be used to endorse or promote products
21 * derived from this software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 * Dynamic linker for ELF.
38 * John Polstra <jdp@polstra.com>.
41 #include <sys/cdefs.h>
43 __RCSID("$NetBSD: rtld.c,v 1.171 2013/11/20 07:18:23 skrll Exp $");
46 #include <sys/param.h>
47 #include <sys/atomic.h>
54 #endif /* !defined(__minix) */
73 * Function declarations.
75 static void _rtld_init(caddr_t
, caddr_t
, const char *);
76 static void _rtld_exit(void);
78 Elf_Addr
_rtld(Elf_Addr
*, Elf_Addr
);
84 static char *error_message
; /* Message for dlopen(), or NULL */
86 struct r_debug _rtld_debug
; /* for GDB; */
87 bool _rtld_trust
; /* False for setuid and setgid programs */
88 Obj_Entry
*_rtld_objlist
; /* Head of linked list of shared objects */
89 Obj_Entry
**_rtld_objtail
; /* Link field of last object in list */
90 Obj_Entry
*_rtld_objmain
; /* The main program shared object */
91 Obj_Entry _rtld_objself
; /* The dynamic linker shared object */
92 u_int _rtld_objcount
; /* Number of objects in _rtld_objlist */
93 u_int _rtld_objloads
; /* Number of objects loaded in _rtld_objlist */
94 u_int _rtld_objgen
; /* Generation count for _rtld_objlist */
95 const char _rtld_path
[] = _PATH_RTLD
;
97 /* Initialize a fake symbol for resolving undefined weak references. */
98 Elf_Sym _rtld_sym_zero
= {
99 .st_info
= ELF_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
102 size_t _rtld_pagesz
; /* Page size, as provided by kernel */
104 Search_Path
*_rtld_default_paths
;
105 Search_Path
*_rtld_paths
;
107 Library_Xform
*_rtld_xforms
;
108 static void *auxinfo
;
111 * Global declarations normally provided by crt0.
116 #if !defined(__minix)
117 static volatile bool _rtld_mutex_may_recurse
;
118 #endif /* !defined(__minix) */
120 #if defined(RTLD_DEBUG)
122 extern Elf_Addr _GLOBAL_OFFSET_TABLE_
[];
123 #else /* 32-bit SuperH */
124 register Elf_Addr
*_GLOBAL_OFFSET_TABLE_
asm("r12");
126 #endif /* RTLD_DEBUG */
127 extern Elf_Dyn _DYNAMIC
;
129 static void _rtld_call_fini_functions(sigset_t
*, int);
130 static void _rtld_call_init_functions(sigset_t
*);
131 static void _rtld_initlist_visit(Objlist
*, Obj_Entry
*, int);
132 static void _rtld_initlist_tsort(Objlist
*, int);
133 static Obj_Entry
*_rtld_dlcheck(void *);
134 static void _rtld_init_dag(Obj_Entry
*);
135 static void _rtld_init_dag1(Obj_Entry
*, Obj_Entry
*);
136 static void _rtld_objlist_remove(Objlist
*, Obj_Entry
*);
137 static void _rtld_objlist_clear(Objlist
*);
138 static void _rtld_unload_object(sigset_t
*, Obj_Entry
*, bool);
139 static void _rtld_unref_dag(Obj_Entry
*);
140 static Obj_Entry
*_rtld_obj_from_addr(const void *);
143 _rtld_call_initfini_function(fptr_t func
, sigset_t
*mask
)
145 _rtld_exclusive_exit(mask
);
147 _rtld_exclusive_enter(mask
);
151 _rtld_call_fini_function(Obj_Entry
*obj
, sigset_t
*mask
, u_int cur_objgen
)
153 if (obj
->fini_arraysz
== 0 && (obj
->fini
== NULL
|| obj
->fini_called
)) {
156 if (obj
->fini
!= NULL
&& !obj
->fini_called
) {
157 dbg (("calling fini function %s at %p%s", obj
->path
,
159 obj
->z_initfirst
? " (DF_1_INITFIRST)" : ""));
160 obj
->fini_called
= 1;
161 _rtld_call_initfini_function(obj
->fini
, mask
);
163 #ifdef HAVE_INITFINI_ARRAY
165 * Now process the fini_array if it exists. Simply go from
166 * start to end. We need to make restartable so just advance
167 * the array pointer and decrement the size each time through
170 while (obj
->fini_arraysz
> 0 && _rtld_objgen
== cur_objgen
) {
171 fptr_t fini
= *obj
->fini_array
++;
173 dbg (("calling fini array function %s at %p%s", obj
->path
,
175 obj
->z_initfirst
? " (DF_1_INITFIRST)" : ""));
176 _rtld_call_initfini_function(fini
, mask
);
178 #endif /* HAVE_INITFINI_ARRAY */
182 _rtld_call_fini_functions(sigset_t
*mask
, int force
)
188 dbg(("_rtld_call_fini_functions(%d)", force
));
191 cur_objgen
= ++_rtld_objgen
;
192 SIMPLEQ_INIT(&finilist
);
193 _rtld_initlist_tsort(&finilist
, 1);
195 /* First pass: objects _not_ marked with DF_1_INITFIRST. */
196 SIMPLEQ_FOREACH(elm
, &finilist
, link
) {
197 Obj_Entry
* const obj
= elm
->obj
;
198 if (!obj
->z_initfirst
) {
199 if (obj
->refcount
> 0 && !force
) {
203 * XXX This can race against a concurrent dlclose().
204 * XXX In that case, the object could be unmapped before
205 * XXX the fini() call or the fini_array has completed.
207 _rtld_call_fini_function(obj
, mask
, cur_objgen
);
208 if (_rtld_objgen
!= cur_objgen
) {
209 dbg(("restarting fini iteration"));
210 _rtld_objlist_clear(&finilist
);
216 /* Second pass: objects marked with DF_1_INITFIRST. */
217 SIMPLEQ_FOREACH(elm
, &finilist
, link
) {
218 Obj_Entry
* const obj
= elm
->obj
;
219 if (obj
->refcount
> 0 && !force
) {
222 /* XXX See above for the race condition here */
223 _rtld_call_fini_function(obj
, mask
, cur_objgen
);
224 if (_rtld_objgen
!= cur_objgen
) {
225 dbg(("restarting fini iteration"));
226 _rtld_objlist_clear(&finilist
);
231 _rtld_objlist_clear(&finilist
);
235 _rtld_call_init_function(Obj_Entry
*obj
, sigset_t
*mask
, u_int cur_objgen
)
237 if (obj
->init_arraysz
== 0 && (obj
->init_called
|| obj
->init
== NULL
)) {
240 if (!obj
->init_called
&& obj
->init
!= NULL
) {
241 dbg (("calling init function %s at %p%s",
242 obj
->path
, (void *)obj
->init
,
243 obj
->z_initfirst
? " (DF_1_INITFIRST)" : ""));
244 obj
->init_called
= 1;
245 _rtld_call_initfini_function(obj
->init
, mask
);
248 #ifdef HAVE_INITFINI_ARRAY
250 * Now process the init_array if it exists. Simply go from
251 * start to end. We need to make restartable so just advance
252 * the array pointer and decrement the size each time through
255 while (obj
->init_arraysz
> 0 && _rtld_objgen
== cur_objgen
) {
256 fptr_t init
= *obj
->init_array
++;
258 dbg (("calling init_array function %s at %p%s",
259 obj
->path
, (void *)init
,
260 obj
->z_initfirst
? " (DF_1_INITFIRST)" : ""));
261 _rtld_call_initfini_function(init
, mask
);
263 #endif /* HAVE_INITFINI_ARRAY */
267 _rtld_call_init_functions(sigset_t
*mask
)
273 dbg(("_rtld_call_init_functions()"));
276 cur_objgen
= ++_rtld_objgen
;
277 SIMPLEQ_INIT(&initlist
);
278 _rtld_initlist_tsort(&initlist
, 0);
280 /* First pass: objects marked with DF_1_INITFIRST. */
281 SIMPLEQ_FOREACH(elm
, &initlist
, link
) {
282 Obj_Entry
* const obj
= elm
->obj
;
283 if (obj
->z_initfirst
) {
284 _rtld_call_init_function(obj
, mask
, cur_objgen
);
285 if (_rtld_objgen
!= cur_objgen
) {
286 dbg(("restarting init iteration"));
287 _rtld_objlist_clear(&initlist
);
293 /* Second pass: all other objects. */
294 SIMPLEQ_FOREACH(elm
, &initlist
, link
) {
295 _rtld_call_init_function(elm
->obj
, mask
, cur_objgen
);
296 if (_rtld_objgen
!= cur_objgen
) {
297 dbg(("restarting init iteration"));
298 _rtld_objlist_clear(&initlist
);
303 _rtld_objlist_clear(&initlist
);
307 * Initialize the dynamic linker. The argument is the address at which
308 * the dynamic linker has been mapped into memory. The primary task of
309 * this function is to create an Obj_Entry for the dynamic linker and
310 * to resolve the PLT relocation for platforms that need it (those that
311 * define __HAVE_FUNCTION_DESCRIPTORS
314 _rtld_init(caddr_t mapbase
, caddr_t relocbase
, const char *execname
)
317 /* Conjure up an Obj_Entry structure for the dynamic linker. */
318 _rtld_objself
.path
= __UNCONST(_rtld_path
);
319 _rtld_objself
.pathlen
= sizeof(_rtld_path
)-1;
320 _rtld_objself
.rtld
= true;
321 _rtld_objself
.mapbase
= mapbase
;
322 _rtld_objself
.relocbase
= relocbase
;
323 _rtld_objself
.dynamic
= (Elf_Dyn
*) &_DYNAMIC
;
324 _rtld_objself
.strtab
= "_rtld_sym_zero";
327 * Set value to -relocbase so that
329 * _rtld_objself.relocbase + _rtld_sym_zero.st_value == 0
331 * This allows unresolved references to weak symbols to be computed
334 _rtld_sym_zero
.st_value
= -(uintptr_t)relocbase
;
336 _rtld_digest_dynamic(_rtld_path
, &_rtld_objself
);
337 assert(!_rtld_objself
.needed
);
338 #if !defined(__hppa__)
339 assert(!_rtld_objself
.pltrel
&& !_rtld_objself
.pltrela
);
341 _rtld_relocate_plt_objects(&_rtld_objself
);
343 #if !defined(__mips__) && !defined(__hppa__)
344 assert(!_rtld_objself
.pltgot
);
346 #if !defined(__arm__) && !defined(__mips__) && !defined(__sh__)
347 /* ARM, MIPS and SH{3,5} have a bogus DT_TEXTREL. */
348 assert(!_rtld_objself
.textrel
);
351 _rtld_add_paths(execname
, &_rtld_default_paths
,
352 RTLD_DEFAULT_LIBRARY_PATH
);
354 #ifdef RTLD_ARCH_SUBDIR
355 _rtld_add_paths(execname
, &_rtld_default_paths
,
356 RTLD_DEFAULT_LIBRARY_PATH
"/" RTLD_ARCH_SUBDIR
);
359 /* Make the object list empty. */
360 _rtld_objlist
= NULL
;
361 _rtld_objtail
= &_rtld_objlist
;
364 _rtld_debug
.r_brk
= _rtld_debug_state
;
365 _rtld_debug
.r_state
= RT_CONSISTENT
;
369 * Cleanup procedure. It will be called (by the atexit() mechanism) just
370 * before the process exits.
377 dbg(("rtld_exit()"));
379 _rtld_exclusive_enter(&mask
);
381 _rtld_call_fini_functions(&mask
, 1);
383 _rtld_exclusive_exit(&mask
);
393 * Main entry point for dynamic linking. The argument is the stack
394 * pointer. The stack is expected to be laid out as described in the
395 * SVR4 ABI specification, Intel 386 Processor Supplement. Specifically,
396 * the stack pointer points to a word containing ARGC. Following that
397 * in the stack is a null-terminated sequence of pointers to argument
398 * strings. Then comes a null-terminated sequence of pointers to
399 * environment strings. Finally, there is a sequence of "auxiliary
402 * This function returns the entry point for the main program, the dynamic
403 * linker's exit procedure in sp[0], and a pointer to the main object in
407 _rtld(Elf_Addr
*sp
, Elf_Addr relocbase
)
409 const AuxInfo
*pAUX_base
, *pAUX_entry
, *pAUX_execfd
, *pAUX_phdr
,
410 *pAUX_phent
, *pAUX_phnum
, *pAUX_euid
, *pAUX_egid
,
411 *pAUX_ruid
, *pAUX_rgid
;
412 const AuxInfo
*pAUX_pagesz
;
416 Elf_Addr
*const osp
= sp
;
418 const char *ld_bind_now
, *ld_preload
, *ld_library_path
;
420 const char *execname
;
422 const char **real___progname
;
423 const Obj_Entry
**real___mainprog_obj
;
424 char ***real_environ
;
427 const char *ld_debug
;
434 * On entry, the dynamic linker itself has not been relocated yet.
435 * Be very careful not to reference any global data until after
436 * _rtld_init has returned. It is OK to reference file-scope statics
437 * and string constants, and to call static and global functions.
439 /* Find the auxiliary vector on the stack. */
440 /* first Elf_Word reserved to address of exit routine */
441 #if defined(RTLD_DEBUG)
443 dbg(("sp = %p, argc = %ld, argv = %p <%s> relocbase %p", sp
,
444 (long)sp
[2], &sp
[3], (char *) sp
[3], (void *)relocbase
));
446 dbg(("got is at %p, dynamic is at %p", _GLOBAL_OFFSET_TABLE_
,
451 sp
+= 2; /* skip over return argument space */
452 argv
= (const char **) &sp
[1];
454 sp
+= 2 + argc
; /* Skip over argc, arguments, and NULL
457 while (*sp
++ != 0) { /* Skip over environment, and NULL terminator */
458 #if defined(RTLD_DEBUG)
459 dbg(("env[%d] = %p %s", i
++, (void *)sp
[-1], (char *)sp
[-1]));
462 auxinfo
= (AuxInfo
*) sp
;
464 pAUX_base
= pAUX_entry
= pAUX_execfd
= NULL
;
465 pAUX_phdr
= pAUX_phent
= pAUX_phnum
= NULL
;
466 pAUX_euid
= pAUX_ruid
= pAUX_egid
= pAUX_rgid
= NULL
;
471 /* Digest the auxiliary vector. */
472 for (auxp
= auxinfo
; auxp
->a_type
!= AT_NULL
; ++auxp
) {
473 switch (auxp
->a_type
) {
506 #ifdef AT_SUN_EXECNAME
507 case AT_SUN_EXECNAME
:
508 execname
= (const char *)(const void *)auxp
->a_v
;
517 /* Initialize and relocate ourselves. */
518 if (pAUX_base
== NULL
) {
519 _rtld_error("Bad pAUX_base");
522 assert(pAUX_pagesz
!= NULL
);
523 _rtld_pagesz
= (int)pAUX_pagesz
->a_v
;
524 _rtld_init((caddr_t
)pAUX_base
->a_v
, (caddr_t
)relocbase
, execname
);
526 __progname
= _rtld_objself
.path
;
529 _rtld_trust
= ((pAUX_euid
? (uid_t
)pAUX_euid
->a_v
: geteuid()) ==
530 (pAUX_ruid
? (uid_t
)pAUX_ruid
->a_v
: getuid())) &&
531 ((pAUX_egid
? (gid_t
)pAUX_egid
->a_v
: getegid()) ==
532 (pAUX_rgid
? (gid_t
)pAUX_rgid
->a_v
: getgid()));
538 ld_library_path
= NULL
;
541 * Inline avoid using normal getenv/unsetenv here as the libc
542 * code is quite a bit more complicated.
544 for (oenvp
= env
; *env
!= NULL
; ++env
) {
545 static const char bind_var
[] = "LD_BIND_NOW=";
546 static const char debug_var
[] = "LD_DEBUG=";
547 static const char path_var
[] = "LD_LIBRARY_PATH=";
548 static const char preload_var
[] = "LD_PRELOAD=";
549 #define LEN(x) (sizeof(x) - 1)
551 if ((*env
)[0] != 'L' || (*env
)[1] != 'D') {
553 * Special case to skip most entries without
554 * the more expensive calls to strncmp.
557 } else if (strncmp(*env
, debug_var
, LEN(debug_var
)) == 0) {
560 ld_debug
= *env
+ LEN(debug_var
);
564 } else if (strncmp(*env
, bind_var
, LEN(bind_var
)) == 0) {
565 ld_bind_now
= *env
+ LEN(bind_var
);
566 } else if (strncmp(*env
, path_var
, LEN(path_var
)) == 0) {
568 ld_library_path
= *env
+ LEN(path_var
);
571 } else if (strncmp(*env
, preload_var
, LEN(preload_var
)) == 0) {
573 ld_preload
= *env
+ LEN(preload_var
);
583 if (ld_bind_now
!= NULL
&& *ld_bind_now
!= '\0')
590 if (ld_debug
!= NULL
&& *ld_debug
!= '\0')
593 _rtld_add_paths(execname
, &_rtld_paths
, ld_library_path
);
597 _rtld_process_hints(execname
, &_rtld_paths
, &_rtld_xforms
,
599 dbg(("dynamic linker is initialized, mapbase=%p, relocbase=%p",
600 _rtld_objself
.mapbase
, _rtld_objself
.relocbase
));
603 * Load the main program, or process its program header if it is
606 if (pAUX_execfd
!= NULL
) { /* Load the main program. */
607 int fd
= pAUX_execfd
->a_v
;
608 const char *obj_name
= argv
[0] ? argv
[0] : "main program";
609 dbg(("loading main program"));
610 _rtld_objmain
= _rtld_map_object(obj_name
, fd
, NULL
);
612 if (_rtld_objmain
== NULL
)
614 } else { /* Main program already loaded. */
615 const Elf_Phdr
*phdr
;
619 dbg(("processing main program's program header"));
620 assert(pAUX_phdr
!= NULL
);
621 phdr
= (const Elf_Phdr
*) pAUX_phdr
->a_v
;
622 assert(pAUX_phnum
!= NULL
);
623 phnum
= pAUX_phnum
->a_v
;
624 assert(pAUX_phent
!= NULL
);
625 assert(pAUX_phent
->a_v
== sizeof(Elf_Phdr
));
626 assert(pAUX_entry
!= NULL
);
627 entry
= (caddr_t
) pAUX_entry
->a_v
;
628 _rtld_objmain
= _rtld_digest_phdr(phdr
, phnum
, entry
);
629 _rtld_objmain
->path
= xstrdup(argv
[0] ? argv
[0] :
631 _rtld_objmain
->pathlen
= strlen(_rtld_objmain
->path
);
634 _rtld_objmain
->mainprog
= true;
637 * Get the actual dynamic linker pathname from the executable if
638 * possible. (It should always be possible.) That ensures that
639 * gdb will find the right dynamic linker even if a non-standard
642 if (_rtld_objmain
->interp
!= NULL
&&
643 strcmp(_rtld_objmain
->interp
, _rtld_objself
.path
) != 0) {
644 _rtld_objself
.path
= xstrdup(_rtld_objmain
->interp
);
645 _rtld_objself
.pathlen
= strlen(_rtld_objself
.path
);
647 dbg(("actual dynamic linker is %s", _rtld_objself
.path
));
649 _rtld_digest_dynamic(execname
, _rtld_objmain
);
651 /* Link the main program into the list of objects. */
652 *_rtld_objtail
= _rtld_objmain
;
653 _rtld_objtail
= &_rtld_objmain
->next
;
657 _rtld_linkmap_add(_rtld_objmain
);
658 _rtld_linkmap_add(&_rtld_objself
);
660 ++_rtld_objmain
->refcount
;
661 _rtld_objmain
->mainref
= 1;
662 _rtld_objlist_push_tail(&_rtld_list_main
, _rtld_objmain
);
666 * Pre-load user-specified objects after the main program
667 * but before any shared object dependencies.
669 dbg(("preloading objects"));
670 if (_rtld_preload(ld_preload
) == -1)
674 dbg(("loading needed objects"));
675 if (_rtld_load_needed_objects(_rtld_objmain
, _RTLD_MAIN
) == -1)
678 dbg(("checking for required versions"));
679 for (obj
= _rtld_objlist
; obj
!= NULL
; obj
= obj
->next
) {
680 if (_rtld_verify_object_versions(obj
) == -1)
684 #if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
685 dbg(("initializing initial Thread Local Storage offsets"));
687 * All initial objects get the TLS space from the static block.
689 for (obj
= _rtld_objlist
; obj
!= NULL
; obj
= obj
->next
)
690 _rtld_tls_offset_allocate(obj
);
693 dbg(("relocating objects"));
694 if (_rtld_relocate_objects(_rtld_objmain
, bind_now
) == -1)
697 dbg(("doing copy relocations"));
698 if (_rtld_do_copy_relocations(_rtld_objmain
) == -1)
701 #if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
702 dbg(("initializing Thread Local Storage for main thread"));
704 * Set up TLS area for the main thread.
705 * This has to be done after all relocations are processed,
706 * since .tdata may contain relocations.
708 _rtld_tls_initial_allocation();
712 * Set the __progname, environ and, __mainprog_obj before
713 * calling anything that might use them.
715 real___progname
= _rtld_objmain_sym("__progname");
716 if (real___progname
) {
717 if (argv
[0] != NULL
) {
718 if ((*real___progname
= strrchr(argv
[0], '/')) == NULL
)
719 (*real___progname
) = argv
[0];
721 (*real___progname
)++;
723 (*real___progname
) = NULL
;
726 real_environ
= _rtld_objmain_sym("environ");
728 *real_environ
= environ
;
730 * Set __mainprog_obj for old binaries.
732 real___mainprog_obj
= _rtld_objmain_sym("__mainprog_obj");
733 if (real___mainprog_obj
)
734 *real___mainprog_obj
= _rtld_objmain
;
736 _rtld_exclusive_enter(&mask
);
738 dbg(("calling _init functions"));
739 _rtld_call_init_functions(&mask
);
741 dbg(("control at program entry point = %p, obj = %p, exit = %p",
742 _rtld_objmain
->entry
, _rtld_objmain
, _rtld_exit
));
744 _rtld_exclusive_exit(&mask
);
747 * Return with the entry point and the exit procedure in at the top
751 _rtld_debug_state(); /* say hello to gdb! */
753 ((void **) osp
)[0] = _rtld_exit
;
754 ((void **) osp
)[1] = _rtld_objmain
;
755 return (Elf_Addr
) _rtld_objmain
->entry
;
761 const char *msg
= dlerror();
769 _rtld_dlcheck(void *handle
)
773 for (obj
= _rtld_objlist
; obj
!= NULL
; obj
= obj
->next
)
774 if (obj
== (Obj_Entry
*) handle
)
777 if (obj
== NULL
|| obj
->dl_refcount
== 0) {
778 _rtld_error("Invalid shared object handle %p", handle
);
785 _rtld_initlist_visit(Objlist
* list
, Obj_Entry
*obj
, int rev
)
789 /* dbg(("_rtld_initlist_visit(%s)", obj->path)); */
795 for (elm
= obj
->needed
; elm
!= NULL
; elm
= elm
->next
) {
796 if (elm
->obj
!= NULL
) {
797 _rtld_initlist_visit(list
, elm
->obj
, rev
);
802 _rtld_objlist_push_head(list
, obj
);
804 _rtld_objlist_push_tail(list
, obj
);
809 _rtld_initlist_tsort(Objlist
* list
, int rev
)
811 dbg(("_rtld_initlist_tsort"));
815 for (obj
= _rtld_objlist
->next
; obj
; obj
= obj
->next
) {
819 for (obj
= _rtld_objlist
->next
; obj
; obj
= obj
->next
) {
820 _rtld_initlist_visit(list
, obj
, rev
);
825 _rtld_init_dag(Obj_Entry
*root
)
828 _rtld_init_dag1(root
, root
);
832 _rtld_init_dag1(Obj_Entry
*root
, Obj_Entry
*obj
)
834 const Needed_Entry
*needed
;
837 if (_rtld_objlist_find(&obj
->dldags
, root
))
839 dbg(("add %p (%s) to %p (%s) DAG", obj
, obj
->path
, root
,
841 _rtld_objlist_push_tail(&obj
->dldags
, root
);
842 _rtld_objlist_push_tail(&root
->dagmembers
, obj
);
844 for (needed
= obj
->needed
; needed
!= NULL
; needed
= needed
->next
)
845 if (needed
->obj
!= NULL
)
846 _rtld_init_dag1(root
, needed
->obj
);
850 * Note, this is called only for objects loaded by dlopen().
853 _rtld_unload_object(sigset_t
*mask
, Obj_Entry
*root
, bool do_fini_funcs
)
856 _rtld_unref_dag(root
);
857 if (root
->refcount
== 0) { /* We are finished with some objects. */
862 /* Finalize objects that are about to be unmapped. */
864 _rtld_call_fini_functions(mask
, 0);
866 /* Remove the DAG from all objects' DAG lists. */
867 SIMPLEQ_FOREACH(elm
, &root
->dagmembers
, link
)
868 _rtld_objlist_remove(&elm
->obj
->dldags
, root
);
870 /* Remove the DAG from the RTLD_GLOBAL list. */
871 if (root
->globalref
) {
873 _rtld_objlist_remove(&_rtld_list_global
, root
);
876 /* Unmap all objects that are no longer referenced. */
877 linkp
= &_rtld_objlist
->next
;
878 while ((obj
= *linkp
) != NULL
) {
879 if (obj
->refcount
== 0) {
880 dbg(("unloading \"%s\"", obj
->path
));
881 if (obj
->ehdr
!= MAP_FAILED
)
882 munmap(obj
->ehdr
, _rtld_pagesz
);
883 munmap(obj
->mapbase
, obj
->mapsize
);
884 _rtld_objlist_remove(&_rtld_list_global
, obj
);
885 _rtld_linkmap_delete(obj
);
892 _rtld_objtail
= linkp
;
897 _rtld_ref_dag(Obj_Entry
*root
)
899 const Needed_Entry
*needed
;
905 dbg(("incremented reference on \"%s\" (%d)", root
->path
,
907 for (needed
= root
->needed
; needed
!= NULL
;
908 needed
= needed
->next
) {
909 if (needed
->obj
!= NULL
)
910 _rtld_ref_dag(needed
->obj
);
915 _rtld_unref_dag(Obj_Entry
*root
)
919 assert(root
->refcount
!= 0);
922 dbg(("decremented reference on \"%s\" (%d)", root
->path
,
925 if (root
->refcount
== 0) {
926 const Needed_Entry
*needed
;
928 for (needed
= root
->needed
; needed
!= NULL
;
929 needed
= needed
->next
) {
930 if (needed
->obj
!= NULL
)
931 _rtld_unref_dag(needed
->obj
);
936 __strong_alias(__dlclose
,dlclose
)
938 dlclose(void *handle
)
943 dbg(("dlclose of %p", handle
));
945 _rtld_exclusive_enter(&mask
);
947 root
= _rtld_dlcheck(handle
);
950 _rtld_exclusive_exit(&mask
);
954 _rtld_debug
.r_state
= RT_DELETE
;
958 _rtld_unload_object(&mask
, root
, true);
960 _rtld_debug
.r_state
= RT_CONSISTENT
;
963 _rtld_exclusive_exit(&mask
);
968 __strong_alias(__dlerror
,dlerror
)
972 char *msg
= error_message
;
974 error_message
= NULL
;
978 __strong_alias(__dlopen
,dlopen
)
980 dlopen(const char *name
, int mode
)
982 Obj_Entry
**old_obj_tail
= _rtld_objtail
;
983 Obj_Entry
*obj
= NULL
;
984 int flags
= _RTLD_DLOPEN
;
990 dbg(("dlopen of %s %d", name
, mode
));
992 _rtld_exclusive_enter(&mask
);
994 flags
|= (mode
& RTLD_GLOBAL
) ? _RTLD_GLOBAL
: 0;
995 flags
|= (mode
& RTLD_NOLOAD
) ? _RTLD_NOLOAD
: 0;
997 nodelete
= (mode
& RTLD_NODELETE
) ? true : false;
998 now
= ((mode
& RTLD_MODEMASK
) == RTLD_NOW
) ? true : false;
1000 _rtld_debug
.r_state
= RT_ADD
;
1001 _rtld_debug_state();
1004 obj
= _rtld_objmain
;
1007 obj
= _rtld_load_library(name
, _rtld_objmain
, flags
);
1012 if (*old_obj_tail
!= NULL
) { /* We loaded something new. */
1013 assert(*old_obj_tail
== obj
);
1015 result
= _rtld_load_needed_objects(obj
, flags
);
1017 Objlist_Entry
*entry
;
1018 _rtld_init_dag(obj
);
1019 SIMPLEQ_FOREACH(entry
, &obj
->dagmembers
, link
) {
1020 result
= _rtld_verify_object_versions(entry
->obj
);
1025 if (result
== -1 || _rtld_relocate_objects(obj
,
1026 (now
|| obj
->z_now
)) == -1) {
1027 _rtld_unload_object(&mask
, obj
, false);
1031 _rtld_call_init_functions(&mask
);
1035 if ((nodelete
|| obj
->z_nodelete
) && !obj
->ref_nodel
) {
1036 dbg(("dlopen obj %s nodelete", obj
->path
));
1038 obj
->z_nodelete
= obj
->ref_nodel
= true;
1042 _rtld_debug
.r_state
= RT_CONSISTENT
;
1043 _rtld_debug_state();
1045 _rtld_exclusive_exit(&mask
);
1051 * Find a symbol in the main program.
1054 _rtld_objmain_sym(const char *name
)
1058 const Obj_Entry
*obj
;
1061 hash
= _rtld_elf_hash(name
);
1062 obj
= _rtld_objmain
;
1063 _rtld_donelist_init(&donelist
);
1065 def
= _rtld_symlook_list(name
, hash
, &_rtld_list_main
, &obj
, 0,
1069 return obj
->relocbase
+ def
->st_value
;
1075 hackish_return_address(void)
1077 return __builtin_return_address(1);
1081 #ifdef __HAVE_FUNCTION_DESCRIPTORS
1082 #define lookup_mutex_enter() _rtld_exclusive_enter(&mask)
1083 #define lookup_mutex_exit() _rtld_exclusive_exit(&mask)
1085 #define lookup_mutex_enter() _rtld_shared_enter()
1086 #define lookup_mutex_exit() _rtld_shared_exit()
1090 do_dlsym(void *handle
, const char *name
, const Ver_Entry
*ventry
, void *retaddr
)
1092 const Obj_Entry
*obj
;
1095 const Obj_Entry
*defobj
;
1097 const u_int flags
= SYMLOOK_DLSYM
| SYMLOOK_IN_PLT
;
1098 #ifdef __HAVE_FUNCTION_DESCRIPTORS
1102 lookup_mutex_enter();
1104 hash
= _rtld_elf_hash(name
);
1108 switch ((intptr_t)handle
) {
1109 case (intptr_t)NULL
:
1110 case (intptr_t)RTLD_NEXT
:
1111 case (intptr_t)RTLD_DEFAULT
:
1112 case (intptr_t)RTLD_SELF
:
1113 if ((obj
= _rtld_obj_from_addr(retaddr
)) == NULL
) {
1114 _rtld_error("Cannot determine caller's shared object");
1115 lookup_mutex_exit();
1119 switch ((intptr_t)handle
) {
1120 case (intptr_t)NULL
: /* Just the caller's shared object. */
1121 def
= _rtld_symlook_obj(name
, hash
, obj
, flags
, ventry
);
1125 case (intptr_t)RTLD_NEXT
: /* Objects after callers */
1129 case (intptr_t)RTLD_SELF
: /* Caller included */
1130 for (; obj
; obj
= obj
->next
) {
1131 if ((def
= _rtld_symlook_obj(name
, hash
, obj
,
1132 flags
, ventry
)) != NULL
) {
1139 case (intptr_t)RTLD_DEFAULT
:
1140 def
= _rtld_symlook_default(name
, hash
, obj
, &defobj
,
1150 if ((obj
= _rtld_dlcheck(handle
)) == NULL
) {
1151 lookup_mutex_exit();
1155 _rtld_donelist_init(&donelist
);
1157 if (obj
->mainprog
) {
1158 /* Search main program and all libraries loaded by it */
1159 def
= _rtld_symlook_list(name
, hash
, &_rtld_list_main
,
1160 &defobj
, flags
, ventry
, &donelist
);
1165 /* Search the object and all the libraries loaded by it. */
1167 fake
.obj
= __UNCONST(obj
);
1170 _rtld_donelist_init(&depth
);
1171 def
= _rtld_symlook_needed(name
, hash
, &fake
, &defobj
,
1172 flags
, ventry
, &donelist
, &depth
);
1180 #ifdef __HAVE_FUNCTION_DESCRIPTORS
1181 if (ELF_ST_TYPE(def
->st_info
) == STT_FUNC
) {
1182 p
= (void *)_rtld_function_descriptor_alloc(defobj
,
1184 lookup_mutex_exit();
1187 #endif /* __HAVE_FUNCTION_DESCRIPTORS */
1188 p
= defobj
->relocbase
+ def
->st_value
;
1189 lookup_mutex_exit();
1193 _rtld_error("Undefined symbol \"%s\"", name
);
1194 lookup_mutex_exit();
1198 __strong_alias(__dlsym
,dlsym
)
1200 dlsym(void *handle
, const char *name
)
1204 dbg(("dlsym of %s in %p", name
, handle
));
1207 retaddr
= hackish_return_address();
1209 retaddr
= __builtin_return_address(0);
1211 return do_dlsym(handle
, name
, NULL
, retaddr
);
1214 __strong_alias(__dlvsym
,dlvsym
)
1216 dlvsym(void *handle
, const char *name
, const char *version
)
1218 Ver_Entry
*ventry
= NULL
;
1219 Ver_Entry ver_entry
;
1222 dbg(("dlvsym of %s@%s in %p", name
, version
? version
: NULL
, handle
));
1224 if (version
!= NULL
) {
1225 ver_entry
.name
= version
;
1226 ver_entry
.file
= NULL
;
1227 ver_entry
.hash
= _rtld_elf_hash(version
);
1228 ver_entry
.flags
= 0;
1229 ventry
= &ver_entry
;
1232 retaddr
= hackish_return_address();
1234 retaddr
= __builtin_return_address(0);
1236 return do_dlsym(handle
, name
, ventry
, retaddr
);
1239 __strong_alias(__dladdr
,dladdr
)
1241 dladdr(const void *addr
, Dl_info
*info
)
1243 const Obj_Entry
*obj
;
1244 const Elf_Sym
*def
, *best_def
;
1246 unsigned long symoffset
;
1247 #ifdef __HAVE_FUNCTION_DESCRIPTORS
1251 dbg(("dladdr of %p", addr
));
1253 lookup_mutex_enter();
1255 #ifdef __HAVE_FUNCTION_DESCRIPTORS
1256 addr
= _rtld_function_descriptor_function(addr
);
1257 #endif /* __HAVE_FUNCTION_DESCRIPTORS */
1259 obj
= _rtld_obj_from_addr(addr
);
1261 _rtld_error("No shared object contains address");
1262 lookup_mutex_enter();
1265 info
->dli_fname
= obj
->path
;
1266 info
->dli_fbase
= obj
->mapbase
;
1267 info
->dli_saddr
= (void *)0;
1268 info
->dli_sname
= NULL
;
1271 * Walk the symbol list looking for the symbol whose address is
1272 * closest to the address sent in.
1275 for (symoffset
= 0; symoffset
< obj
->nchains
; symoffset
++) {
1276 def
= obj
->symtab
+ symoffset
;
1279 * For skip the symbol if st_shndx is either SHN_UNDEF or
1282 if (def
->st_shndx
== SHN_UNDEF
|| def
->st_shndx
== SHN_COMMON
)
1286 * If the symbol is greater than the specified address, or if it
1287 * is further away from addr than the current nearest symbol,
1290 symbol_addr
= obj
->relocbase
+ def
->st_value
;
1291 if (symbol_addr
> addr
|| symbol_addr
< info
->dli_saddr
)
1294 /* Update our idea of the nearest symbol. */
1295 info
->dli_sname
= obj
->strtab
+ def
->st_name
;
1296 info
->dli_saddr
= symbol_addr
;
1301 if (info
->dli_saddr
== addr
)
1305 #ifdef __HAVE_FUNCTION_DESCRIPTORS
1306 if (best_def
!= NULL
&& ELF_ST_TYPE(best_def
->st_info
) == STT_FUNC
)
1307 info
->dli_saddr
= (void *)_rtld_function_descriptor_alloc(obj
,
1311 #endif /* __HAVE_FUNCTION_DESCRIPTORS */
1313 lookup_mutex_exit();
1317 __strong_alias(__dlinfo
,dlinfo
)
1319 dlinfo(void *handle
, int req
, void *v
)
1321 const Obj_Entry
*obj
;
1324 dbg(("dlinfo for %p %d", handle
, req
));
1326 _rtld_shared_enter();
1328 if (handle
== RTLD_SELF
) {
1330 retaddr
= hackish_return_address();
1332 retaddr
= __builtin_return_address(0);
1334 if ((obj
= _rtld_obj_from_addr(retaddr
)) == NULL
) {
1335 _rtld_error("Cannot determine caller's shared object");
1336 _rtld_shared_exit();
1340 if ((obj
= _rtld_dlcheck(handle
)) == NULL
) {
1341 _rtld_shared_exit();
1347 case RTLD_DI_LINKMAP
:
1349 const struct link_map
**map
= v
;
1351 *map
= &obj
->linkmap
;
1356 _rtld_error("Invalid request");
1357 _rtld_shared_exit();
1361 _rtld_shared_exit();
1365 __strong_alias(__dl_iterate_phdr
,dl_iterate_phdr
);
1367 dl_iterate_phdr(int (*callback
)(struct dl_phdr_info
*, size_t, void *), void *param
)
1369 struct dl_phdr_info phdr_info
;
1370 const Obj_Entry
*obj
;
1373 dbg(("dl_iterate_phdr"));
1375 _rtld_shared_enter();
1377 for (obj
= _rtld_objlist
; obj
!= NULL
; obj
= obj
->next
) {
1378 phdr_info
.dlpi_addr
= (Elf_Addr
)obj
->relocbase
;
1379 /* XXX: wrong but not fixing it yet */
1380 phdr_info
.dlpi_name
= SIMPLEQ_FIRST(&obj
->names
) ?
1381 SIMPLEQ_FIRST(&obj
->names
)->name
: obj
->path
;
1382 phdr_info
.dlpi_phdr
= obj
->phdr
;
1383 phdr_info
.dlpi_phnum
= obj
->phsize
/ sizeof(obj
->phdr
[0]);
1384 #if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
1385 phdr_info
.dlpi_tls_modid
= obj
->tlsindex
;
1386 phdr_info
.dlpi_tls_data
= obj
->tlsinit
;
1388 phdr_info
.dlpi_tls_modid
= 0;
1389 phdr_info
.dlpi_tls_data
= 0;
1391 phdr_info
.dlpi_adds
= _rtld_objloads
;
1392 phdr_info
.dlpi_subs
= _rtld_objloads
- _rtld_objcount
;
1394 /* XXXlocking: exit point */
1395 error
= callback(&phdr_info
, sizeof(phdr_info
), param
);
1400 _rtld_shared_exit();
1405 * Error reporting function. Use it like printf. If formats the message
1406 * into a buffer, and sets things up so that the next call to dlerror()
1407 * will return the message.
1410 _rtld_error(const char *fmt
,...)
1412 static char buf
[512];
1416 xvsnprintf(buf
, sizeof buf
, fmt
, ap
);
1417 error_message
= buf
;
1422 _rtld_debug_state(void)
1425 /* Prevent optimizer from removing calls to this function */
1430 _rtld_linkmap_add(Obj_Entry
*obj
)
1432 struct link_map
*l
= &obj
->linkmap
;
1433 struct link_map
*prev
;
1435 obj
->linkmap
.l_name
= obj
->path
;
1436 obj
->linkmap
.l_addr
= obj
->relocbase
;
1437 obj
->linkmap
.l_ld
= obj
->dynamic
;
1439 /* XXX This field is not standard and will be removed eventually. */
1440 obj
->linkmap
.l_offs
= obj
->relocbase
;
1443 if (_rtld_debug
.r_map
== NULL
) {
1444 _rtld_debug
.r_map
= l
;
1449 * Scan to the end of the list, but not past the entry for the
1450 * dynamic linker, which we want to keep at the very end.
1452 for (prev
= _rtld_debug
.r_map
;
1453 prev
->l_next
!= NULL
&& prev
->l_next
!= &_rtld_objself
.linkmap
;
1454 prev
= prev
->l_next
);
1457 l
->l_next
= prev
->l_next
;
1458 if (l
->l_next
!= NULL
)
1459 l
->l_next
->l_prev
= l
;
1464 _rtld_linkmap_delete(Obj_Entry
*obj
)
1466 struct link_map
*l
= &obj
->linkmap
;
1468 if (l
->l_prev
== NULL
) {
1469 if ((_rtld_debug
.r_map
= l
->l_next
) != NULL
)
1470 l
->l_next
->l_prev
= NULL
;
1473 if ((l
->l_prev
->l_next
= l
->l_next
) != NULL
)
1474 l
->l_next
->l_prev
= l
->l_prev
;
1478 _rtld_obj_from_addr(const void *addr
)
1482 for (obj
= _rtld_objlist
; obj
!= NULL
; obj
= obj
->next
) {
1483 if (addr
< (void *) obj
->mapbase
)
1485 if (addr
< (void *) (obj
->mapbase
+ obj
->mapsize
))
1492 _rtld_objlist_clear(Objlist
*list
)
1494 while (!SIMPLEQ_EMPTY(list
)) {
1495 Objlist_Entry
* elm
= SIMPLEQ_FIRST(list
);
1496 SIMPLEQ_REMOVE_HEAD(list
, link
);
1502 _rtld_objlist_remove(Objlist
*list
, Obj_Entry
*obj
)
1506 if ((elm
= _rtld_objlist_find(list
, obj
)) != NULL
) {
1507 SIMPLEQ_REMOVE(list
, elm
, Struct_Objlist_Entry
, link
);
1512 #if defined(__minix)
1513 void _rtld_shared_enter(void) {}
1514 void _rtld_shared_exit(void) {}
1515 void _rtld_exclusive_enter(sigset_t
*mask
) {}
1516 void _rtld_exclusive_exit(sigset_t
*mask
) {}
1518 #define RTLD_EXCLUSIVE_MASK 0x80000000U
1519 static volatile unsigned int _rtld_mutex
;
1520 static volatile unsigned int _rtld_waiter_exclusive
;
1521 static volatile unsigned int _rtld_waiter_shared
;
1524 _rtld_shared_enter(void)
1527 lwpid_t waiter
, self
= 0;
1534 * First check if we are currently not exclusively locked.
1536 if ((cur
& RTLD_EXCLUSIVE_MASK
) == 0) {
1537 /* Yes, so increment use counter */
1538 if (atomic_cas_uint(&_rtld_mutex
, cur
, cur
+ 1) != cur
)
1543 * Someone has an exclusive lock. Puts us on the waiter list.
1547 if (cur
== (self
| RTLD_EXCLUSIVE_MASK
)) {
1548 if (_rtld_mutex_may_recurse
)
1550 _rtld_error("dead lock detected");
1553 waiter
= atomic_swap_uint(&_rtld_waiter_shared
, self
);
1555 * Check for race against _rtld_exclusive_exit before sleeping.
1557 if ((_rtld_mutex
& RTLD_EXCLUSIVE_MASK
) ||
1558 _rtld_waiter_exclusive
)
1559 _lwp_park(NULL
, 0, __UNVOLATILE(&_rtld_mutex
), NULL
);
1560 /* Try to remove us from the waiter list. */
1561 atomic_cas_uint(&_rtld_waiter_shared
, self
, 0);
1563 _lwp_unpark(waiter
, __UNVOLATILE(&_rtld_mutex
));
1568 _rtld_shared_exit(void)
1573 * Shared lock taken after an exclusive lock.
1574 * Just assume this is a partial recursion.
1576 if (_rtld_mutex
& RTLD_EXCLUSIVE_MASK
)
1580 * Wakeup LWPs waiting for an exclusive lock if this is the last
1581 * LWP on the shared lock.
1583 if (atomic_dec_uint_nv(&_rtld_mutex
))
1585 if ((waiter
= _rtld_waiter_exclusive
) != 0)
1586 _lwp_unpark(waiter
, __UNVOLATILE(&_rtld_mutex
));
1592 _rtld_exclusive_enter(sigset_t
*mask
)
1594 lwpid_t waiter
, self
= _lwp_self();
1595 unsigned int locked_value
= (unsigned int)self
| RTLD_EXCLUSIVE_MASK
;
1599 sigfillset(&blockmask
);
1600 sigdelset(&blockmask
, SIGTRAP
); /* Allow the debugger */
1601 sigprocmask(SIG_BLOCK
, &blockmask
, mask
);
1606 if (atomic_cas_uint(&_rtld_mutex
, 0, locked_value
) == 0)
1608 waiter
= atomic_swap_uint(&_rtld_waiter_exclusive
, self
);
1610 if (cur
== locked_value
) {
1611 _rtld_error("dead lock detected");
1615 _lwp_park(NULL
, 0, __UNVOLATILE(&_rtld_mutex
), NULL
);
1616 atomic_cas_uint(&_rtld_waiter_exclusive
, self
, 0);
1618 _lwp_unpark(waiter
, __UNVOLATILE(&_rtld_mutex
));
1623 _rtld_exclusive_exit(sigset_t
*mask
)
1628 if ((waiter
= _rtld_waiter_exclusive
) != 0)
1629 _lwp_unpark(waiter
, __UNVOLATILE(&_rtld_mutex
));
1631 if ((waiter
= _rtld_waiter_shared
) != 0)
1632 _lwp_unpark(waiter
, __UNVOLATILE(&_rtld_mutex
));
1635 sigprocmask(SIG_SETMASK
, mask
, NULL
);
1637 #endif /* !defined(__minix) */