1 /* $NetBSD: rtld.c,v 1.177 2015/04/06 09:34:15 yamt 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.177 2015/04/06 09:34:15 yamt Exp $");
46 #include <sys/param.h>
47 #include <sys/atomic.h>
71 * Function declarations.
73 static void _rtld_init(caddr_t
, caddr_t
, const char *);
74 static void _rtld_exit(void);
76 Elf_Addr
_rtld(Elf_Addr
*, Elf_Addr
);
82 static char *error_message
; /* Message for dlopen(), or NULL */
84 struct r_debug _rtld_debug
; /* for GDB; */
85 bool _rtld_trust
; /* False for setuid and setgid programs */
86 Obj_Entry
*_rtld_objlist
; /* Head of linked list of shared objects */
87 Obj_Entry
**_rtld_objtail
; /* Link field of last object in list */
88 Obj_Entry
*_rtld_objmain
; /* The main program shared object */
89 Obj_Entry _rtld_objself
; /* The dynamic linker shared object */
90 u_int _rtld_objcount
; /* Number of objects in _rtld_objlist */
91 u_int _rtld_objloads
; /* Number of objects loaded in _rtld_objlist */
92 u_int _rtld_objgen
; /* Generation count for _rtld_objlist */
93 const char _rtld_path
[] = _PATH_RTLD
;
95 /* Initialize a fake symbol for resolving undefined weak references. */
96 Elf_Sym _rtld_sym_zero
= {
97 .st_info
= ELF_ST_INFO(STB_GLOBAL
, STT_NOTYPE
),
100 size_t _rtld_pagesz
; /* Page size, as provided by kernel */
102 Search_Path
*_rtld_default_paths
;
103 Search_Path
*_rtld_paths
;
105 Library_Xform
*_rtld_xforms
;
106 static void *auxinfo
;
109 * Global declarations normally provided by crt0.
114 #if !defined(__minix)
115 static volatile bool _rtld_mutex_may_recurse
;
116 #endif /* !defined(__minix) */
118 #if defined(RTLD_DEBUG)
120 extern Elf_Addr _GLOBAL_OFFSET_TABLE_
[];
121 #else /* 32-bit SuperH */
122 register Elf_Addr
*_GLOBAL_OFFSET_TABLE_
asm("r12");
124 #endif /* RTLD_DEBUG */
125 extern Elf_Dyn _DYNAMIC
;
127 static void _rtld_call_fini_functions(sigset_t
*, int);
128 static void _rtld_call_init_functions(sigset_t
*);
129 static void _rtld_initlist_visit(Objlist
*, Obj_Entry
*, int);
130 static void _rtld_initlist_tsort(Objlist
*, int);
131 static Obj_Entry
*_rtld_dlcheck(void *);
132 static void _rtld_init_dag(Obj_Entry
*);
133 static void _rtld_init_dag1(Obj_Entry
*, Obj_Entry
*);
134 static void _rtld_objlist_remove(Objlist
*, Obj_Entry
*);
135 static void _rtld_objlist_clear(Objlist
*);
136 static void _rtld_unload_object(sigset_t
*, Obj_Entry
*, bool);
137 static void _rtld_unref_dag(Obj_Entry
*);
138 static Obj_Entry
*_rtld_obj_from_addr(const void *);
141 _rtld_call_initfini_function(const Obj_Entry
*obj
, Elf_Addr func
, sigset_t
*mask
)
143 _rtld_exclusive_exit(mask
);
144 _rtld_call_function_void(obj
, func
);
145 _rtld_exclusive_enter(mask
);
149 _rtld_call_fini_function(Obj_Entry
*obj
, sigset_t
*mask
, u_int cur_objgen
)
151 if (obj
->fini_arraysz
== 0 && (obj
->fini
== 0 || obj
->fini_called
))
154 if (obj
->fini
!= 0 && !obj
->fini_called
) {
155 dbg (("calling fini function %s at %p%s", obj
->path
,
157 obj
->z_initfirst
? " (DF_1_INITFIRST)" : ""));
158 obj
->fini_called
= 1;
159 _rtld_call_initfini_function(obj
, obj
->fini
, mask
);
161 #ifdef HAVE_INITFINI_ARRAY
163 * Now process the fini_array if it exists. Simply go from
164 * start to end. We need to make restartable so just advance
165 * the array pointer and decrement the size each time through
168 while (obj
->fini_arraysz
> 0 && _rtld_objgen
== cur_objgen
) {
169 Elf_Addr fini
= *obj
->fini_array
++;
171 dbg (("calling fini array function %s at %p%s", obj
->path
,
173 obj
->z_initfirst
? " (DF_1_INITFIRST)" : ""));
174 _rtld_call_initfini_function(obj
, fini
, mask
);
176 #endif /* HAVE_INITFINI_ARRAY */
180 _rtld_call_fini_functions(sigset_t
*mask
, int force
)
186 dbg(("_rtld_call_fini_functions(%d)", force
));
189 cur_objgen
= ++_rtld_objgen
;
190 SIMPLEQ_INIT(&finilist
);
191 _rtld_initlist_tsort(&finilist
, 1);
193 /* First pass: objects _not_ marked with DF_1_INITFIRST. */
194 SIMPLEQ_FOREACH(elm
, &finilist
, link
) {
195 Obj_Entry
* const obj
= elm
->obj
;
196 if (!obj
->z_initfirst
) {
197 if (obj
->refcount
> 0 && !force
) {
201 * XXX This can race against a concurrent dlclose().
202 * XXX In that case, the object could be unmapped before
203 * XXX the fini() call or the fini_array has completed.
205 _rtld_call_fini_function(obj
, mask
, cur_objgen
);
206 if (_rtld_objgen
!= cur_objgen
) {
207 dbg(("restarting fini iteration"));
208 _rtld_objlist_clear(&finilist
);
214 /* Second pass: objects marked with DF_1_INITFIRST. */
215 SIMPLEQ_FOREACH(elm
, &finilist
, link
) {
216 Obj_Entry
* const obj
= elm
->obj
;
217 if (obj
->refcount
> 0 && !force
) {
220 /* XXX See above for the race condition here */
221 _rtld_call_fini_function(obj
, mask
, cur_objgen
);
222 if (_rtld_objgen
!= cur_objgen
) {
223 dbg(("restarting fini iteration"));
224 _rtld_objlist_clear(&finilist
);
229 _rtld_objlist_clear(&finilist
);
233 _rtld_call_init_function(Obj_Entry
*obj
, sigset_t
*mask
, u_int cur_objgen
)
235 if (obj
->init_arraysz
== 0 && (obj
->init_called
|| obj
->init
== 0))
238 if (!obj
->init_called
&& obj
->init
!= 0) {
239 dbg (("calling init function %s at %p%s",
240 obj
->path
, (void *)obj
->init
,
241 obj
->z_initfirst
? " (DF_1_INITFIRST)" : ""));
242 obj
->init_called
= 1;
243 _rtld_call_initfini_function(obj
, obj
->init
, mask
);
246 #ifdef HAVE_INITFINI_ARRAY
248 * Now process the init_array if it exists. Simply go from
249 * start to end. We need to make restartable so just advance
250 * the array pointer and decrement the size each time through
253 while (obj
->init_arraysz
> 0 && _rtld_objgen
== cur_objgen
) {
254 Elf_Addr init
= *obj
->init_array
++;
256 dbg (("calling init_array function %s at %p%s",
257 obj
->path
, (void *)init
,
258 obj
->z_initfirst
? " (DF_1_INITFIRST)" : ""));
259 _rtld_call_initfini_function(obj
, init
, mask
);
261 #endif /* HAVE_INITFINI_ARRAY */
265 _rtld_call_init_functions(sigset_t
*mask
)
271 dbg(("_rtld_call_init_functions()"));
274 cur_objgen
= ++_rtld_objgen
;
275 SIMPLEQ_INIT(&initlist
);
276 _rtld_initlist_tsort(&initlist
, 0);
278 /* First pass: objects marked with DF_1_INITFIRST. */
279 SIMPLEQ_FOREACH(elm
, &initlist
, link
) {
280 Obj_Entry
* const obj
= elm
->obj
;
281 if (obj
->z_initfirst
) {
282 _rtld_call_init_function(obj
, mask
, cur_objgen
);
283 if (_rtld_objgen
!= cur_objgen
) {
284 dbg(("restarting init iteration"));
285 _rtld_objlist_clear(&initlist
);
291 /* Second pass: all other objects. */
292 SIMPLEQ_FOREACH(elm
, &initlist
, link
) {
293 _rtld_call_init_function(elm
->obj
, mask
, cur_objgen
);
294 if (_rtld_objgen
!= cur_objgen
) {
295 dbg(("restarting init iteration"));
296 _rtld_objlist_clear(&initlist
);
301 _rtld_objlist_clear(&initlist
);
305 * Initialize the dynamic linker. The argument is the address at which
306 * the dynamic linker has been mapped into memory. The primary task of
307 * this function is to create an Obj_Entry for the dynamic linker and
308 * to resolve the PLT relocation for platforms that need it (those that
309 * define __HAVE_FUNCTION_DESCRIPTORS
312 _rtld_init(caddr_t mapbase
, caddr_t relocbase
, const char *execname
)
315 /* Conjure up an Obj_Entry structure for the dynamic linker. */
316 _rtld_objself
.path
= __UNCONST(_rtld_path
);
317 _rtld_objself
.pathlen
= sizeof(_rtld_path
)-1;
318 _rtld_objself
.rtld
= true;
319 _rtld_objself
.mapbase
= mapbase
;
320 _rtld_objself
.relocbase
= relocbase
;
321 _rtld_objself
.dynamic
= (Elf_Dyn
*) &_DYNAMIC
;
322 _rtld_objself
.strtab
= "_rtld_sym_zero";
325 * Set value to -relocbase so that
327 * _rtld_objself.relocbase + _rtld_sym_zero.st_value == 0
329 * This allows unresolved references to weak symbols to be computed
332 _rtld_sym_zero
.st_value
= -(uintptr_t)relocbase
;
334 _rtld_digest_dynamic(_rtld_path
, &_rtld_objself
);
335 assert(!_rtld_objself
.needed
);
336 #if !defined(__hppa__)
337 assert(!_rtld_objself
.pltrel
&& !_rtld_objself
.pltrela
);
339 _rtld_relocate_plt_objects(&_rtld_objself
);
341 #if !defined(__mips__) && !defined(__hppa__)
342 assert(!_rtld_objself
.pltgot
);
344 #if !defined(__arm__) && !defined(__mips__) && !defined(__sh__)
345 /* ARM, MIPS and SH{3,5} have a bogus DT_TEXTREL. */
346 assert(!_rtld_objself
.textrel
);
349 _rtld_add_paths(execname
, &_rtld_default_paths
,
350 RTLD_DEFAULT_LIBRARY_PATH
);
352 #ifdef RTLD_ARCH_SUBDIR
353 _rtld_add_paths(execname
, &_rtld_default_paths
,
354 RTLD_DEFAULT_LIBRARY_PATH
"/" RTLD_ARCH_SUBDIR
);
357 /* Make the object list empty. */
358 _rtld_objlist
= NULL
;
359 _rtld_objtail
= &_rtld_objlist
;
362 _rtld_debug
.r_brk
= _rtld_debug_state
;
363 _rtld_debug
.r_state
= RT_CONSISTENT
;
367 * Cleanup procedure. It will be called (by the atexit() mechanism) just
368 * before the process exits.
375 dbg(("rtld_exit()"));
377 _rtld_exclusive_enter(&mask
);
379 _rtld_call_fini_functions(&mask
, 1);
381 _rtld_exclusive_exit(&mask
);
391 * Main entry point for dynamic linking. The argument is the stack
392 * pointer. The stack is expected to be laid out as described in the
393 * SVR4 ABI specification, Intel 386 Processor Supplement. Specifically,
394 * the stack pointer points to a word containing ARGC. Following that
395 * in the stack is a null-terminated sequence of pointers to argument
396 * strings. Then comes a null-terminated sequence of pointers to
397 * environment strings. Finally, there is a sequence of "auxiliary
400 * This function returns the entry point for the main program, the dynamic
401 * linker's exit procedure in sp[0], and a pointer to the main object in
405 _rtld(Elf_Addr
*sp
, Elf_Addr relocbase
)
407 const AuxInfo
*pAUX_base
, *pAUX_entry
, *pAUX_execfd
, *pAUX_phdr
,
408 *pAUX_phent
, *pAUX_phnum
, *pAUX_euid
, *pAUX_egid
,
409 *pAUX_ruid
, *pAUX_rgid
;
410 const AuxInfo
*pAUX_pagesz
;
414 Elf_Addr
*const osp
= sp
;
416 const char *ld_bind_now
, *ld_preload
, *ld_library_path
;
418 const char *execname
;
420 const char **real___progname
;
421 const Obj_Entry
**real___mainprog_obj
;
422 char ***real_environ
;
425 const char *ld_debug
;
432 * On entry, the dynamic linker itself has not been relocated yet.
433 * Be very careful not to reference any global data until after
434 * _rtld_init has returned. It is OK to reference file-scope statics
435 * and string constants, and to call static and global functions.
437 /* Find the auxiliary vector on the stack. */
438 /* first Elf_Word reserved to address of exit routine */
439 #if defined(RTLD_DEBUG)
441 dbg(("sp = %p, argc = %ld, argv = %p <%s> relocbase %p", sp
,
442 (long)sp
[2], &sp
[3], (char *) sp
[3], (void *)relocbase
));
444 dbg(("got is at %p, dynamic is at %p", _GLOBAL_OFFSET_TABLE_
,
449 sp
+= 2; /* skip over return argument space */
450 argv
= (const char **) &sp
[1];
452 sp
+= 2 + argc
; /* Skip over argc, arguments, and NULL
455 while (*sp
++ != 0) { /* Skip over environment, and NULL terminator */
456 #if defined(RTLD_DEBUG)
457 dbg(("env[%d] = %p %s", i
++, (void *)sp
[-1], (char *)sp
[-1]));
460 auxinfo
= (AuxInfo
*) sp
;
462 pAUX_base
= pAUX_entry
= pAUX_execfd
= NULL
;
463 pAUX_phdr
= pAUX_phent
= pAUX_phnum
= NULL
;
464 pAUX_euid
= pAUX_ruid
= pAUX_egid
= pAUX_rgid
= NULL
;
469 /* Digest the auxiliary vector. */
470 for (auxp
= auxinfo
; auxp
->a_type
!= AT_NULL
; ++auxp
) {
471 switch (auxp
->a_type
) {
504 #ifdef AT_SUN_EXECNAME
505 case AT_SUN_EXECNAME
:
506 execname
= (const char *)(const void *)auxp
->a_v
;
515 /* Initialize and relocate ourselves. */
516 if (pAUX_base
== NULL
) {
517 _rtld_error("Bad pAUX_base");
520 assert(pAUX_pagesz
!= NULL
);
521 _rtld_pagesz
= (int)pAUX_pagesz
->a_v
;
522 _rtld_init((caddr_t
)pAUX_base
->a_v
, (caddr_t
)relocbase
, execname
);
524 __progname
= _rtld_objself
.path
;
527 _rtld_trust
= ((pAUX_euid
? (uid_t
)pAUX_euid
->a_v
: geteuid()) ==
528 (pAUX_ruid
? (uid_t
)pAUX_ruid
->a_v
: getuid())) &&
529 ((pAUX_egid
? (gid_t
)pAUX_egid
->a_v
: getegid()) ==
530 (pAUX_rgid
? (gid_t
)pAUX_rgid
->a_v
: getgid()));
536 ld_library_path
= NULL
;
539 * Inline avoid using normal getenv/unsetenv here as the libc
540 * code is quite a bit more complicated.
542 for (oenvp
= env
; *env
!= NULL
; ++env
) {
543 static const char bind_var
[] = "LD_BIND_NOW=";
544 static const char debug_var
[] = "LD_DEBUG=";
545 static const char path_var
[] = "LD_LIBRARY_PATH=";
546 static const char preload_var
[] = "LD_PRELOAD=";
547 #define LEN(x) (sizeof(x) - 1)
549 if ((*env
)[0] != 'L' || (*env
)[1] != 'D') {
551 * Special case to skip most entries without
552 * the more expensive calls to strncmp.
555 } else if (strncmp(*env
, debug_var
, LEN(debug_var
)) == 0) {
558 ld_debug
= *env
+ LEN(debug_var
);
562 } else if (strncmp(*env
, bind_var
, LEN(bind_var
)) == 0) {
564 ld_bind_now
= *env
+ LEN(bind_var
);
567 } else if (strncmp(*env
, path_var
, LEN(path_var
)) == 0) {
569 ld_library_path
= *env
+ LEN(path_var
);
572 } else if (strncmp(*env
, preload_var
, LEN(preload_var
)) == 0) {
574 ld_preload
= *env
+ LEN(preload_var
);
584 if (ld_bind_now
!= NULL
&& *ld_bind_now
!= '\0')
591 if (ld_debug
!= NULL
&& *ld_debug
!= '\0')
594 _rtld_add_paths(execname
, &_rtld_paths
, ld_library_path
);
598 _rtld_process_hints(execname
, &_rtld_paths
, &_rtld_xforms
,
600 dbg(("dynamic linker is initialized, mapbase=%p, relocbase=%p",
601 _rtld_objself
.mapbase
, _rtld_objself
.relocbase
));
604 * Load the main program, or process its program header if it is
607 if (pAUX_execfd
!= NULL
) { /* Load the main program. */
608 int fd
= pAUX_execfd
->a_v
;
609 const char *obj_name
= argv
[0] ? argv
[0] : "main program";
610 dbg(("loading main program"));
611 _rtld_objmain
= _rtld_map_object(obj_name
, fd
, NULL
);
613 if (_rtld_objmain
== NULL
)
615 } else { /* Main program already loaded. */
616 const Elf_Phdr
*phdr
;
620 dbg(("processing main program's program header"));
621 assert(pAUX_phdr
!= NULL
);
622 phdr
= (const Elf_Phdr
*) pAUX_phdr
->a_v
;
623 assert(pAUX_phnum
!= NULL
);
624 phnum
= pAUX_phnum
->a_v
;
625 assert(pAUX_phent
!= NULL
);
626 assert(pAUX_phent
->a_v
== sizeof(Elf_Phdr
));
627 assert(pAUX_entry
!= NULL
);
628 entry
= (caddr_t
) pAUX_entry
->a_v
;
629 _rtld_objmain
= _rtld_digest_phdr(phdr
, phnum
, entry
);
630 _rtld_objmain
->path
= xstrdup(argv
[0] ? argv
[0] :
632 _rtld_objmain
->pathlen
= strlen(_rtld_objmain
->path
);
635 _rtld_objmain
->mainprog
= true;
638 * Get the actual dynamic linker pathname from the executable if
639 * possible. (It should always be possible.) That ensures that
640 * gdb will find the right dynamic linker even if a non-standard
643 if (_rtld_objmain
->interp
!= NULL
&&
644 strcmp(_rtld_objmain
->interp
, _rtld_objself
.path
) != 0) {
645 _rtld_objself
.path
= xstrdup(_rtld_objmain
->interp
);
646 _rtld_objself
.pathlen
= strlen(_rtld_objself
.path
);
648 dbg(("actual dynamic linker is %s", _rtld_objself
.path
));
650 _rtld_digest_dynamic(execname
, _rtld_objmain
);
652 /* Link the main program into the list of objects. */
653 *_rtld_objtail
= _rtld_objmain
;
654 _rtld_objtail
= &_rtld_objmain
->next
;
658 _rtld_linkmap_add(_rtld_objmain
);
659 _rtld_linkmap_add(&_rtld_objself
);
661 ++_rtld_objmain
->refcount
;
662 _rtld_objmain
->mainref
= 1;
663 _rtld_objlist_push_tail(&_rtld_list_main
, _rtld_objmain
);
667 * Pre-load user-specified objects after the main program
668 * but before any shared object dependencies.
670 dbg(("preloading objects"));
671 if (_rtld_preload(ld_preload
) == -1)
675 dbg(("loading needed objects"));
676 if (_rtld_load_needed_objects(_rtld_objmain
, _RTLD_MAIN
) == -1)
679 dbg(("checking for required versions"));
680 for (obj
= _rtld_objlist
; obj
!= NULL
; obj
= obj
->next
) {
681 if (_rtld_verify_object_versions(obj
) == -1)
685 #if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
686 dbg(("initializing initial Thread Local Storage offsets"));
688 * All initial objects get the TLS space from the static block.
690 for (obj
= _rtld_objlist
; obj
!= NULL
; obj
= obj
->next
)
691 _rtld_tls_offset_allocate(obj
);
694 dbg(("relocating objects"));
695 if (_rtld_relocate_objects(_rtld_objmain
, bind_now
) == -1)
698 dbg(("doing copy relocations"));
699 if (_rtld_do_copy_relocations(_rtld_objmain
) == -1)
702 #if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
703 dbg(("initializing Thread Local Storage for main thread"));
705 * Set up TLS area for the main thread.
706 * This has to be done after all relocations are processed,
707 * since .tdata may contain relocations.
709 _rtld_tls_initial_allocation();
713 * Set the __progname, environ and, __mainprog_obj before
714 * calling anything that might use them.
716 real___progname
= _rtld_objmain_sym("__progname");
717 if (real___progname
) {
718 if (argv
[0] != NULL
) {
719 if ((*real___progname
= strrchr(argv
[0], '/')) == NULL
)
720 (*real___progname
) = argv
[0];
722 (*real___progname
)++;
724 (*real___progname
) = NULL
;
727 real_environ
= _rtld_objmain_sym("environ");
729 *real_environ
= environ
;
731 * Set __mainprog_obj for old binaries.
733 real___mainprog_obj
= _rtld_objmain_sym("__mainprog_obj");
734 if (real___mainprog_obj
)
735 *real___mainprog_obj
= _rtld_objmain
;
737 _rtld_exclusive_enter(&mask
);
739 dbg(("calling _init functions"));
740 _rtld_call_init_functions(&mask
);
742 dbg(("control at program entry point = %p, obj = %p, exit = %p",
743 _rtld_objmain
->entry
, _rtld_objmain
, _rtld_exit
));
745 _rtld_exclusive_exit(&mask
);
748 * Return with the entry point and the exit procedure in at the top
752 _rtld_debug_state(); /* say hello to gdb! */
754 ((void **) osp
)[0] = _rtld_exit
;
755 ((void **) osp
)[1] = _rtld_objmain
;
756 return (Elf_Addr
) _rtld_objmain
->entry
;
762 const char *msg
= dlerror();
770 _rtld_dlcheck(void *handle
)
774 for (obj
= _rtld_objlist
; obj
!= NULL
; obj
= obj
->next
)
775 if (obj
== (Obj_Entry
*) handle
)
778 if (obj
== NULL
|| obj
->dl_refcount
== 0) {
779 _rtld_error("Invalid shared object handle %p", handle
);
786 _rtld_initlist_visit(Objlist
* list
, Obj_Entry
*obj
, int rev
)
790 /* dbg(("_rtld_initlist_visit(%s)", obj->path)); */
796 for (elm
= obj
->needed
; elm
!= NULL
; elm
= elm
->next
) {
797 if (elm
->obj
!= NULL
) {
798 _rtld_initlist_visit(list
, elm
->obj
, rev
);
803 _rtld_objlist_push_head(list
, obj
);
805 _rtld_objlist_push_tail(list
, obj
);
810 _rtld_initlist_tsort(Objlist
* list
, int rev
)
812 dbg(("_rtld_initlist_tsort"));
816 for (obj
= _rtld_objlist
->next
; obj
; obj
= obj
->next
) {
820 for (obj
= _rtld_objlist
->next
; obj
; obj
= obj
->next
) {
821 _rtld_initlist_visit(list
, obj
, rev
);
826 _rtld_init_dag(Obj_Entry
*root
)
829 _rtld_init_dag1(root
, root
);
833 _rtld_init_dag1(Obj_Entry
*root
, Obj_Entry
*obj
)
835 const Needed_Entry
*needed
;
838 if (_rtld_objlist_find(&obj
->dldags
, root
))
840 dbg(("add %p (%s) to %p (%s) DAG", obj
, obj
->path
, root
,
842 _rtld_objlist_push_tail(&obj
->dldags
, root
);
843 _rtld_objlist_push_tail(&root
->dagmembers
, obj
);
845 for (needed
= obj
->needed
; needed
!= NULL
; needed
= needed
->next
)
846 if (needed
->obj
!= NULL
)
847 _rtld_init_dag1(root
, needed
->obj
);
851 * Note, this is called only for objects loaded by dlopen().
854 _rtld_unload_object(sigset_t
*mask
, Obj_Entry
*root
, bool do_fini_funcs
)
857 _rtld_unref_dag(root
);
858 if (root
->refcount
== 0) { /* We are finished with some objects. */
863 /* Finalize objects that are about to be unmapped. */
865 _rtld_call_fini_functions(mask
, 0);
867 /* Remove the DAG from all objects' DAG lists. */
868 SIMPLEQ_FOREACH(elm
, &root
->dagmembers
, link
)
869 _rtld_objlist_remove(&elm
->obj
->dldags
, root
);
871 /* Remove the DAG from the RTLD_GLOBAL list. */
872 if (root
->globalref
) {
874 _rtld_objlist_remove(&_rtld_list_global
, root
);
877 /* Unmap all objects that are no longer referenced. */
878 linkp
= &_rtld_objlist
->next
;
879 while ((obj
= *linkp
) != NULL
) {
880 if (obj
->refcount
== 0) {
881 dbg(("unloading \"%s\"", obj
->path
));
882 if (obj
->ehdr
!= MAP_FAILED
)
883 munmap(obj
->ehdr
, _rtld_pagesz
);
884 munmap(obj
->mapbase
, obj
->mapsize
);
885 _rtld_objlist_remove(&_rtld_list_global
, obj
);
886 _rtld_linkmap_delete(obj
);
893 _rtld_objtail
= linkp
;
898 _rtld_ref_dag(Obj_Entry
*root
)
900 const Needed_Entry
*needed
;
906 dbg(("incremented reference on \"%s\" (%d)", root
->path
,
908 for (needed
= root
->needed
; needed
!= NULL
;
909 needed
= needed
->next
) {
910 if (needed
->obj
!= NULL
)
911 _rtld_ref_dag(needed
->obj
);
916 _rtld_unref_dag(Obj_Entry
*root
)
920 assert(root
->refcount
!= 0);
923 dbg(("decremented reference on \"%s\" (%d)", root
->path
,
926 if (root
->refcount
== 0) {
927 const Needed_Entry
*needed
;
929 for (needed
= root
->needed
; needed
!= NULL
;
930 needed
= needed
->next
) {
931 if (needed
->obj
!= NULL
)
932 _rtld_unref_dag(needed
->obj
);
937 __strong_alias(__dlclose
,dlclose
)
939 dlclose(void *handle
)
944 dbg(("dlclose of %p", handle
));
946 _rtld_exclusive_enter(&mask
);
948 root
= _rtld_dlcheck(handle
);
951 _rtld_exclusive_exit(&mask
);
955 _rtld_debug
.r_state
= RT_DELETE
;
959 _rtld_unload_object(&mask
, root
, true);
961 _rtld_debug
.r_state
= RT_CONSISTENT
;
964 _rtld_exclusive_exit(&mask
);
969 __strong_alias(__dlerror
,dlerror
)
973 char *msg
= error_message
;
975 error_message
= NULL
;
979 __strong_alias(__dlopen
,dlopen
)
981 dlopen(const char *name
, int mode
)
983 Obj_Entry
**old_obj_tail
= _rtld_objtail
;
984 Obj_Entry
*obj
= NULL
;
985 int flags
= _RTLD_DLOPEN
;
991 dbg(("dlopen of %s %d", name
, mode
));
993 _rtld_exclusive_enter(&mask
);
995 flags
|= (mode
& RTLD_GLOBAL
) ? _RTLD_GLOBAL
: 0;
996 flags
|= (mode
& RTLD_NOLOAD
) ? _RTLD_NOLOAD
: 0;
998 nodelete
= (mode
& RTLD_NODELETE
) ? true : false;
999 now
= ((mode
& RTLD_MODEMASK
) == RTLD_NOW
) ? true : false;
1001 _rtld_debug
.r_state
= RT_ADD
;
1002 _rtld_debug_state();
1005 obj
= _rtld_objmain
;
1008 obj
= _rtld_load_library(name
, _rtld_objmain
, flags
);
1013 if (*old_obj_tail
!= NULL
) { /* We loaded something new. */
1014 assert(*old_obj_tail
== obj
);
1016 result
= _rtld_load_needed_objects(obj
, flags
);
1018 Objlist_Entry
*entry
;
1019 _rtld_init_dag(obj
);
1020 SIMPLEQ_FOREACH(entry
, &obj
->dagmembers
, link
) {
1021 result
= _rtld_verify_object_versions(entry
->obj
);
1026 if (result
== -1 || _rtld_relocate_objects(obj
,
1027 (now
|| obj
->z_now
)) == -1) {
1028 _rtld_unload_object(&mask
, obj
, false);
1032 _rtld_call_init_functions(&mask
);
1036 if ((nodelete
|| obj
->z_nodelete
) && !obj
->ref_nodel
) {
1037 dbg(("dlopen obj %s nodelete", obj
->path
));
1039 obj
->z_nodelete
= obj
->ref_nodel
= true;
1043 _rtld_debug
.r_state
= RT_CONSISTENT
;
1044 _rtld_debug_state();
1046 _rtld_exclusive_exit(&mask
);
1052 * Find a symbol in the main program.
1055 _rtld_objmain_sym(const char *name
)
1059 const Obj_Entry
*obj
;
1062 hash
= _rtld_elf_hash(name
);
1063 obj
= _rtld_objmain
;
1064 _rtld_donelist_init(&donelist
);
1066 def
= _rtld_symlook_list(name
, hash
, &_rtld_list_main
, &obj
, 0,
1070 return obj
->relocbase
+ def
->st_value
;
1076 hackish_return_address(void)
1078 return __builtin_return_address(1);
1082 #ifdef __HAVE_FUNCTION_DESCRIPTORS
1083 #define lookup_mutex_enter() _rtld_exclusive_enter(&mask)
1084 #define lookup_mutex_exit() _rtld_exclusive_exit(&mask)
1086 #define lookup_mutex_enter() _rtld_shared_enter()
1087 #define lookup_mutex_exit() _rtld_shared_exit()
1091 do_dlsym(void *handle
, const char *name
, const Ver_Entry
*ventry
, void *retaddr
)
1093 const Obj_Entry
*obj
;
1096 const Obj_Entry
*defobj
;
1098 const u_int flags
= SYMLOOK_DLSYM
| SYMLOOK_IN_PLT
;
1099 #ifdef __HAVE_FUNCTION_DESCRIPTORS
1103 lookup_mutex_enter();
1105 hash
= _rtld_elf_hash(name
);
1109 switch ((intptr_t)handle
) {
1110 case (intptr_t)NULL
:
1111 case (intptr_t)RTLD_NEXT
:
1112 case (intptr_t)RTLD_DEFAULT
:
1113 case (intptr_t)RTLD_SELF
:
1114 if ((obj
= _rtld_obj_from_addr(retaddr
)) == NULL
) {
1115 _rtld_error("Cannot determine caller's shared object");
1116 lookup_mutex_exit();
1120 switch ((intptr_t)handle
) {
1121 case (intptr_t)NULL
: /* Just the caller's shared object. */
1122 def
= _rtld_symlook_obj(name
, hash
, obj
, flags
, ventry
);
1126 case (intptr_t)RTLD_NEXT
: /* Objects after callers */
1130 case (intptr_t)RTLD_SELF
: /* Caller included */
1131 for (; obj
; obj
= obj
->next
) {
1132 if ((def
= _rtld_symlook_obj(name
, hash
, obj
,
1133 flags
, ventry
)) != NULL
) {
1140 case (intptr_t)RTLD_DEFAULT
:
1141 def
= _rtld_symlook_default(name
, hash
, obj
, &defobj
,
1151 if ((obj
= _rtld_dlcheck(handle
)) == NULL
) {
1152 lookup_mutex_exit();
1156 _rtld_donelist_init(&donelist
);
1158 if (obj
->mainprog
) {
1159 /* Search main program and all libraries loaded by it */
1160 def
= _rtld_symlook_list(name
, hash
, &_rtld_list_main
,
1161 &defobj
, flags
, ventry
, &donelist
);
1166 /* Search the object and all the libraries loaded by it. */
1168 fake
.obj
= __UNCONST(obj
);
1171 _rtld_donelist_init(&depth
);
1172 def
= _rtld_symlook_needed(name
, hash
, &fake
, &defobj
,
1173 flags
, ventry
, &donelist
, &depth
);
1182 if (ELF_ST_TYPE(def
->st_info
) == STT_GNU_IFUNC
) {
1183 #ifdef __HAVE_FUNCTION_DESCRIPTORS
1184 lookup_mutex_exit();
1185 _rtld_shared_enter();
1187 p
= (void *)_rtld_resolve_ifunc(defobj
, def
);
1188 _rtld_shared_exit();
1192 #ifdef __HAVE_FUNCTION_DESCRIPTORS
1193 if (ELF_ST_TYPE(def
->st_info
) == STT_FUNC
) {
1194 p
= (void *)_rtld_function_descriptor_alloc(defobj
,
1196 lookup_mutex_exit();
1199 #endif /* __HAVE_FUNCTION_DESCRIPTORS */
1200 p
= defobj
->relocbase
+ def
->st_value
;
1201 lookup_mutex_exit();
1205 _rtld_error("Undefined symbol \"%s\"", name
);
1206 lookup_mutex_exit();
1210 __strong_alias(__dlsym
,dlsym
)
1212 dlsym(void *handle
, const char *name
)
1216 dbg(("dlsym of %s in %p", name
, handle
));
1219 retaddr
= hackish_return_address();
1221 retaddr
= __builtin_return_address(0);
1223 return do_dlsym(handle
, name
, NULL
, retaddr
);
1226 __strong_alias(__dlvsym
,dlvsym
)
1228 dlvsym(void *handle
, const char *name
, const char *version
)
1230 Ver_Entry
*ventry
= NULL
;
1231 Ver_Entry ver_entry
;
1234 dbg(("dlvsym of %s@%s in %p", name
, version
? version
: NULL
, handle
));
1236 if (version
!= NULL
) {
1237 ver_entry
.name
= version
;
1238 ver_entry
.file
= NULL
;
1239 ver_entry
.hash
= _rtld_elf_hash(version
);
1240 ver_entry
.flags
= 0;
1241 ventry
= &ver_entry
;
1244 retaddr
= hackish_return_address();
1246 retaddr
= __builtin_return_address(0);
1248 return do_dlsym(handle
, name
, ventry
, retaddr
);
1251 __strong_alias(__dladdr
,dladdr
)
1253 dladdr(const void *addr
, Dl_info
*info
)
1255 const Obj_Entry
*obj
;
1256 const Elf_Sym
*def
, *best_def
;
1258 unsigned long symoffset
;
1259 #ifdef __HAVE_FUNCTION_DESCRIPTORS
1263 dbg(("dladdr of %p", addr
));
1265 lookup_mutex_enter();
1267 #ifdef __HAVE_FUNCTION_DESCRIPTORS
1268 addr
= _rtld_function_descriptor_function(addr
);
1269 #endif /* __HAVE_FUNCTION_DESCRIPTORS */
1271 obj
= _rtld_obj_from_addr(addr
);
1273 _rtld_error("No shared object contains address");
1274 lookup_mutex_exit();
1277 info
->dli_fname
= obj
->path
;
1278 info
->dli_fbase
= obj
->mapbase
;
1279 info
->dli_saddr
= (void *)0;
1280 info
->dli_sname
= NULL
;
1283 * Walk the symbol list looking for the symbol whose address is
1284 * closest to the address sent in.
1287 for (symoffset
= 0; symoffset
< obj
->nchains
; symoffset
++) {
1288 def
= obj
->symtab
+ symoffset
;
1291 * For skip the symbol if st_shndx is either SHN_UNDEF or
1294 if (def
->st_shndx
== SHN_UNDEF
|| def
->st_shndx
== SHN_COMMON
)
1298 * If the symbol is greater than the specified address, or if it
1299 * is further away from addr than the current nearest symbol,
1302 symbol_addr
= obj
->relocbase
+ def
->st_value
;
1303 if (symbol_addr
> addr
|| symbol_addr
< info
->dli_saddr
)
1306 /* Update our idea of the nearest symbol. */
1307 info
->dli_sname
= obj
->strtab
+ def
->st_name
;
1308 info
->dli_saddr
= symbol_addr
;
1313 if (info
->dli_saddr
== addr
)
1317 #ifdef __HAVE_FUNCTION_DESCRIPTORS
1318 if (best_def
!= NULL
&& ELF_ST_TYPE(best_def
->st_info
) == STT_FUNC
)
1319 info
->dli_saddr
= (void *)_rtld_function_descriptor_alloc(obj
,
1323 #endif /* __HAVE_FUNCTION_DESCRIPTORS */
1325 lookup_mutex_exit();
1329 __strong_alias(__dlinfo
,dlinfo
)
1331 dlinfo(void *handle
, int req
, void *v
)
1333 const Obj_Entry
*obj
;
1336 dbg(("dlinfo for %p %d", handle
, req
));
1338 _rtld_shared_enter();
1340 if (handle
== RTLD_SELF
) {
1342 retaddr
= hackish_return_address();
1344 retaddr
= __builtin_return_address(0);
1346 if ((obj
= _rtld_obj_from_addr(retaddr
)) == NULL
) {
1347 _rtld_error("Cannot determine caller's shared object");
1348 _rtld_shared_exit();
1352 if ((obj
= _rtld_dlcheck(handle
)) == NULL
) {
1353 _rtld_shared_exit();
1359 case RTLD_DI_LINKMAP
:
1361 const struct link_map
**map
= v
;
1363 *map
= &obj
->linkmap
;
1368 _rtld_error("Invalid request");
1369 _rtld_shared_exit();
1373 _rtld_shared_exit();
1377 __strong_alias(__dl_iterate_phdr
,dl_iterate_phdr
);
1379 dl_iterate_phdr(int (*callback
)(struct dl_phdr_info
*, size_t, void *), void *param
)
1381 struct dl_phdr_info phdr_info
;
1382 const Obj_Entry
*obj
;
1385 dbg(("dl_iterate_phdr"));
1387 _rtld_shared_enter();
1389 for (obj
= _rtld_objlist
; obj
!= NULL
; obj
= obj
->next
) {
1390 phdr_info
.dlpi_addr
= (Elf_Addr
)obj
->relocbase
;
1391 /* XXX: wrong but not fixing it yet */
1392 phdr_info
.dlpi_name
= SIMPLEQ_FIRST(&obj
->names
) ?
1393 SIMPLEQ_FIRST(&obj
->names
)->name
: obj
->path
;
1394 phdr_info
.dlpi_phdr
= obj
->phdr
;
1395 phdr_info
.dlpi_phnum
= obj
->phsize
/ sizeof(obj
->phdr
[0]);
1396 #if defined(__HAVE_TLS_VARIANT_I) || defined(__HAVE_TLS_VARIANT_II)
1397 phdr_info
.dlpi_tls_modid
= obj
->tlsindex
;
1398 phdr_info
.dlpi_tls_data
= obj
->tlsinit
;
1400 phdr_info
.dlpi_tls_modid
= 0;
1401 phdr_info
.dlpi_tls_data
= 0;
1403 phdr_info
.dlpi_adds
= _rtld_objloads
;
1404 phdr_info
.dlpi_subs
= _rtld_objloads
- _rtld_objcount
;
1406 /* XXXlocking: exit point */
1407 error
= callback(&phdr_info
, sizeof(phdr_info
), param
);
1412 _rtld_shared_exit();
1417 * Error reporting function. Use it like printf. If formats the message
1418 * into a buffer, and sets things up so that the next call to dlerror()
1419 * will return the message.
1422 _rtld_error(const char *fmt
,...)
1424 static char buf
[512];
1428 xvsnprintf(buf
, sizeof buf
, fmt
, ap
);
1429 error_message
= buf
;
1434 _rtld_debug_state(void)
1436 #if defined(__hppa__)
1437 __asm
volatile("nop" ::: "memory");
1440 /* Prevent optimizer from removing calls to this function */
1445 _rtld_linkmap_add(Obj_Entry
*obj
)
1447 struct link_map
*l
= &obj
->linkmap
;
1448 struct link_map
*prev
;
1450 obj
->linkmap
.l_name
= obj
->path
;
1451 obj
->linkmap
.l_addr
= obj
->relocbase
;
1452 obj
->linkmap
.l_ld
= obj
->dynamic
;
1454 /* XXX This field is not standard and will be removed eventually. */
1455 obj
->linkmap
.l_offs
= obj
->relocbase
;
1458 if (_rtld_debug
.r_map
== NULL
) {
1459 _rtld_debug
.r_map
= l
;
1464 * Scan to the end of the list, but not past the entry for the
1465 * dynamic linker, which we want to keep at the very end.
1467 for (prev
= _rtld_debug
.r_map
;
1468 prev
->l_next
!= NULL
&& prev
->l_next
!= &_rtld_objself
.linkmap
;
1469 prev
= prev
->l_next
);
1472 l
->l_next
= prev
->l_next
;
1473 if (l
->l_next
!= NULL
)
1474 l
->l_next
->l_prev
= l
;
1479 _rtld_linkmap_delete(Obj_Entry
*obj
)
1481 struct link_map
*l
= &obj
->linkmap
;
1483 if (l
->l_prev
== NULL
) {
1484 if ((_rtld_debug
.r_map
= l
->l_next
) != NULL
)
1485 l
->l_next
->l_prev
= NULL
;
1488 if ((l
->l_prev
->l_next
= l
->l_next
) != NULL
)
1489 l
->l_next
->l_prev
= l
->l_prev
;
1493 _rtld_obj_from_addr(const void *addr
)
1497 for (obj
= _rtld_objlist
; obj
!= NULL
; obj
= obj
->next
) {
1498 if (addr
< (void *) obj
->mapbase
)
1500 if (addr
< (void *) (obj
->mapbase
+ obj
->mapsize
))
1507 _rtld_objlist_clear(Objlist
*list
)
1509 while (!SIMPLEQ_EMPTY(list
)) {
1510 Objlist_Entry
* elm
= SIMPLEQ_FIRST(list
);
1511 SIMPLEQ_REMOVE_HEAD(list
, link
);
1517 _rtld_objlist_remove(Objlist
*list
, Obj_Entry
*obj
)
1521 if ((elm
= _rtld_objlist_find(list
, obj
)) != NULL
) {
1522 SIMPLEQ_REMOVE(list
, elm
, Struct_Objlist_Entry
, link
);
1527 #if defined(__minix)
1528 void _rtld_shared_enter(void) {}
1529 void _rtld_shared_exit(void) {}
1530 void _rtld_exclusive_enter(sigset_t
*mask
) {}
1531 void _rtld_exclusive_exit(sigset_t
*mask
) {}
1533 #define RTLD_EXCLUSIVE_MASK 0x80000000U
1534 static volatile unsigned int _rtld_mutex
;
1535 static volatile unsigned int _rtld_waiter_exclusive
;
1536 static volatile unsigned int _rtld_waiter_shared
;
1539 _rtld_shared_enter(void)
1542 lwpid_t waiter
, self
= 0;
1549 * First check if we are currently not exclusively locked.
1551 if ((cur
& RTLD_EXCLUSIVE_MASK
) == 0) {
1552 /* Yes, so increment use counter */
1553 if (atomic_cas_uint(&_rtld_mutex
, cur
, cur
+ 1) != cur
)
1559 * Someone has an exclusive lock. Puts us on the waiter list.
1563 if (cur
== (self
| RTLD_EXCLUSIVE_MASK
)) {
1564 if (_rtld_mutex_may_recurse
)
1566 _rtld_error("dead lock detected");
1569 waiter
= atomic_swap_uint(&_rtld_waiter_shared
, self
);
1571 * Check for race against _rtld_exclusive_exit before sleeping.
1574 if ((_rtld_mutex
& RTLD_EXCLUSIVE_MASK
) ||
1575 _rtld_waiter_exclusive
)
1576 _lwp_park(CLOCK_REALTIME
, 0, NULL
, 0,
1577 __UNVOLATILE(&_rtld_mutex
), NULL
);
1578 /* Try to remove us from the waiter list. */
1579 atomic_cas_uint(&_rtld_waiter_shared
, self
, 0);
1581 _lwp_unpark(waiter
, __UNVOLATILE(&_rtld_mutex
));
1586 _rtld_shared_exit(void)
1591 * Shared lock taken after an exclusive lock.
1592 * Just assume this is a partial recursion.
1594 if (_rtld_mutex
& RTLD_EXCLUSIVE_MASK
)
1598 * Wakeup LWPs waiting for an exclusive lock if this is the last
1599 * LWP on the shared lock.
1602 if (atomic_dec_uint_nv(&_rtld_mutex
))
1605 if ((waiter
= _rtld_waiter_exclusive
) != 0)
1606 _lwp_unpark(waiter
, __UNVOLATILE(&_rtld_mutex
));
1610 _rtld_exclusive_enter(sigset_t
*mask
)
1612 lwpid_t waiter
, self
= _lwp_self();
1613 unsigned int locked_value
= (unsigned int)self
| RTLD_EXCLUSIVE_MASK
;
1617 sigfillset(&blockmask
);
1618 sigdelset(&blockmask
, SIGTRAP
); /* Allow the debugger */
1619 sigprocmask(SIG_BLOCK
, &blockmask
, mask
);
1622 if (atomic_cas_uint(&_rtld_mutex
, 0, locked_value
) == 0) {
1626 waiter
= atomic_swap_uint(&_rtld_waiter_exclusive
, self
);
1629 if (cur
== locked_value
) {
1630 _rtld_error("dead lock detected");
1634 _lwp_park(CLOCK_REALTIME
, 0, NULL
, 0,
1635 __UNVOLATILE(&_rtld_mutex
), NULL
);
1636 atomic_cas_uint(&_rtld_waiter_exclusive
, self
, 0);
1638 _lwp_unpark(waiter
, __UNVOLATILE(&_rtld_mutex
));
1643 _rtld_exclusive_exit(sigset_t
*mask
)
1650 if ((waiter
= _rtld_waiter_exclusive
) != 0)
1651 _lwp_unpark(waiter
, __UNVOLATILE(&_rtld_mutex
));
1653 if ((waiter
= _rtld_waiter_shared
) != 0)
1654 _lwp_unpark(waiter
, __UNVOLATILE(&_rtld_mutex
));
1656 sigprocmask(SIG_SETMASK
, mask
, NULL
);
1658 #endif /* !defined(__minix) */