Deleted Added
full compact
rtld.c (216489) rtld.c (216695)
1/*-
2 * Copyright 1996, 1997, 1998, 1999, 2000 John D. Polstra.
3 * Copyright 2003 Alexander Kabaev <kan@FreeBSD.ORG>.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 9 unchanged lines hidden (view full) ---

18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
1/*-
2 * Copyright 1996, 1997, 1998, 1999, 2000 John D. Polstra.
3 * Copyright 2003 Alexander Kabaev <kan@FreeBSD.ORG>.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 9 unchanged lines hidden (view full) ---

18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * $FreeBSD: head/libexec/rtld-elf/rtld.c 216489 2010-12-16 16:56:44Z jh $
26 * $FreeBSD: head/libexec/rtld-elf/rtld.c 216695 2010-12-25 08:51:20Z kib $
27 */
28
29/*
30 * Dynamic linker for ELF.
31 *
32 * John Polstra <jdp@polstra.com>.
33 */
34

--- 31 unchanged lines hidden (view full) ---

66#define PATH_RTLD "/libexec/ld-elf32.so.1"
67#endif
68
69/* Types. */
70typedef void (*func_ptr_type)();
71typedef void * (*path_enum_proc) (const char *path, size_t len, void *arg);
72
73/*
27 */
28
29/*
30 * Dynamic linker for ELF.
31 *
32 * John Polstra <jdp@polstra.com>.
33 */
34

--- 31 unchanged lines hidden (view full) ---

66#define PATH_RTLD "/libexec/ld-elf32.so.1"
67#endif
68
69/* Types. */
70typedef void (*func_ptr_type)();
71typedef void * (*path_enum_proc) (const char *path, size_t len, void *arg);
72
73/*
74 * This structure provides a reentrant way to keep a list of objects and
75 * check which ones have already been processed in some way.
76 */
77typedef struct Struct_DoneList {
78 const Obj_Entry **objs; /* Array of object pointers */
79 unsigned int num_alloc; /* Allocated size of the array */
80 unsigned int num_used; /* Number of array slots used */
81} DoneList;
82
83/*
84 * Function declarations.
85 */
86static const char *basename(const char *);
87static void die(void) __dead2;
88static void digest_dynamic1(Obj_Entry *, int, const Elf_Dyn **,
89 const Elf_Dyn **);
90static void digest_dynamic2(Obj_Entry *, const Elf_Dyn *, const Elf_Dyn *);
91static void digest_dynamic(Obj_Entry *, int);
92static Obj_Entry *digest_phdr(const Elf_Phdr *, int, caddr_t, const char *);
93static Obj_Entry *dlcheck(void *);
74 * Function declarations.
75 */
76static const char *basename(const char *);
77static void die(void) __dead2;
78static void digest_dynamic1(Obj_Entry *, int, const Elf_Dyn **,
79 const Elf_Dyn **);
80static void digest_dynamic2(Obj_Entry *, const Elf_Dyn *, const Elf_Dyn *);
81static void digest_dynamic(Obj_Entry *, int);
82static Obj_Entry *digest_phdr(const Elf_Phdr *, int, caddr_t, const char *);
83static Obj_Entry *dlcheck(void *);
84static Obj_Entry *dlopen_object(const char *name, Obj_Entry *refobj,
85 int lo_flags, int mode);
94static Obj_Entry *do_load_object(int, const char *, char *, struct stat *, int);
95static int do_search_info(const Obj_Entry *obj, int, struct dl_serinfo *);
96static bool donelist_check(DoneList *, const Obj_Entry *);
97static void errmsg_restore(char *);
98static char *errmsg_save(void);
99static void *fill_search_info(const char *, size_t, void *);
100static char *find_library(const char *, const Obj_Entry *);
101static const char *gethints(void);
102static void init_dag(Obj_Entry *);
103static void init_dag1(Obj_Entry *, Obj_Entry *, DoneList *);
104static void init_rtld(caddr_t, Elf_Auxinfo **);
105static void initlist_add_neededs(Needed_Entry *, Objlist *);
106static void initlist_add_objects(Obj_Entry *, Obj_Entry **, Objlist *);
107static void linkmap_add(Obj_Entry *);
108static void linkmap_delete(Obj_Entry *);
86static Obj_Entry *do_load_object(int, const char *, char *, struct stat *, int);
87static int do_search_info(const Obj_Entry *obj, int, struct dl_serinfo *);
88static bool donelist_check(DoneList *, const Obj_Entry *);
89static void errmsg_restore(char *);
90static char *errmsg_save(void);
91static void *fill_search_info(const char *, size_t, void *);
92static char *find_library(const char *, const Obj_Entry *);
93static const char *gethints(void);
94static void init_dag(Obj_Entry *);
95static void init_dag1(Obj_Entry *, Obj_Entry *, DoneList *);
96static void init_rtld(caddr_t, Elf_Auxinfo **);
97static void initlist_add_neededs(Needed_Entry *, Objlist *);
98static void initlist_add_objects(Obj_Entry *, Obj_Entry **, Objlist *);
99static void linkmap_add(Obj_Entry *);
100static void linkmap_delete(Obj_Entry *);
101static void load_filtees(Obj_Entry *, int flags, RtldLockState *);
102static void unload_filtees(Obj_Entry *);
109static int load_needed_objects(Obj_Entry *, int);
110static int load_preload_objects(void);
111static Obj_Entry *load_object(const char *, const Obj_Entry *, int);
112static Obj_Entry *obj_from_addr(const void *);
103static int load_needed_objects(Obj_Entry *, int);
104static int load_preload_objects(void);
105static Obj_Entry *load_object(const char *, const Obj_Entry *, int);
106static Obj_Entry *obj_from_addr(const void *);
113static void objlist_call_fini(Objlist *, Obj_Entry *, int *);
114static void objlist_call_init(Objlist *, int *);
107static void objlist_call_fini(Objlist *, Obj_Entry *, RtldLockState *);
108static void objlist_call_init(Objlist *, RtldLockState *);
115static void objlist_clear(Objlist *);
116static Objlist_Entry *objlist_find(Objlist *, const Obj_Entry *);
117static void objlist_init(Objlist *);
118static void objlist_push_head(Objlist *, Obj_Entry *);
119static void objlist_push_tail(Objlist *, Obj_Entry *);
120static void objlist_remove(Objlist *, Obj_Entry *);
121static void *path_enumerate(const char *, path_enum_proc, void *);
109static void objlist_clear(Objlist *);
110static Objlist_Entry *objlist_find(Objlist *, const Obj_Entry *);
111static void objlist_init(Objlist *);
112static void objlist_push_head(Objlist *, Obj_Entry *);
113static void objlist_push_tail(Objlist *, Obj_Entry *);
114static void objlist_remove(Objlist *, Obj_Entry *);
115static void *path_enumerate(const char *, path_enum_proc, void *);
122static int relocate_objects(Obj_Entry *, bool, Obj_Entry *);
116static int relocate_objects(Obj_Entry *, bool, Obj_Entry *, RtldLockState *);
123static int rtld_dirname(const char *, char *);
124static int rtld_dirname_abs(const char *, char *);
125static void rtld_exit(void);
126static char *search_library_path(const char *, const char *);
127static const void **get_program_var_addr(const char *);
128static void set_program_var(const char *, const void *);
117static int rtld_dirname(const char *, char *);
118static int rtld_dirname_abs(const char *, char *);
119static void rtld_exit(void);
120static char *search_library_path(const char *, const char *);
121static const void **get_program_var_addr(const char *);
122static void set_program_var(const char *, const void *);
129static const Elf_Sym *symlook_default(const char *, unsigned long,
130 const Obj_Entry *, const Obj_Entry **, const Ver_Entry *, int);
131static const Elf_Sym *symlook_list(const char *, unsigned long, const Objlist *,
132 const Obj_Entry **, const Ver_Entry *, int, DoneList *);
133static const Elf_Sym *symlook_needed(const char *, unsigned long,
134 const Needed_Entry *, const Obj_Entry **, const Ver_Entry *,
135 int, DoneList *);
123static int symlook_default(SymLook *, const Obj_Entry *refobj);
124static void symlook_init_from_req(SymLook *, const SymLook *);
125static int symlook_list(SymLook *, const Objlist *, DoneList *);
126static int symlook_needed(SymLook *, const Needed_Entry *, DoneList *);
127static int symlook_obj1(SymLook *, const Obj_Entry *);
136static void trace_loaded_objects(Obj_Entry *);
137static void unlink_object(Obj_Entry *);
138static void unload_object(Obj_Entry *);
139static void unref_dag(Obj_Entry *);
140static void ref_dag(Obj_Entry *);
141static int origin_subst_one(char **, const char *, const char *,
142 const char *, char *);
143static char *origin_subst(const char *, const char *);

--- 8 unchanged lines hidden (view full) ---

152void r_debug_state(struct r_debug *, struct link_map *);
153
154/*
155 * Data declarations.
156 */
157static char *error_message; /* Message for dlerror(), or NULL */
158struct r_debug r_debug; /* for GDB; */
159static bool libmap_disable; /* Disable libmap */
128static void trace_loaded_objects(Obj_Entry *);
129static void unlink_object(Obj_Entry *);
130static void unload_object(Obj_Entry *);
131static void unref_dag(Obj_Entry *);
132static void ref_dag(Obj_Entry *);
133static int origin_subst_one(char **, const char *, const char *,
134 const char *, char *);
135static char *origin_subst(const char *, const char *);

--- 8 unchanged lines hidden (view full) ---

144void r_debug_state(struct r_debug *, struct link_map *);
145
146/*
147 * Data declarations.
148 */
149static char *error_message; /* Message for dlerror(), or NULL */
150struct r_debug r_debug; /* for GDB; */
151static bool libmap_disable; /* Disable libmap */
152static bool ld_loadfltr; /* Immediate filters processing */
160static char *libmap_override; /* Maps to use in addition to libmap.conf */
161static bool trust; /* False for setuid and setgid programs */
162static bool dangerous_ld_env; /* True if environment variables have been
163 used to affect the libraries loaded */
164static char *ld_bind_now; /* Environment variable for immediate binding */
165static char *ld_debug; /* Environment variable for debugging */
166static char *ld_library_path; /* Environment variable for search path */
167static char *ld_preload; /* Environment variable for libraries to

--- 127 unchanged lines hidden (view full) ---

295 char **env;
296 Elf_Auxinfo *aux;
297 Elf_Auxinfo *auxp;
298 const char *argv0;
299 Objlist_Entry *entry;
300 Obj_Entry *obj;
301 Obj_Entry **preload_tail;
302 Objlist initlist;
153static char *libmap_override; /* Maps to use in addition to libmap.conf */
154static bool trust; /* False for setuid and setgid programs */
155static bool dangerous_ld_env; /* True if environment variables have been
156 used to affect the libraries loaded */
157static char *ld_bind_now; /* Environment variable for immediate binding */
158static char *ld_debug; /* Environment variable for debugging */
159static char *ld_library_path; /* Environment variable for search path */
160static char *ld_preload; /* Environment variable for libraries to

--- 127 unchanged lines hidden (view full) ---

288 char **env;
289 Elf_Auxinfo *aux;
290 Elf_Auxinfo *auxp;
291 const char *argv0;
292 Objlist_Entry *entry;
293 Obj_Entry *obj;
294 Obj_Entry **preload_tail;
295 Objlist initlist;
303 int lockstate;
296 RtldLockState lockstate;
304
305 /*
306 * On entry, the dynamic linker itself has not been relocated yet.
307 * Be very careful not to reference any global data until after
308 * init_rtld has returned. It is OK to reference file-scope statics
309 * and string constants, and to call static and global functions.
310 */
311

--- 29 unchanged lines hidden (view full) ---

341 * If the process is tainted, then we un-set the dangerous environment
342 * variables. The process will be marked as tainted until setuid(2)
343 * is called. If any child process calls setuid(2) we do not want any
344 * future processes to honor the potentially un-safe variables.
345 */
346 if (!trust) {
347 if (unsetenv(LD_ "PRELOAD") || unsetenv(LD_ "LIBMAP") ||
348 unsetenv(LD_ "LIBRARY_PATH") || unsetenv(LD_ "LIBMAP_DISABLE") ||
297
298 /*
299 * On entry, the dynamic linker itself has not been relocated yet.
300 * Be very careful not to reference any global data until after
301 * init_rtld has returned. It is OK to reference file-scope statics
302 * and string constants, and to call static and global functions.
303 */
304

--- 29 unchanged lines hidden (view full) ---

334 * If the process is tainted, then we un-set the dangerous environment
335 * variables. The process will be marked as tainted until setuid(2)
336 * is called. If any child process calls setuid(2) we do not want any
337 * future processes to honor the potentially un-safe variables.
338 */
339 if (!trust) {
340 if (unsetenv(LD_ "PRELOAD") || unsetenv(LD_ "LIBMAP") ||
341 unsetenv(LD_ "LIBRARY_PATH") || unsetenv(LD_ "LIBMAP_DISABLE") ||
349 unsetenv(LD_ "DEBUG") || unsetenv(LD_ "ELF_HINTS_PATH")) {
342 unsetenv(LD_ "DEBUG") || unsetenv(LD_ "ELF_HINTS_PATH") ||
343 unsetenv(LD_ "LOADFLTR")) {
350 _rtld_error("environment corrupt; aborting");
351 die();
352 }
353 }
354 ld_debug = getenv(LD_ "DEBUG");
355 libmap_disable = getenv(LD_ "LIBMAP_DISABLE") != NULL;
356 libmap_override = getenv(LD_ "LIBMAP");
357 ld_library_path = getenv(LD_ "LIBRARY_PATH");
358 ld_preload = getenv(LD_ "PRELOAD");
359 ld_elf_hints_path = getenv(LD_ "ELF_HINTS_PATH");
344 _rtld_error("environment corrupt; aborting");
345 die();
346 }
347 }
348 ld_debug = getenv(LD_ "DEBUG");
349 libmap_disable = getenv(LD_ "LIBMAP_DISABLE") != NULL;
350 libmap_override = getenv(LD_ "LIBMAP");
351 ld_library_path = getenv(LD_ "LIBRARY_PATH");
352 ld_preload = getenv(LD_ "PRELOAD");
353 ld_elf_hints_path = getenv(LD_ "ELF_HINTS_PATH");
354 ld_loadfltr = getenv(LD_ "LOADFLTR") != NULL;
360 dangerous_ld_env = libmap_disable || (libmap_override != NULL) ||
361 (ld_library_path != NULL) || (ld_preload != NULL) ||
355 dangerous_ld_env = libmap_disable || (libmap_override != NULL) ||
356 (ld_library_path != NULL) || (ld_preload != NULL) ||
362 (ld_elf_hints_path != NULL);
357 (ld_elf_hints_path != NULL) || ld_loadfltr;
363 ld_tracing = getenv(LD_ "TRACE_LOADED_OBJECTS");
364 ld_utrace = getenv(LD_ "UTRACE");
365
366 if ((ld_elf_hints_path == NULL) || strlen(ld_elf_hints_path) == 0)
367 ld_elf_hints_path = _PATH_ELF_HINTS;
368
369 if (ld_debug != NULL && *ld_debug != '\0')
370 debug = 1;
371 dbg("%s is initialized, base address = %p", __progname,
372 (caddr_t) aux_info[AT_BASE]->a_un.a_ptr);
373 dbg("RTLD dynamic = %p", obj_rtld.dynamic);
374 dbg("RTLD pltgot = %p", obj_rtld.pltgot);
375
358 ld_tracing = getenv(LD_ "TRACE_LOADED_OBJECTS");
359 ld_utrace = getenv(LD_ "UTRACE");
360
361 if ((ld_elf_hints_path == NULL) || strlen(ld_elf_hints_path) == 0)
362 ld_elf_hints_path = _PATH_ELF_HINTS;
363
364 if (ld_debug != NULL && *ld_debug != '\0')
365 debug = 1;
366 dbg("%s is initialized, base address = %p", __progname,
367 (caddr_t) aux_info[AT_BASE]->a_un.a_ptr);
368 dbg("RTLD dynamic = %p", obj_rtld.dynamic);
369 dbg("RTLD pltgot = %p", obj_rtld.pltgot);
370
371 dbg("initializing thread locks");
372 lockdflt_init();
373
376 /*
377 * Load the main program, or process its program header if it is
378 * already loaded.
379 */
380 if (aux_info[AT_EXECFD] != NULL) { /* Load the main program. */
381 int fd = aux_info[AT_EXECFD]->a_un.a_val;
382 dbg("loading main program");
383 obj_main = map_object(fd, argv0, NULL);

--- 109 unchanged lines hidden (view full) ---

493 * Allocate all the initial objects out of the static TLS
494 * block even if they didn't ask for it.
495 */
496 allocate_tls_offset(entry->obj);
497 }
498 allocate_initial_tls(obj_list);
499
500 if (relocate_objects(obj_main,
374 /*
375 * Load the main program, or process its program header if it is
376 * already loaded.
377 */
378 if (aux_info[AT_EXECFD] != NULL) { /* Load the main program. */
379 int fd = aux_info[AT_EXECFD]->a_un.a_val;
380 dbg("loading main program");
381 obj_main = map_object(fd, argv0, NULL);

--- 109 unchanged lines hidden (view full) ---

491 * Allocate all the initial objects out of the static TLS
492 * block even if they didn't ask for it.
493 */
494 allocate_tls_offset(entry->obj);
495 }
496 allocate_initial_tls(obj_list);
497
498 if (relocate_objects(obj_main,
501 ld_bind_now != NULL && *ld_bind_now != '\0', &obj_rtld) == -1)
499 ld_bind_now != NULL && *ld_bind_now != '\0', &obj_rtld, NULL) == -1)
502 die();
503
504 dbg("doing copy relocations");
505 if (do_copy_relocations(obj_main) == -1)
506 die();
507
508 if (getenv(LD_ "DUMP_REL_POST") != NULL) {
509 dump_relocations(obj_main);
510 exit (0);
511 }
512
513 dbg("initializing key program variables");
514 set_program_var("__progname", argv[0] != NULL ? basename(argv[0]) : "");
515 set_program_var("environ", env);
516 set_program_var("__elf_aux_vector", aux);
517
500 die();
501
502 dbg("doing copy relocations");
503 if (do_copy_relocations(obj_main) == -1)
504 die();
505
506 if (getenv(LD_ "DUMP_REL_POST") != NULL) {
507 dump_relocations(obj_main);
508 exit (0);
509 }
510
511 dbg("initializing key program variables");
512 set_program_var("__progname", argv[0] != NULL ? basename(argv[0]) : "");
513 set_program_var("environ", env);
514 set_program_var("__elf_aux_vector", aux);
515
518 dbg("initializing thread locks");
519 lockdflt_init();
520
521 /* Make a list of init functions to call. */
522 objlist_init(&initlist);
523 initlist_add_objects(obj_list, preload_tail, &initlist);
524
525 r_debug_state(NULL, &obj_main->linkmap); /* say hello to gdb! */
526
516 /* Make a list of init functions to call. */
517 objlist_init(&initlist);
518 initlist_add_objects(obj_list, preload_tail, &initlist);
519
520 r_debug_state(NULL, &obj_main->linkmap); /* say hello to gdb! */
521
527 lockstate = wlock_acquire(rtld_bind_lock);
522 wlock_acquire(rtld_bind_lock, &lockstate);
528 objlist_call_init(&initlist, &lockstate);
529 objlist_clear(&initlist);
523 objlist_call_init(&initlist, &lockstate);
524 objlist_clear(&initlist);
530 wlock_release(rtld_bind_lock, lockstate);
525 dbg("loading filtees");
526 for (obj = obj_list->next; obj != NULL; obj = obj->next) {
527 if (ld_loadfltr || obj->z_loadfltr)
528 load_filtees(obj, 0, &lockstate);
529 }
530 lock_release(rtld_bind_lock, &lockstate);
531
532 dbg("transferring control to program entry point = %p", obj_main->entry);
533
534 /* Return the exit procedure and the program entry point. */
535 *exit_proc = rtld_exit;
536 *objp = obj_main;
537 return (func_ptr_type) obj_main->entry;
538}
539
540Elf_Addr
541_rtld_bind(Obj_Entry *obj, Elf_Size reloff)
542{
543 const Elf_Rel *rel;
544 const Elf_Sym *def;
545 const Obj_Entry *defobj;
546 Elf_Addr *where;
547 Elf_Addr target;
531
532 dbg("transferring control to program entry point = %p", obj_main->entry);
533
534 /* Return the exit procedure and the program entry point. */
535 *exit_proc = rtld_exit;
536 *objp = obj_main;
537 return (func_ptr_type) obj_main->entry;
538}
539
540Elf_Addr
541_rtld_bind(Obj_Entry *obj, Elf_Size reloff)
542{
543 const Elf_Rel *rel;
544 const Elf_Sym *def;
545 const Obj_Entry *defobj;
546 Elf_Addr *where;
547 Elf_Addr target;
548 int lockstate;
548 RtldLockState lockstate;
549
549
550 lockstate = rlock_acquire(rtld_bind_lock);
550 rlock_acquire(rtld_bind_lock, &lockstate);
551 if (setjmp(lockstate.env) != 0)
552 lock_upgrade(rtld_bind_lock, &lockstate);
551 if (obj->pltrel)
552 rel = (const Elf_Rel *) ((caddr_t) obj->pltrel + reloff);
553 else
554 rel = (const Elf_Rel *) ((caddr_t) obj->pltrela + reloff);
555
556 where = (Elf_Addr *) (obj->relocbase + rel->r_offset);
553 if (obj->pltrel)
554 rel = (const Elf_Rel *) ((caddr_t) obj->pltrel + reloff);
555 else
556 rel = (const Elf_Rel *) ((caddr_t) obj->pltrela + reloff);
557
558 where = (Elf_Addr *) (obj->relocbase + rel->r_offset);
557 def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, true, NULL);
559 def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, true, NULL,
560 &lockstate);
558 if (def == NULL)
559 die();
560
561 target = (Elf_Addr)(defobj->relocbase + def->st_value);
562
563 dbg("\"%s\" in \"%s\" ==> %p in \"%s\"",
564 defobj->strtab + def->st_name, basename(obj->path),
565 (void *)target, basename(defobj->path));
566
567 /*
568 * Write the new contents for the jmpslot. Note that depending on
569 * architecture, the value which we need to return back to the
570 * lazy binding trampoline may or may not be the target
571 * address. The value returned from reloc_jmpslot() is the value
572 * that the trampoline needs.
573 */
574 target = reloc_jmpslot(where, target, defobj, obj, rel);
561 if (def == NULL)
562 die();
563
564 target = (Elf_Addr)(defobj->relocbase + def->st_value);
565
566 dbg("\"%s\" in \"%s\" ==> %p in \"%s\"",
567 defobj->strtab + def->st_name, basename(obj->path),
568 (void *)target, basename(defobj->path));
569
570 /*
571 * Write the new contents for the jmpslot. Note that depending on
572 * architecture, the value which we need to return back to the
573 * lazy binding trampoline may or may not be the target
574 * address. The value returned from reloc_jmpslot() is the value
575 * that the trampoline needs.
576 */
577 target = reloc_jmpslot(where, target, defobj, obj, rel);
575 rlock_release(rtld_bind_lock, lockstate);
578 lock_release(rtld_bind_lock, &lockstate);
576 return target;
577}
578
579/*
580 * Error reporting function. Use it like printf. If formats the message
581 * into a buffer, and sets things up so that the next call to dlerror()
582 * will return the message.
583 */

--- 132 unchanged lines hidden (view full) ---

716 * information in its Obj_Entry structure.
717 */
718static void
719digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath,
720 const Elf_Dyn **dyn_soname)
721{
722 const Elf_Dyn *dynp;
723 Needed_Entry **needed_tail = &obj->needed;
579 return target;
580}
581
582/*
583 * Error reporting function. Use it like printf. If formats the message
584 * into a buffer, and sets things up so that the next call to dlerror()
585 * will return the message.
586 */

--- 132 unchanged lines hidden (view full) ---

719 * information in its Obj_Entry structure.
720 */
721static void
722digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath,
723 const Elf_Dyn **dyn_soname)
724{
725 const Elf_Dyn *dynp;
726 Needed_Entry **needed_tail = &obj->needed;
727 Needed_Entry **needed_filtees_tail = &obj->needed_filtees;
728 Needed_Entry **needed_aux_filtees_tail = &obj->needed_aux_filtees;
724 int plttype = DT_REL;
725
726 *dyn_rpath = NULL;
727 *dyn_soname = NULL;
728
729 obj->bind_now = false;
730 for (dynp = obj->dynamic; dynp->d_tag != DT_NULL; dynp++) {
731 switch (dynp->d_tag) {

--- 94 unchanged lines hidden (view full) ---

826 nep->obj = NULL;
827 nep->next = NULL;
828
829 *needed_tail = nep;
830 needed_tail = &nep->next;
831 }
832 break;
833
729 int plttype = DT_REL;
730
731 *dyn_rpath = NULL;
732 *dyn_soname = NULL;
733
734 obj->bind_now = false;
735 for (dynp = obj->dynamic; dynp->d_tag != DT_NULL; dynp++) {
736 switch (dynp->d_tag) {

--- 94 unchanged lines hidden (view full) ---

831 nep->obj = NULL;
832 nep->next = NULL;
833
834 *needed_tail = nep;
835 needed_tail = &nep->next;
836 }
837 break;
838
839 case DT_FILTER:
840 if (!obj->rtld) {
841 Needed_Entry *nep = NEW(Needed_Entry);
842 nep->name = dynp->d_un.d_val;
843 nep->obj = NULL;
844 nep->next = NULL;
845
846 *needed_filtees_tail = nep;
847 needed_filtees_tail = &nep->next;
848 }
849 break;
850
851 case DT_AUXILIARY:
852 if (!obj->rtld) {
853 Needed_Entry *nep = NEW(Needed_Entry);
854 nep->name = dynp->d_un.d_val;
855 nep->obj = NULL;
856 nep->next = NULL;
857
858 *needed_aux_filtees_tail = nep;
859 needed_aux_filtees_tail = &nep->next;
860 }
861 break;
862
834 case DT_PLTGOT:
835 obj->pltgot = (Elf_Addr *) (obj->relocbase + dynp->d_un.d_ptr);
836 break;
837
838 case DT_TEXTREL:
839 obj->textrel = true;
840 break;
841

--- 76 unchanged lines hidden (view full) ---

918 if ((dynp->d_un.d_val & DF_1_ORIGIN) && trust)
919 obj->z_origin = true;
920 if (dynp->d_un.d_val & DF_1_GLOBAL)
921 /* XXX */;
922 if (dynp->d_un.d_val & DF_1_BIND_NOW)
923 obj->bind_now = true;
924 if (dynp->d_un.d_val & DF_1_NODELETE)
925 obj->z_nodelete = true;
863 case DT_PLTGOT:
864 obj->pltgot = (Elf_Addr *) (obj->relocbase + dynp->d_un.d_ptr);
865 break;
866
867 case DT_TEXTREL:
868 obj->textrel = true;
869 break;
870

--- 76 unchanged lines hidden (view full) ---

947 if ((dynp->d_un.d_val & DF_1_ORIGIN) && trust)
948 obj->z_origin = true;
949 if (dynp->d_un.d_val & DF_1_GLOBAL)
950 /* XXX */;
951 if (dynp->d_un.d_val & DF_1_BIND_NOW)
952 obj->bind_now = true;
953 if (dynp->d_un.d_val & DF_1_NODELETE)
954 obj->z_nodelete = true;
955 if (dynp->d_un.d_val & DF_1_LOADFLTR)
956 obj->z_loadfltr = true;
926 break;
927
928 default:
929 if (!early) {
930 dbg("Ignoring d_tag %ld = %#lx", (long)dynp->d_tag,
931 (long)dynp->d_tag);
932 }
933 break;

--- 224 unchanged lines hidden (view full) ---

1158/*
1159 * Given a symbol number in a referencing object, find the corresponding
1160 * definition of the symbol. Returns a pointer to the symbol, or NULL if
1161 * no definition was found. Returns a pointer to the Obj_Entry of the
1162 * defining object via the reference parameter DEFOBJ_OUT.
1163 */
1164const Elf_Sym *
1165find_symdef(unsigned long symnum, const Obj_Entry *refobj,
957 break;
958
959 default:
960 if (!early) {
961 dbg("Ignoring d_tag %ld = %#lx", (long)dynp->d_tag,
962 (long)dynp->d_tag);
963 }
964 break;

--- 224 unchanged lines hidden (view full) ---

1189/*
1190 * Given a symbol number in a referencing object, find the corresponding
1191 * definition of the symbol. Returns a pointer to the symbol, or NULL if
1192 * no definition was found. Returns a pointer to the Obj_Entry of the
1193 * defining object via the reference parameter DEFOBJ_OUT.
1194 */
1195const Elf_Sym *
1196find_symdef(unsigned long symnum, const Obj_Entry *refobj,
1166 const Obj_Entry **defobj_out, int flags, SymCache *cache)
1197 const Obj_Entry **defobj_out, int flags, SymCache *cache,
1198 RtldLockState *lockstate)
1167{
1168 const Elf_Sym *ref;
1169 const Elf_Sym *def;
1170 const Obj_Entry *defobj;
1199{
1200 const Elf_Sym *ref;
1201 const Elf_Sym *def;
1202 const Obj_Entry *defobj;
1171 const Ver_Entry *ventry;
1203 SymLook req;
1172 const char *name;
1204 const char *name;
1173 unsigned long hash;
1205 int res;
1174
1175 /*
1176 * If we have already found this symbol, get the information from
1177 * the cache.
1178 */
1179 if (symnum >= refobj->nchains)
1180 return NULL; /* Bad object */
1181 if (cache != NULL && cache[symnum].sym != NULL) {
1182 *defobj_out = cache[symnum].obj;
1183 return cache[symnum].sym;
1184 }
1185
1186 ref = refobj->symtab + symnum;
1187 name = refobj->strtab + ref->st_name;
1206
1207 /*
1208 * If we have already found this symbol, get the information from
1209 * the cache.
1210 */
1211 if (symnum >= refobj->nchains)
1212 return NULL; /* Bad object */
1213 if (cache != NULL && cache[symnum].sym != NULL) {
1214 *defobj_out = cache[symnum].obj;
1215 return cache[symnum].sym;
1216 }
1217
1218 ref = refobj->symtab + symnum;
1219 name = refobj->strtab + ref->st_name;
1220 def = NULL;
1188 defobj = NULL;
1189
1190 /*
1191 * We don't have to do a full scale lookup if the symbol is local.
1192 * We know it will bind to the instance in this load module; to
1193 * which we already have a pointer (ie ref). By not doing a lookup,
1194 * we not only improve performance, but it also avoids unresolvable
1195 * symbols when local symbols are not in the hash table. This has
1196 * been seen with the ia64 toolchain.
1197 */
1198 if (ELF_ST_BIND(ref->st_info) != STB_LOCAL) {
1199 if (ELF_ST_TYPE(ref->st_info) == STT_SECTION) {
1200 _rtld_error("%s: Bogus symbol table entry %lu", refobj->path,
1201 symnum);
1202 }
1221 defobj = NULL;
1222
1223 /*
1224 * We don't have to do a full scale lookup if the symbol is local.
1225 * We know it will bind to the instance in this load module; to
1226 * which we already have a pointer (ie ref). By not doing a lookup,
1227 * we not only improve performance, but it also avoids unresolvable
1228 * symbols when local symbols are not in the hash table. This has
1229 * been seen with the ia64 toolchain.
1230 */
1231 if (ELF_ST_BIND(ref->st_info) != STB_LOCAL) {
1232 if (ELF_ST_TYPE(ref->st_info) == STT_SECTION) {
1233 _rtld_error("%s: Bogus symbol table entry %lu", refobj->path,
1234 symnum);
1235 }
1203 ventry = fetch_ventry(refobj, symnum);
1204 hash = elf_hash(name);
1205 def = symlook_default(name, hash, refobj, &defobj, ventry, flags);
1236 symlook_init(&req, name);
1237 req.flags = flags;
1238 req.ventry = fetch_ventry(refobj, symnum);
1239 req.lockstate = lockstate;
1240 res = symlook_default(&req, refobj);
1241 if (res == 0) {
1242 def = req.sym_out;
1243 defobj = req.defobj_out;
1244 }
1206 } else {
1207 def = ref;
1208 defobj = refobj;
1209 }
1210
1211 /*
1212 * If we found no definition and the reference is weak, treat the
1213 * symbol as having the value zero.

--- 117 unchanged lines hidden (view full) ---

1331 assert(!objtmp.textrel);
1332#endif
1333
1334 /*
1335 * Temporarily put the dynamic linker entry into the object list, so
1336 * that symbols can be found.
1337 */
1338
1245 } else {
1246 def = ref;
1247 defobj = refobj;
1248 }
1249
1250 /*
1251 * If we found no definition and the reference is weak, treat the
1252 * symbol as having the value zero.

--- 117 unchanged lines hidden (view full) ---

1370 assert(!objtmp.textrel);
1371#endif
1372
1373 /*
1374 * Temporarily put the dynamic linker entry into the object list, so
1375 * that symbols can be found.
1376 */
1377
1339 relocate_objects(&objtmp, true, &objtmp);
1378 relocate_objects(&objtmp, true, &objtmp, NULL);
1340 }
1341
1342 /* Initialize the object list. */
1343 obj_tail = &obj_list;
1344
1345 /* Now that non-local variables can be accesses, copy out obj_rtld. */
1346 memcpy(&obj_rtld, &objtmp, sizeof(obj_rtld));
1347

--- 63 unchanged lines hidden (view full) ---

1411 obj->on_fini_list = true;
1412 }
1413}
1414
1415#ifndef FPTR_TARGET
1416#define FPTR_TARGET(f) ((Elf_Addr) (f))
1417#endif
1418
1379 }
1380
1381 /* Initialize the object list. */
1382 obj_tail = &obj_list;
1383
1384 /* Now that non-local variables can be accesses, copy out obj_rtld. */
1385 memcpy(&obj_rtld, &objtmp, sizeof(obj_rtld));
1386

--- 63 unchanged lines hidden (view full) ---

1450 obj->on_fini_list = true;
1451 }
1452}
1453
1454#ifndef FPTR_TARGET
1455#define FPTR_TARGET(f) ((Elf_Addr) (f))
1456#endif
1457
1458static void
1459free_needed_filtees(Needed_Entry *n)
1460{
1461 Needed_Entry *needed, *needed1;
1462
1463 for (needed = n; needed != NULL; needed = needed->next) {
1464 if (needed->obj != NULL) {
1465 dlclose(needed->obj);
1466 needed->obj = NULL;
1467 }
1468 }
1469 for (needed = n; needed != NULL; needed = needed1) {
1470 needed1 = needed->next;
1471 free(needed);
1472 }
1473}
1474
1475static void
1476unload_filtees(Obj_Entry *obj)
1477{
1478
1479 free_needed_filtees(obj->needed_filtees);
1480 obj->needed_filtees = NULL;
1481 free_needed_filtees(obj->needed_aux_filtees);
1482 obj->needed_aux_filtees = NULL;
1483 obj->filtees_loaded = false;
1484}
1485
1486static void
1487load_filtee1(Obj_Entry *obj, Needed_Entry *needed, int flags)
1488{
1489
1490 for (; needed != NULL; needed = needed->next) {
1491 needed->obj = dlopen_object(obj->strtab + needed->name, obj,
1492 flags, ((ld_loadfltr || obj->z_loadfltr) ? RTLD_NOW : RTLD_LAZY) |
1493 RTLD_LOCAL);
1494 }
1495}
1496
1497static void
1498load_filtees(Obj_Entry *obj, int flags, RtldLockState *lockstate)
1499{
1500
1501 lock_restart_for_upgrade(lockstate);
1502 if (!obj->filtees_loaded) {
1503 load_filtee1(obj, obj->needed_filtees, flags);
1504 load_filtee1(obj, obj->needed_aux_filtees, flags);
1505 obj->filtees_loaded = true;
1506 }
1507}
1508
1509static int
1510process_needed(Obj_Entry *obj, Needed_Entry *needed, int flags)
1511{
1512 Obj_Entry *obj1;
1513
1514 for (; needed != NULL; needed = needed->next) {
1515 obj1 = needed->obj = load_object(obj->strtab + needed->name, obj,
1516 flags & ~RTLD_LO_NOLOAD);
1517 if (obj1 == NULL && !ld_tracing && (flags & RTLD_LO_FILTEES) == 0)
1518 return (-1);
1519 if (obj1 != NULL && obj1->z_nodelete && !obj1->ref_nodel) {
1520 dbg("obj %s nodelete", obj1->path);
1521 init_dag(obj1);
1522 ref_dag(obj1);
1523 obj1->ref_nodel = true;
1524 }
1525 }
1526 return (0);
1527}
1528
1419/*
1420 * Given a shared object, traverse its list of needed objects, and load
1421 * each of them. Returns 0 on success. Generates an error message and
1422 * returns -1 on failure.
1423 */
1424static int
1425load_needed_objects(Obj_Entry *first, int flags)
1426{
1529/*
1530 * Given a shared object, traverse its list of needed objects, and load
1531 * each of them. Returns 0 on success. Generates an error message and
1532 * returns -1 on failure.
1533 */
1534static int
1535load_needed_objects(Obj_Entry *first, int flags)
1536{
1427 Obj_Entry *obj, *obj1;
1537 Obj_Entry *obj;
1428
1429 for (obj = first; obj != NULL; obj = obj->next) {
1538
1539 for (obj = first; obj != NULL; obj = obj->next) {
1430 Needed_Entry *needed;
1431
1432 for (needed = obj->needed; needed != NULL; needed = needed->next) {
1433 obj1 = needed->obj = load_object(obj->strtab + needed->name, obj,
1434 flags & ~RTLD_LO_NOLOAD);
1435 if (obj1 == NULL && !ld_tracing)
1436 return -1;
1437 if (obj1 != NULL && obj1->z_nodelete && !obj1->ref_nodel) {
1438 dbg("obj %s nodelete", obj1->path);
1439 init_dag(obj1);
1440 ref_dag(obj1);
1441 obj1->ref_nodel = true;
1442 }
1443 }
1540 if (process_needed(obj, obj->needed, flags) == -1)
1541 return (-1);
1444 }
1542 }
1445
1446 return 0;
1543 return (0);
1447}
1448
1449static int
1450load_preload_objects(void)
1451{
1452 char *p = ld_preload;
1453 static const char delim[] = " \t:;";
1454

--- 155 unchanged lines hidden (view full) ---

1610/*
1611 * Call the finalization functions for each of the objects in "list"
1612 * belonging to the DAG of "root" and referenced once. If NULL "root"
1613 * is specified, every finalization function will be called regardless
1614 * of the reference count and the list elements won't be freed. All of
1615 * the objects are expected to have non-NULL fini functions.
1616 */
1617static void
1544}
1545
1546static int
1547load_preload_objects(void)
1548{
1549 char *p = ld_preload;
1550 static const char delim[] = " \t:;";
1551

--- 155 unchanged lines hidden (view full) ---

1707/*
1708 * Call the finalization functions for each of the objects in "list"
1709 * belonging to the DAG of "root" and referenced once. If NULL "root"
1710 * is specified, every finalization function will be called regardless
1711 * of the reference count and the list elements won't be freed. All of
1712 * the objects are expected to have non-NULL fini functions.
1713 */
1714static void
1618objlist_call_fini(Objlist *list, Obj_Entry *root, int *lockstate)
1715objlist_call_fini(Objlist *list, Obj_Entry *root, RtldLockState *lockstate)
1619{
1620 Objlist_Entry *elm;
1621 char *saved_msg;
1622
1623 assert(root == NULL || root->refcount == 1);
1624
1625 /*
1626 * Preserve the current error message since a fini function might

--- 13 unchanged lines hidden (view full) ---

1640 STAILQ_REMOVE(list, elm, Struct_Objlist_Entry, link);
1641 /*
1642 * XXX: If a dlopen() call references an object while the
1643 * fini function is in progress, we might end up trying to
1644 * unload the referenced object in dlclose() or the object
1645 * won't be unloaded although its fini function has been
1646 * called.
1647 */
1716{
1717 Objlist_Entry *elm;
1718 char *saved_msg;
1719
1720 assert(root == NULL || root->refcount == 1);
1721
1722 /*
1723 * Preserve the current error message since a fini function might

--- 13 unchanged lines hidden (view full) ---

1737 STAILQ_REMOVE(list, elm, Struct_Objlist_Entry, link);
1738 /*
1739 * XXX: If a dlopen() call references an object while the
1740 * fini function is in progress, we might end up trying to
1741 * unload the referenced object in dlclose() or the object
1742 * won't be unloaded although its fini function has been
1743 * called.
1744 */
1648 wlock_release(rtld_bind_lock, *lockstate);
1745 lock_release(rtld_bind_lock, lockstate);
1649 call_initfini_pointer(elm->obj, elm->obj->fini);
1746 call_initfini_pointer(elm->obj, elm->obj->fini);
1650 *lockstate = wlock_acquire(rtld_bind_lock);
1747 wlock_acquire(rtld_bind_lock, lockstate);
1651 /* No need to free anything if process is going down. */
1652 if (root != NULL)
1653 free(elm);
1654 /*
1655 * We must restart the list traversal after every fini call
1656 * because a dlclose() call from the fini function or from
1657 * another thread might have modified the reference counts.
1658 */

--- 4 unchanged lines hidden (view full) ---

1663}
1664
1665/*
1666 * Call the initialization functions for each of the objects in
1667 * "list". All of the objects are expected to have non-NULL init
1668 * functions.
1669 */
1670static void
1748 /* No need to free anything if process is going down. */
1749 if (root != NULL)
1750 free(elm);
1751 /*
1752 * We must restart the list traversal after every fini call
1753 * because a dlclose() call from the fini function or from
1754 * another thread might have modified the reference counts.
1755 */

--- 4 unchanged lines hidden (view full) ---

1760}
1761
1762/*
1763 * Call the initialization functions for each of the objects in
1764 * "list". All of the objects are expected to have non-NULL init
1765 * functions.
1766 */
1767static void
1671objlist_call_init(Objlist *list, int *lockstate)
1768objlist_call_init(Objlist *list, RtldLockState *lockstate)
1672{
1673 Objlist_Entry *elm;
1674 Obj_Entry *obj;
1675 char *saved_msg;
1676
1677 /*
1678 * Clean init_scanned flag so that objects can be rechecked and
1679 * possibly initialized earlier if any of vectors called below

--- 15 unchanged lines hidden (view full) ---

1695 LD_UTRACE(UTRACE_INIT_CALL, elm->obj, (void *)elm->obj->init, 0, 0,
1696 elm->obj->path);
1697 /*
1698 * Race: other thread might try to use this object before current
1699 * one completes the initilization. Not much can be done here
1700 * without better locking.
1701 */
1702 elm->obj->init_done = true;
1769{
1770 Objlist_Entry *elm;
1771 Obj_Entry *obj;
1772 char *saved_msg;
1773
1774 /*
1775 * Clean init_scanned flag so that objects can be rechecked and
1776 * possibly initialized earlier if any of vectors called below

--- 15 unchanged lines hidden (view full) ---

1792 LD_UTRACE(UTRACE_INIT_CALL, elm->obj, (void *)elm->obj->init, 0, 0,
1793 elm->obj->path);
1794 /*
1795 * Race: other thread might try to use this object before current
1796 * one completes the initilization. Not much can be done here
1797 * without better locking.
1798 */
1799 elm->obj->init_done = true;
1703 wlock_release(rtld_bind_lock, *lockstate);
1800 lock_release(rtld_bind_lock, lockstate);
1704 call_initfini_pointer(elm->obj, elm->obj->init);
1801 call_initfini_pointer(elm->obj, elm->obj->init);
1705 *lockstate = wlock_acquire(rtld_bind_lock);
1802 wlock_acquire(rtld_bind_lock, lockstate);
1706 }
1707 errmsg_restore(saved_msg);
1708}
1709
1710static void
1711objlist_clear(Objlist *list)
1712{
1713 Objlist_Entry *elm;

--- 55 unchanged lines hidden (view full) ---

1769
1770/*
1771 * Relocate newly-loaded shared objects. The argument is a pointer to
1772 * the Obj_Entry for the first such object. All objects from the first
1773 * to the end of the list of objects are relocated. Returns 0 on success,
1774 * or -1 on failure.
1775 */
1776static int
1803 }
1804 errmsg_restore(saved_msg);
1805}
1806
1807static void
1808objlist_clear(Objlist *list)
1809{
1810 Objlist_Entry *elm;

--- 55 unchanged lines hidden (view full) ---

1866
1867/*
1868 * Relocate newly-loaded shared objects. The argument is a pointer to
1869 * the Obj_Entry for the first such object. All objects from the first
1870 * to the end of the list of objects are relocated. Returns 0 on success,
1871 * or -1 on failure.
1872 */
1873static int
1777relocate_objects(Obj_Entry *first, bool bind_now, Obj_Entry *rtldobj)
1874relocate_objects(Obj_Entry *first, bool bind_now, Obj_Entry *rtldobj,
1875 RtldLockState *lockstate)
1778{
1779 Obj_Entry *obj;
1780
1781 for (obj = first; obj != NULL; obj = obj->next) {
1782 if (obj != rtldobj)
1783 dbg("relocating \"%s\"", obj->path);
1784 if (obj->nbuckets == 0 || obj->nchains == 0 || obj->buckets == NULL ||
1785 obj->symtab == NULL || obj->strtab == NULL) {

--- 8 unchanged lines hidden (view full) ---

1794 PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
1795 _rtld_error("%s: Cannot write-enable text segment: %s",
1796 obj->path, strerror(errno));
1797 return -1;
1798 }
1799 }
1800
1801 /* Process the non-PLT relocations. */
1876{
1877 Obj_Entry *obj;
1878
1879 for (obj = first; obj != NULL; obj = obj->next) {
1880 if (obj != rtldobj)
1881 dbg("relocating \"%s\"", obj->path);
1882 if (obj->nbuckets == 0 || obj->nchains == 0 || obj->buckets == NULL ||
1883 obj->symtab == NULL || obj->strtab == NULL) {

--- 8 unchanged lines hidden (view full) ---

1892 PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
1893 _rtld_error("%s: Cannot write-enable text segment: %s",
1894 obj->path, strerror(errno));
1895 return -1;
1896 }
1897 }
1898
1899 /* Process the non-PLT relocations. */
1802 if (reloc_non_plt(obj, rtldobj))
1900 if (reloc_non_plt(obj, rtldobj, lockstate))
1803 return -1;
1804
1805 if (obj->textrel) { /* Re-protected the text segment. */
1806 if (mprotect(obj->mapbase, obj->textsize,
1807 PROT_READ|PROT_EXEC) == -1) {
1808 _rtld_error("%s: Cannot write-protect text segment: %s",
1809 obj->path, strerror(errno));
1810 return -1;
1811 }
1812 }
1813
1814 /* Process the PLT relocations. */
1815 if (reloc_plt(obj) == -1)
1816 return -1;
1817 /* Relocate the jump slots if we are doing immediate binding. */
1818 if (obj->bind_now || bind_now)
1901 return -1;
1902
1903 if (obj->textrel) { /* Re-protected the text segment. */
1904 if (mprotect(obj->mapbase, obj->textsize,
1905 PROT_READ|PROT_EXEC) == -1) {
1906 _rtld_error("%s: Cannot write-protect text segment: %s",
1907 obj->path, strerror(errno));
1908 return -1;
1909 }
1910 }
1911
1912 /* Process the PLT relocations. */
1913 if (reloc_plt(obj) == -1)
1914 return -1;
1915 /* Relocate the jump slots if we are doing immediate binding. */
1916 if (obj->bind_now || bind_now)
1819 if (reloc_jmpslots(obj) == -1)
1917 if (reloc_jmpslots(obj, lockstate) == -1)
1820 return -1;
1821
1822
1823 /*
1824 * Set up the magic number and version in the Obj_Entry. These
1825 * were checked in the crt1.o from the original ElfKit, so we
1826 * set them for backward compatibility.
1827 */

--- 9 unchanged lines hidden (view full) ---

1837
1838/*
1839 * Cleanup procedure. It will be called (by the atexit mechanism) just
1840 * before the process exits.
1841 */
1842static void
1843rtld_exit(void)
1844{
1918 return -1;
1919
1920
1921 /*
1922 * Set up the magic number and version in the Obj_Entry. These
1923 * were checked in the crt1.o from the original ElfKit, so we
1924 * set them for backward compatibility.
1925 */

--- 9 unchanged lines hidden (view full) ---

1935
1936/*
1937 * Cleanup procedure. It will be called (by the atexit mechanism) just
1938 * before the process exits.
1939 */
1940static void
1941rtld_exit(void)
1942{
1845 int lockstate;
1943 RtldLockState lockstate;
1846
1944
1847 lockstate = wlock_acquire(rtld_bind_lock);
1945 wlock_acquire(rtld_bind_lock, &lockstate);
1848 dbg("rtld_exit()");
1849 objlist_call_fini(&list_fini, NULL, &lockstate);
1850 /* No need to remove the items from the list, since we are exiting. */
1851 if (!libmap_disable)
1852 lm_fini();
1946 dbg("rtld_exit()");
1947 objlist_call_fini(&list_fini, NULL, &lockstate);
1948 /* No need to remove the items from the list, since we are exiting. */
1949 if (!libmap_disable)
1950 lm_fini();
1853 wlock_release(rtld_bind_lock, lockstate);
1951 lock_release(rtld_bind_lock, &lockstate);
1854}
1855
1856static void *
1857path_enumerate(const char *path, path_enum_proc callback, void *arg)
1858{
1859#ifdef COMPAT_32BIT
1860 const char *trans;
1861#endif

--- 78 unchanged lines hidden (view full) ---

1940
1941 return (p);
1942}
1943
1944int
1945dlclose(void *handle)
1946{
1947 Obj_Entry *root;
1952}
1953
1954static void *
1955path_enumerate(const char *path, path_enum_proc callback, void *arg)
1956{
1957#ifdef COMPAT_32BIT
1958 const char *trans;
1959#endif

--- 78 unchanged lines hidden (view full) ---

2038
2039 return (p);
2040}
2041
2042int
2043dlclose(void *handle)
2044{
2045 Obj_Entry *root;
1948 int lockstate;
2046 RtldLockState lockstate;
1949
2047
1950 lockstate = wlock_acquire(rtld_bind_lock);
2048 wlock_acquire(rtld_bind_lock, &lockstate);
1951 root = dlcheck(handle);
1952 if (root == NULL) {
2049 root = dlcheck(handle);
2050 if (root == NULL) {
1953 wlock_release(rtld_bind_lock, lockstate);
2051 lock_release(rtld_bind_lock, &lockstate);
1954 return -1;
1955 }
1956 LD_UTRACE(UTRACE_DLCLOSE_START, handle, NULL, 0, root->dl_refcount,
1957 root->path);
1958
1959 /* Unreference the object and its dependencies. */
1960 root->dl_refcount--;
1961

--- 9 unchanged lines hidden (view full) ---

1971 /* Finish cleaning up the newly-unreferenced objects. */
1972 GDB_STATE(RT_DELETE,&root->linkmap);
1973 unload_object(root);
1974 GDB_STATE(RT_CONSISTENT,NULL);
1975 } else
1976 unref_dag(root);
1977
1978 LD_UTRACE(UTRACE_DLCLOSE_STOP, handle, NULL, 0, 0, NULL);
2052 return -1;
2053 }
2054 LD_UTRACE(UTRACE_DLCLOSE_START, handle, NULL, 0, root->dl_refcount,
2055 root->path);
2056
2057 /* Unreference the object and its dependencies. */
2058 root->dl_refcount--;
2059

--- 9 unchanged lines hidden (view full) ---

2069 /* Finish cleaning up the newly-unreferenced objects. */
2070 GDB_STATE(RT_DELETE,&root->linkmap);
2071 unload_object(root);
2072 GDB_STATE(RT_CONSISTENT,NULL);
2073 } else
2074 unref_dag(root);
2075
2076 LD_UTRACE(UTRACE_DLCLOSE_STOP, handle, NULL, 0, 0, NULL);
1979 wlock_release(rtld_bind_lock, lockstate);
2077 lock_release(rtld_bind_lock, &lockstate);
1980 return 0;
1981}
1982
1983char *
1984dlerror(void)
1985{
1986 char *msg = error_message;
1987 error_message = NULL;

--- 20 unchanged lines hidden (view full) ---

2008 cur_context_destroy(cur_context);
2009 cur_context = context;
2010 cur_context_destroy = context_destroy;
2011}
2012
2013void *
2014dlopen(const char *name, int mode)
2015{
2078 return 0;
2079}
2080
2081char *
2082dlerror(void)
2083{
2084 char *msg = error_message;
2085 error_message = NULL;

--- 20 unchanged lines hidden (view full) ---

2106 cur_context_destroy(cur_context);
2107 cur_context = context;
2108 cur_context_destroy = context_destroy;
2109}
2110
2111void *
2112dlopen(const char *name, int mode)
2113{
2016 Obj_Entry **old_obj_tail;
2017 Obj_Entry *obj;
2018 Objlist initlist;
2019 int result, lockstate, nodelete, lo_flags;
2114 int lo_flags;
2020
2021 LD_UTRACE(UTRACE_DLOPEN_START, NULL, NULL, 0, mode, name);
2022 ld_tracing = (mode & RTLD_TRACE) == 0 ? NULL : "1";
2023 if (ld_tracing != NULL)
2024 environ = (char **)*get_program_var_addr("environ");
2115
2116 LD_UTRACE(UTRACE_DLOPEN_START, NULL, NULL, 0, mode, name);
2117 ld_tracing = (mode & RTLD_TRACE) == 0 ? NULL : "1";
2118 if (ld_tracing != NULL)
2119 environ = (char **)*get_program_var_addr("environ");
2025 nodelete = mode & RTLD_NODELETE;
2026 lo_flags = RTLD_LO_DLOPEN;
2120 lo_flags = RTLD_LO_DLOPEN;
2121 if (mode & RTLD_NODELETE)
2122 lo_flags |= RTLD_LO_NODELETE;
2027 if (mode & RTLD_NOLOAD)
2028 lo_flags |= RTLD_LO_NOLOAD;
2029 if (ld_tracing != NULL)
2030 lo_flags |= RTLD_LO_TRACE;
2031
2123 if (mode & RTLD_NOLOAD)
2124 lo_flags |= RTLD_LO_NOLOAD;
2125 if (ld_tracing != NULL)
2126 lo_flags |= RTLD_LO_TRACE;
2127
2128 return (dlopen_object(name, obj_main, lo_flags,
2129 mode & (RTLD_MODEMASK | RTLD_GLOBAL)));
2130}
2131
2132static Obj_Entry *
2133dlopen_object(const char *name, Obj_Entry *refobj, int lo_flags, int mode)
2134{
2135 Obj_Entry **old_obj_tail;
2136 Obj_Entry *obj;
2137 Objlist initlist;
2138 RtldLockState lockstate;
2139 int result;
2140
2032 objlist_init(&initlist);
2033
2141 objlist_init(&initlist);
2142
2034 lockstate = wlock_acquire(rtld_bind_lock);
2143 wlock_acquire(rtld_bind_lock, &lockstate);
2035 GDB_STATE(RT_ADD,NULL);
2036
2037 old_obj_tail = obj_tail;
2038 obj = NULL;
2039 if (name == NULL) {
2040 obj = obj_main;
2041 obj->refcount++;
2042 } else {
2144 GDB_STATE(RT_ADD,NULL);
2145
2146 old_obj_tail = obj_tail;
2147 obj = NULL;
2148 if (name == NULL) {
2149 obj = obj_main;
2150 obj->refcount++;
2151 } else {
2043 obj = load_object(name, obj_main, lo_flags);
2152 obj = load_object(name, refobj, lo_flags);
2044 }
2045
2046 if (obj) {
2047 obj->dl_refcount++;
2048 if (mode & RTLD_GLOBAL && objlist_find(&list_global, obj) == NULL)
2049 objlist_push_tail(&list_global, obj);
2153 }
2154
2155 if (obj) {
2156 obj->dl_refcount++;
2157 if (mode & RTLD_GLOBAL && objlist_find(&list_global, obj) == NULL)
2158 objlist_push_tail(&list_global, obj);
2050 mode &= RTLD_MODEMASK;
2051 if (*old_obj_tail != NULL) { /* We loaded something new. */
2052 assert(*old_obj_tail == obj);
2159 if (*old_obj_tail != NULL) { /* We loaded something new. */
2160 assert(*old_obj_tail == obj);
2053 result = load_needed_objects(obj, RTLD_LO_DLOPEN);
2161 result = load_needed_objects(obj, lo_flags & RTLD_LO_DLOPEN);
2054 init_dag(obj);
2055 ref_dag(obj);
2056 if (result != -1)
2057 result = rtld_verify_versions(&obj->dagmembers);
2058 if (result != -1 && ld_tracing)
2059 goto trace;
2162 init_dag(obj);
2163 ref_dag(obj);
2164 if (result != -1)
2165 result = rtld_verify_versions(&obj->dagmembers);
2166 if (result != -1 && ld_tracing)
2167 goto trace;
2060 if (result == -1 ||
2061 (relocate_objects(obj, mode == RTLD_NOW, &obj_rtld)) == -1) {
2168 if (result == -1 || (relocate_objects(obj, (mode & RTLD_MODEMASK)
2169 == RTLD_NOW, &obj_rtld, &lockstate)) == -1) {
2062 obj->dl_refcount--;
2063 unref_dag(obj);
2064 if (obj->refcount == 0)
2065 unload_object(obj);
2066 obj = NULL;
2067 } else {
2068 /* Make list of init functions to call. */
2069 initlist_add_objects(obj, &obj->next, &initlist);

--- 4 unchanged lines hidden (view full) ---

2074 * Bump the reference counts for objects on this DAG. If
2075 * this is the first dlopen() call for the object that was
2076 * already loaded as a dependency, initialize the dag
2077 * starting at it.
2078 */
2079 init_dag(obj);
2080 ref_dag(obj);
2081
2170 obj->dl_refcount--;
2171 unref_dag(obj);
2172 if (obj->refcount == 0)
2173 unload_object(obj);
2174 obj = NULL;
2175 } else {
2176 /* Make list of init functions to call. */
2177 initlist_add_objects(obj, &obj->next, &initlist);

--- 4 unchanged lines hidden (view full) ---

2182 * Bump the reference counts for objects on this DAG. If
2183 * this is the first dlopen() call for the object that was
2184 * already loaded as a dependency, initialize the dag
2185 * starting at it.
2186 */
2187 init_dag(obj);
2188 ref_dag(obj);
2189
2082 if (ld_tracing)
2190 if ((lo_flags & RTLD_LO_TRACE) != 0)
2083 goto trace;
2084 }
2191 goto trace;
2192 }
2085 if (obj != NULL && (nodelete || obj->z_nodelete) && !obj->ref_nodel) {
2193 if (obj != NULL && ((lo_flags & RTLD_LO_NODELETE) != 0 ||
2194 obj->z_nodelete) && !obj->ref_nodel) {
2086 dbg("obj %s nodelete", obj->path);
2087 ref_dag(obj);
2088 obj->z_nodelete = obj->ref_nodel = true;
2089 }
2090 }
2091
2092 LD_UTRACE(UTRACE_DLOPEN_STOP, obj, NULL, 0, obj ? obj->dl_refcount : 0,
2093 name);
2094 GDB_STATE(RT_CONSISTENT,obj ? &obj->linkmap : NULL);
2095
2096 /* Call the init functions. */
2097 objlist_call_init(&initlist, &lockstate);
2098 objlist_clear(&initlist);
2195 dbg("obj %s nodelete", obj->path);
2196 ref_dag(obj);
2197 obj->z_nodelete = obj->ref_nodel = true;
2198 }
2199 }
2200
2201 LD_UTRACE(UTRACE_DLOPEN_STOP, obj, NULL, 0, obj ? obj->dl_refcount : 0,
2202 name);
2203 GDB_STATE(RT_CONSISTENT,obj ? &obj->linkmap : NULL);
2204
2205 /* Call the init functions. */
2206 objlist_call_init(&initlist, &lockstate);
2207 objlist_clear(&initlist);
2099 wlock_release(rtld_bind_lock, lockstate);
2208 lock_release(rtld_bind_lock, &lockstate);
2100 return obj;
2101trace:
2102 trace_loaded_objects(obj);
2209 return obj;
2210trace:
2211 trace_loaded_objects(obj);
2103 wlock_release(rtld_bind_lock, lockstate);
2212 lock_release(rtld_bind_lock, &lockstate);
2104 exit(0);
2105}
2106
2107static void *
2108do_dlsym(void *handle, const char *name, void *retaddr, const Ver_Entry *ve,
2109 int flags)
2110{
2111 DoneList donelist;
2112 const Obj_Entry *obj, *defobj;
2213 exit(0);
2214}
2215
2216static void *
2217do_dlsym(void *handle, const char *name, void *retaddr, const Ver_Entry *ve,
2218 int flags)
2219{
2220 DoneList donelist;
2221 const Obj_Entry *obj, *defobj;
2113 const Elf_Sym *def, *symp;
2114 unsigned long hash;
2115 int lockstate;
2222 const Elf_Sym *def;
2223 SymLook req;
2224 RtldLockState lockstate;
2225 int res;
2116
2226
2117 hash = elf_hash(name);
2118 def = NULL;
2119 defobj = NULL;
2227 def = NULL;
2228 defobj = NULL;
2120 flags |= SYMLOOK_IN_PLT;
2229 symlook_init(&req, name);
2230 req.ventry = ve;
2231 req.flags = flags | SYMLOOK_IN_PLT;
2232 req.lockstate = &lockstate;
2121
2233
2122 lockstate = rlock_acquire(rtld_bind_lock);
2234 rlock_acquire(rtld_bind_lock, &lockstate);
2235 if (setjmp(lockstate.env) != 0)
2236 lock_upgrade(rtld_bind_lock, &lockstate);
2123 if (handle == NULL || handle == RTLD_NEXT ||
2124 handle == RTLD_DEFAULT || handle == RTLD_SELF) {
2125
2126 if ((obj = obj_from_addr(retaddr)) == NULL) {
2127 _rtld_error("Cannot determine caller's shared object");
2237 if (handle == NULL || handle == RTLD_NEXT ||
2238 handle == RTLD_DEFAULT || handle == RTLD_SELF) {
2239
2240 if ((obj = obj_from_addr(retaddr)) == NULL) {
2241 _rtld_error("Cannot determine caller's shared object");
2128 rlock_release(rtld_bind_lock, lockstate);
2242 lock_release(rtld_bind_lock, &lockstate);
2129 return NULL;
2130 }
2131 if (handle == NULL) { /* Just the caller's shared object. */
2243 return NULL;
2244 }
2245 if (handle == NULL) { /* Just the caller's shared object. */
2132 def = symlook_obj(name, hash, obj, ve, flags);
2133 defobj = obj;
2246 res = symlook_obj(&req, obj);
2247 if (res == 0) {
2248 def = req.sym_out;
2249 defobj = req.defobj_out;
2250 }
2134 } else if (handle == RTLD_NEXT || /* Objects after caller's */
2135 handle == RTLD_SELF) { /* ... caller included */
2136 if (handle == RTLD_NEXT)
2137 obj = obj->next;
2138 for (; obj != NULL; obj = obj->next) {
2251 } else if (handle == RTLD_NEXT || /* Objects after caller's */
2252 handle == RTLD_SELF) { /* ... caller included */
2253 if (handle == RTLD_NEXT)
2254 obj = obj->next;
2255 for (; obj != NULL; obj = obj->next) {
2139 if ((symp = symlook_obj(name, hash, obj, ve, flags)) != NULL) {
2140 if (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK) {
2141 def = symp;
2142 defobj = obj;
2256 res = symlook_obj(&req, obj);
2257 if (res == 0) {
2258 if (def == NULL ||
2259 ELF_ST_BIND(req.sym_out->st_info) != STB_WEAK) {
2260 def = req.sym_out;
2261 defobj = req.defobj_out;
2143 if (ELF_ST_BIND(def->st_info) != STB_WEAK)
2144 break;
2145 }
2146 }
2147 }
2148 /*
2149 * Search the dynamic linker itself, and possibly resolve the
2150 * symbol from there. This is how the application links to
2151 * dynamic linker services such as dlopen.
2152 */
2153 if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
2262 if (ELF_ST_BIND(def->st_info) != STB_WEAK)
2263 break;
2264 }
2265 }
2266 }
2267 /*
2268 * Search the dynamic linker itself, and possibly resolve the
2269 * symbol from there. This is how the application links to
2270 * dynamic linker services such as dlopen.
2271 */
2272 if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
2154 symp = symlook_obj(name, hash, &obj_rtld, ve, flags);
2155 if (symp != NULL) {
2156 def = symp;
2157 defobj = &obj_rtld;
2273 res = symlook_obj(&req, &obj_rtld);
2274 if (res == 0) {
2275 def = req.sym_out;
2276 defobj = req.defobj_out;
2158 }
2159 }
2160 } else {
2161 assert(handle == RTLD_DEFAULT);
2277 }
2278 }
2279 } else {
2280 assert(handle == RTLD_DEFAULT);
2162 def = symlook_default(name, hash, obj, &defobj, ve, flags);
2281 res = symlook_obj(&req, obj);
2282 if (res == 0) {
2283 defobj = req.defobj_out;
2284 def = req.sym_out;
2285 }
2163 }
2164 } else {
2165 if ((obj = dlcheck(handle)) == NULL) {
2286 }
2287 } else {
2288 if ((obj = dlcheck(handle)) == NULL) {
2166 rlock_release(rtld_bind_lock, lockstate);
2289 lock_release(rtld_bind_lock, &lockstate);
2167 return NULL;
2168 }
2169
2170 donelist_init(&donelist);
2171 if (obj->mainprog) {
2172 /* Search main program and all libraries loaded by it. */
2290 return NULL;
2291 }
2292
2293 donelist_init(&donelist);
2294 if (obj->mainprog) {
2295 /* Search main program and all libraries loaded by it. */
2173 def = symlook_list(name, hash, &list_main, &defobj, ve, flags,
2174 &donelist);
2175
2176 /*
2177 * We do not distinguish between 'main' object and global scope.
2178 * If symbol is not defined by objects loaded at startup, continue
2179 * search among dynamically loaded objects with RTLD_GLOBAL
2180 * scope.
2181 */
2182 if (def == NULL)
2183 def = symlook_list(name, hash, &list_global, &defobj, ve,
2184 flags, &donelist);
2296 res = symlook_list(&req, &list_main, &donelist);
2297 if (res == 0) {
2298 def = req.sym_out;
2299 defobj = req.defobj_out;
2300 } else {
2301 /*
2302 * We do not distinguish between 'main' object and
2303 * global scope. If symbol is not defined by objects
2304 * loaded at startup, continue search among
2305 * dynamically loaded objects with RTLD_GLOBAL scope.
2306 */
2307 res = symlook_list(&req, &list_global, &donelist);
2308 if (res == 0) {
2309 def = req.sym_out;
2310 defobj = req.defobj_out;
2311 }
2312 }
2185 } else {
2186 Needed_Entry fake;
2187
2188 /* Search the whole DAG rooted at the given object. */
2189 fake.next = NULL;
2190 fake.obj = (Obj_Entry *)obj;
2191 fake.name = 0;
2313 } else {
2314 Needed_Entry fake;
2315
2316 /* Search the whole DAG rooted at the given object. */
2317 fake.next = NULL;
2318 fake.obj = (Obj_Entry *)obj;
2319 fake.name = 0;
2192 def = symlook_needed(name, hash, &fake, &defobj, ve, flags,
2193 &donelist);
2320 res = symlook_needed(&req, &fake, &donelist);
2321 if (res == 0) {
2322 def = req.sym_out;
2323 defobj = req.defobj_out;
2324 }
2194 }
2195 }
2196
2197 if (def != NULL) {
2325 }
2326 }
2327
2328 if (def != NULL) {
2198 rlock_release(rtld_bind_lock, lockstate);
2329 lock_release(rtld_bind_lock, &lockstate);
2199
2200 /*
2201 * The value required by the caller is derived from the value
2202 * of the symbol. For the ia64 architecture, we need to
2203 * construct a function descriptor which the caller can use to
2204 * call the function with the right 'gp' value. For other
2205 * architectures and for non-functions, the value is simply
2206 * the relocated value of the symbol.
2207 */
2208 if (ELF_ST_TYPE(def->st_info) == STT_FUNC)
2209 return make_function_pointer(def, defobj);
2210 else
2211 return defobj->relocbase + def->st_value;
2212 }
2213
2214 _rtld_error("Undefined symbol \"%s\"", name);
2330
2331 /*
2332 * The value required by the caller is derived from the value
2333 * of the symbol. For the ia64 architecture, we need to
2334 * construct a function descriptor which the caller can use to
2335 * call the function with the right 'gp' value. For other
2336 * architectures and for non-functions, the value is simply
2337 * the relocated value of the symbol.
2338 */
2339 if (ELF_ST_TYPE(def->st_info) == STT_FUNC)
2340 return make_function_pointer(def, defobj);
2341 else
2342 return defobj->relocbase + def->st_value;
2343 }
2344
2345 _rtld_error("Undefined symbol \"%s\"", name);
2215 rlock_release(rtld_bind_lock, lockstate);
2346 lock_release(rtld_bind_lock, &lockstate);
2216 return NULL;
2217}
2218
2219void *
2220dlsym(void *handle, const char *name)
2221{
2222 return do_dlsym(handle, name, __builtin_return_address(0), NULL,
2223 SYMLOOK_DLSYM);

--- 24 unchanged lines hidden (view full) ---

2248 return do_dlsym(handle, name, __builtin_return_address(0), &ventry,
2249 SYMLOOK_DLSYM);
2250}
2251
2252int
2253_rtld_addr_phdr(const void *addr, struct dl_phdr_info *phdr_info)
2254{
2255 const Obj_Entry *obj;
2347 return NULL;
2348}
2349
2350void *
2351dlsym(void *handle, const char *name)
2352{
2353 return do_dlsym(handle, name, __builtin_return_address(0), NULL,
2354 SYMLOOK_DLSYM);

--- 24 unchanged lines hidden (view full) ---

2379 return do_dlsym(handle, name, __builtin_return_address(0), &ventry,
2380 SYMLOOK_DLSYM);
2381}
2382
2383int
2384_rtld_addr_phdr(const void *addr, struct dl_phdr_info *phdr_info)
2385{
2386 const Obj_Entry *obj;
2256 int lockstate;
2387 RtldLockState lockstate;
2257
2388
2258 lockstate = rlock_acquire(rtld_bind_lock);
2389 rlock_acquire(rtld_bind_lock, &lockstate);
2259 obj = obj_from_addr(addr);
2260 if (obj == NULL) {
2261 _rtld_error("No shared object contains address");
2390 obj = obj_from_addr(addr);
2391 if (obj == NULL) {
2392 _rtld_error("No shared object contains address");
2262 rlock_release(rtld_bind_lock, lockstate);
2393 lock_release(rtld_bind_lock, &lockstate);
2263 return (0);
2264 }
2265 rtld_fill_dl_phdr_info(obj, phdr_info);
2394 return (0);
2395 }
2396 rtld_fill_dl_phdr_info(obj, phdr_info);
2266 rlock_release(rtld_bind_lock, lockstate);
2397 lock_release(rtld_bind_lock, &lockstate);
2267 return (1);
2268}
2269
2270int
2271dladdr(const void *addr, Dl_info *info)
2272{
2273 const Obj_Entry *obj;
2274 const Elf_Sym *def;
2275 void *symbol_addr;
2276 unsigned long symoffset;
2398 return (1);
2399}
2400
2401int
2402dladdr(const void *addr, Dl_info *info)
2403{
2404 const Obj_Entry *obj;
2405 const Elf_Sym *def;
2406 void *symbol_addr;
2407 unsigned long symoffset;
2277 int lockstate;
2408 RtldLockState lockstate;
2278
2409
2279 lockstate = rlock_acquire(rtld_bind_lock);
2410 rlock_acquire(rtld_bind_lock, &lockstate);
2280 obj = obj_from_addr(addr);
2281 if (obj == NULL) {
2282 _rtld_error("No shared object contains address");
2411 obj = obj_from_addr(addr);
2412 if (obj == NULL) {
2413 _rtld_error("No shared object contains address");
2283 rlock_release(rtld_bind_lock, lockstate);
2414 lock_release(rtld_bind_lock, &lockstate);
2284 return 0;
2285 }
2286 info->dli_fname = obj->path;
2287 info->dli_fbase = obj->mapbase;
2288 info->dli_saddr = (void *)0;
2289 info->dli_sname = NULL;
2290
2291 /*

--- 22 unchanged lines hidden (view full) ---

2314 /* Update our idea of the nearest symbol. */
2315 info->dli_sname = obj->strtab + def->st_name;
2316 info->dli_saddr = symbol_addr;
2317
2318 /* Exact match? */
2319 if (info->dli_saddr == addr)
2320 break;
2321 }
2415 return 0;
2416 }
2417 info->dli_fname = obj->path;
2418 info->dli_fbase = obj->mapbase;
2419 info->dli_saddr = (void *)0;
2420 info->dli_sname = NULL;
2421
2422 /*

--- 22 unchanged lines hidden (view full) ---

2445 /* Update our idea of the nearest symbol. */
2446 info->dli_sname = obj->strtab + def->st_name;
2447 info->dli_saddr = symbol_addr;
2448
2449 /* Exact match? */
2450 if (info->dli_saddr == addr)
2451 break;
2452 }
2322 rlock_release(rtld_bind_lock, lockstate);
2453 lock_release(rtld_bind_lock, &lockstate);
2323 return 1;
2324}
2325
2326int
2327dlinfo(void *handle, int request, void *p)
2328{
2329 const Obj_Entry *obj;
2454 return 1;
2455}
2456
2457int
2458dlinfo(void *handle, int request, void *p)
2459{
2460 const Obj_Entry *obj;
2330 int error, lockstate;
2461 RtldLockState lockstate;
2462 int error;
2331
2463
2332 lockstate = rlock_acquire(rtld_bind_lock);
2464 rlock_acquire(rtld_bind_lock, &lockstate);
2333
2334 if (handle == NULL || handle == RTLD_SELF) {
2335 void *retaddr;
2336
2337 retaddr = __builtin_return_address(0); /* __GNUC__ only */
2338 if ((obj = obj_from_addr(retaddr)) == NULL)
2339 _rtld_error("Cannot determine caller's shared object");
2340 } else
2341 obj = dlcheck(handle);
2342
2343 if (obj == NULL) {
2465
2466 if (handle == NULL || handle == RTLD_SELF) {
2467 void *retaddr;
2468
2469 retaddr = __builtin_return_address(0); /* __GNUC__ only */
2470 if ((obj = obj_from_addr(retaddr)) == NULL)
2471 _rtld_error("Cannot determine caller's shared object");
2472 } else
2473 obj = dlcheck(handle);
2474
2475 if (obj == NULL) {
2344 rlock_release(rtld_bind_lock, lockstate);
2476 lock_release(rtld_bind_lock, &lockstate);
2345 return (-1);
2346 }
2347
2348 error = 0;
2349 switch (request) {
2350 case RTLD_DI_LINKMAP:
2351 *((struct link_map const **)p) = &obj->linkmap;
2352 break;

--- 6 unchanged lines hidden (view full) ---

2359 error = do_search_info(obj, request, (struct dl_serinfo *)p);
2360 break;
2361
2362 default:
2363 _rtld_error("Invalid request %d passed to dlinfo()", request);
2364 error = -1;
2365 }
2366
2477 return (-1);
2478 }
2479
2480 error = 0;
2481 switch (request) {
2482 case RTLD_DI_LINKMAP:
2483 *((struct link_map const **)p) = &obj->linkmap;
2484 break;

--- 6 unchanged lines hidden (view full) ---

2491 error = do_search_info(obj, request, (struct dl_serinfo *)p);
2492 break;
2493
2494 default:
2495 _rtld_error("Invalid request %d passed to dlinfo()", request);
2496 error = -1;
2497 }
2498
2367 rlock_release(rtld_bind_lock, lockstate);
2499 lock_release(rtld_bind_lock, &lockstate);
2368
2369 return (error);
2370}
2371
2372static void
2373rtld_fill_dl_phdr_info(const Obj_Entry *obj, struct dl_phdr_info *phdr_info)
2374{
2375

--- 8 unchanged lines hidden (view full) ---

2384 phdr_info->dlpi_subs = obj_loads - obj_count;
2385}
2386
2387int
2388dl_iterate_phdr(__dl_iterate_hdr_callback callback, void *param)
2389{
2390 struct dl_phdr_info phdr_info;
2391 const Obj_Entry *obj;
2500
2501 return (error);
2502}
2503
2504static void
2505rtld_fill_dl_phdr_info(const Obj_Entry *obj, struct dl_phdr_info *phdr_info)
2506{
2507

--- 8 unchanged lines hidden (view full) ---

2516 phdr_info->dlpi_subs = obj_loads - obj_count;
2517}
2518
2519int
2520dl_iterate_phdr(__dl_iterate_hdr_callback callback, void *param)
2521{
2522 struct dl_phdr_info phdr_info;
2523 const Obj_Entry *obj;
2392 int error, bind_lockstate, phdr_lockstate;
2524 RtldLockState bind_lockstate, phdr_lockstate;
2525 int error;
2393
2526
2394 phdr_lockstate = wlock_acquire(rtld_phdr_lock);
2395 bind_lockstate = rlock_acquire(rtld_bind_lock);
2527 wlock_acquire(rtld_phdr_lock, &phdr_lockstate);
2528 rlock_acquire(rtld_bind_lock, &bind_lockstate);
2396
2397 error = 0;
2398
2399 for (obj = obj_list; obj != NULL; obj = obj->next) {
2400 rtld_fill_dl_phdr_info(obj, &phdr_info);
2401 if ((error = callback(&phdr_info, sizeof phdr_info, param)) != 0)
2402 break;
2403
2404 }
2529
2530 error = 0;
2531
2532 for (obj = obj_list; obj != NULL; obj = obj->next) {
2533 rtld_fill_dl_phdr_info(obj, &phdr_info);
2534 if ((error = callback(&phdr_info, sizeof phdr_info, param)) != 0)
2535 break;
2536
2537 }
2405 rlock_release(rtld_bind_lock, bind_lockstate);
2406 wlock_release(rtld_phdr_lock, phdr_lockstate);
2538 lock_release(rtld_bind_lock, &bind_lockstate);
2539 lock_release(rtld_phdr_lock, &phdr_lockstate);
2407
2408 return (error);
2409}
2410
2411struct fill_search_info_args {
2412 int request;
2413 unsigned int flags;
2414 Dl_serinfo *serinfo;

--- 211 unchanged lines hidden (view full) ---

2626
2627/*
2628 * Get address of the pointer variable in the main program.
2629 */
2630static const void **
2631get_program_var_addr(const char *name)
2632{
2633 const Obj_Entry *obj;
2540
2541 return (error);
2542}
2543
2544struct fill_search_info_args {
2545 int request;
2546 unsigned int flags;
2547 Dl_serinfo *serinfo;

--- 211 unchanged lines hidden (view full) ---

2759
2760/*
2761 * Get address of the pointer variable in the main program.
2762 */
2763static const void **
2764get_program_var_addr(const char *name)
2765{
2766 const Obj_Entry *obj;
2634 unsigned long hash;
2767 SymLook req;
2635
2768
2636 hash = elf_hash(name);
2769 symlook_init(&req, name);
2637 for (obj = obj_main; obj != NULL; obj = obj->next) {
2770 for (obj = obj_main; obj != NULL; obj = obj->next) {
2638 const Elf_Sym *def;
2639
2640 if ((def = symlook_obj(name, hash, obj, NULL, 0)) != NULL) {
2641 const void **addr;
2642
2643 addr = (const void **)(obj->relocbase + def->st_value);
2644 return addr;
2771 if (symlook_obj(&req, obj) == 0) {
2772 return ((const void **)(req.defobj_out->relocbase +
2773 req.sym_out->st_value));
2645 }
2646 }
2774 }
2775 }
2647 return NULL;
2776 return (NULL);
2648}
2649
2650/*
2651 * Set a pointer variable in the main program to the given value. This
2652 * is used to set key variables such as "environ" before any of the
2653 * init functions are called.
2654 */
2655static void

--- 8 unchanged lines hidden (view full) ---

2664}
2665
2666/*
2667 * Given a symbol name in a referencing object, find the corresponding
2668 * definition of the symbol. Returns a pointer to the symbol, or NULL if
2669 * no definition was found. Returns a pointer to the Obj_Entry of the
2670 * defining object via the reference parameter DEFOBJ_OUT.
2671 */
2777}
2778
2779/*
2780 * Set a pointer variable in the main program to the given value. This
2781 * is used to set key variables such as "environ" before any of the
2782 * init functions are called.
2783 */
2784static void

--- 8 unchanged lines hidden (view full) ---

2793}
2794
2795/*
2796 * Given a symbol name in a referencing object, find the corresponding
2797 * definition of the symbol. Returns a pointer to the symbol, or NULL if
2798 * no definition was found. Returns a pointer to the Obj_Entry of the
2799 * defining object via the reference parameter DEFOBJ_OUT.
2800 */
2672static const Elf_Sym *
2673symlook_default(const char *name, unsigned long hash, const Obj_Entry *refobj,
2674 const Obj_Entry **defobj_out, const Ver_Entry *ventry, int flags)
2801static int
2802symlook_default(SymLook *req, const Obj_Entry *refobj)
2675{
2676 DoneList donelist;
2677 const Elf_Sym *def;
2803{
2804 DoneList donelist;
2805 const Elf_Sym *def;
2678 const Elf_Sym *symp;
2679 const Obj_Entry *obj;
2680 const Obj_Entry *defobj;
2681 const Objlist_Entry *elm;
2806 const Obj_Entry *defobj;
2807 const Objlist_Entry *elm;
2808 SymLook req1;
2809 int res;
2682 def = NULL;
2683 defobj = NULL;
2684 donelist_init(&donelist);
2810 def = NULL;
2811 defobj = NULL;
2812 donelist_init(&donelist);
2813 symlook_init_from_req(&req1, req);
2685
2686 /* Look first in the referencing object if linked symbolically. */
2687 if (refobj->symbolic && !donelist_check(&donelist, refobj)) {
2814
2815 /* Look first in the referencing object if linked symbolically. */
2816 if (refobj->symbolic && !donelist_check(&donelist, refobj)) {
2688 symp = symlook_obj(name, hash, refobj, ventry, flags);
2689 if (symp != NULL) {
2690 def = symp;
2691 defobj = refobj;
2817 res = symlook_obj(&req1, refobj);
2818 if (res == 0) {
2819 def = req1.sym_out;
2820 defobj = req1.defobj_out;
2821 assert(defobj != NULL);
2692 }
2693 }
2694
2695 /* Search all objects loaded at program start up. */
2696 if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
2822 }
2823 }
2824
2825 /* Search all objects loaded at program start up. */
2826 if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
2697 symp = symlook_list(name, hash, &list_main, &obj, ventry, flags,
2698 &donelist);
2699 if (symp != NULL &&
2700 (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
2701 def = symp;
2702 defobj = obj;
2827 res = symlook_list(&req1, &list_main, &donelist);
2828 if (res == 0 &&
2829 (def == NULL || ELF_ST_BIND(req1.sym_out->st_info) != STB_WEAK)) {
2830 def = req1.sym_out;
2831 defobj = req1.defobj_out;
2832 assert(defobj != NULL);
2703 }
2704 }
2705
2706 /* Search all DAGs whose roots are RTLD_GLOBAL objects. */
2707 STAILQ_FOREACH(elm, &list_global, link) {
2708 if (def != NULL && ELF_ST_BIND(def->st_info) != STB_WEAK)
2709 break;
2833 }
2834 }
2835
2836 /* Search all DAGs whose roots are RTLD_GLOBAL objects. */
2837 STAILQ_FOREACH(elm, &list_global, link) {
2838 if (def != NULL && ELF_ST_BIND(def->st_info) != STB_WEAK)
2839 break;
2710 symp = symlook_list(name, hash, &elm->obj->dagmembers, &obj, ventry,
2711 flags, &donelist);
2712 if (symp != NULL &&
2713 (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
2714 def = symp;
2715 defobj = obj;
2840 res = symlook_list(&req1, &elm->obj->dagmembers, &donelist);
2841 if (res == 0 &&
2842 (def == NULL || ELF_ST_BIND(req1.sym_out->st_info) != STB_WEAK)) {
2843 def = req1.sym_out;
2844 defobj = req1.defobj_out;
2845 assert(defobj != NULL);
2716 }
2717 }
2718
2719 /* Search all dlopened DAGs containing the referencing object. */
2720 STAILQ_FOREACH(elm, &refobj->dldags, link) {
2721 if (def != NULL && ELF_ST_BIND(def->st_info) != STB_WEAK)
2722 break;
2846 }
2847 }
2848
2849 /* Search all dlopened DAGs containing the referencing object. */
2850 STAILQ_FOREACH(elm, &refobj->dldags, link) {
2851 if (def != NULL && ELF_ST_BIND(def->st_info) != STB_WEAK)
2852 break;
2723 symp = symlook_list(name, hash, &elm->obj->dagmembers, &obj, ventry,
2724 flags, &donelist);
2725 if (symp != NULL &&
2726 (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
2727 def = symp;
2728 defobj = obj;
2853 res = symlook_list(&req1, &elm->obj->dagmembers, &donelist);
2854 if (res == 0 &&
2855 (def == NULL || ELF_ST_BIND(req1.sym_out->st_info) != STB_WEAK)) {
2856 def = req1.sym_out;
2857 defobj = req1.defobj_out;
2858 assert(defobj != NULL);
2729 }
2730 }
2731
2732 /*
2733 * Search the dynamic linker itself, and possibly resolve the
2734 * symbol from there. This is how the application links to
2735 * dynamic linker services such as dlopen.
2736 */
2737 if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
2859 }
2860 }
2861
2862 /*
2863 * Search the dynamic linker itself, and possibly resolve the
2864 * symbol from there. This is how the application links to
2865 * dynamic linker services such as dlopen.
2866 */
2867 if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
2738 symp = symlook_obj(name, hash, &obj_rtld, ventry, flags);
2739 if (symp != NULL) {
2740 def = symp;
2741 defobj = &obj_rtld;
2868 res = symlook_obj(&req1, &obj_rtld);
2869 if (res == 0) {
2870 def = req1.sym_out;
2871 defobj = req1.defobj_out;
2872 assert(defobj != NULL);
2742 }
2743 }
2744
2873 }
2874 }
2875
2745 if (def != NULL)
2746 *defobj_out = defobj;
2747 return def;
2876 if (def != NULL) {
2877 assert(defobj != NULL);
2878 req->defobj_out = defobj;
2879 req->sym_out = def;
2880 return (0);
2881 }
2882 return (ESRCH);
2748}
2749
2883}
2884
2750static const Elf_Sym *
2751symlook_list(const char *name, unsigned long hash, const Objlist *objlist,
2752 const Obj_Entry **defobj_out, const Ver_Entry *ventry, int flags,
2753 DoneList *dlp)
2885static int
2886symlook_list(SymLook *req, const Objlist *objlist, DoneList *dlp)
2754{
2887{
2755 const Elf_Sym *symp;
2756 const Elf_Sym *def;
2757 const Obj_Entry *defobj;
2758 const Objlist_Entry *elm;
2888 const Elf_Sym *def;
2889 const Obj_Entry *defobj;
2890 const Objlist_Entry *elm;
2891 SymLook req1;
2892 int res;
2759
2760 def = NULL;
2761 defobj = NULL;
2762 STAILQ_FOREACH(elm, objlist, link) {
2763 if (donelist_check(dlp, elm->obj))
2764 continue;
2893
2894 def = NULL;
2895 defobj = NULL;
2896 STAILQ_FOREACH(elm, objlist, link) {
2897 if (donelist_check(dlp, elm->obj))
2898 continue;
2765 if ((symp = symlook_obj(name, hash, elm->obj, ventry, flags)) != NULL) {
2766 if (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK) {
2767 def = symp;
2768 defobj = elm->obj;
2899 symlook_init_from_req(&req1, req);
2900 if ((res = symlook_obj(&req1, elm->obj)) == 0) {
2901 if (def == NULL || ELF_ST_BIND(req1.sym_out->st_info) != STB_WEAK) {
2902 def = req1.sym_out;
2903 defobj = req1.defobj_out;
2769 if (ELF_ST_BIND(def->st_info) != STB_WEAK)
2770 break;
2771 }
2772 }
2773 }
2904 if (ELF_ST_BIND(def->st_info) != STB_WEAK)
2905 break;
2906 }
2907 }
2908 }
2774 if (def != NULL)
2775 *defobj_out = defobj;
2776 return def;
2909 if (def != NULL) {
2910 req->sym_out = def;
2911 req->defobj_out = defobj;
2912 return (0);
2913 }
2914 return (ESRCH);
2777}
2778
2779/*
2780 * Search the symbol table of a shared object and all objects needed
2781 * by it for a symbol of the given name. Search order is
2782 * breadth-first. Returns a pointer to the symbol, or NULL if no
2783 * definition was found.
2784 */
2915}
2916
2917/*
2918 * Search the symbol table of a shared object and all objects needed
2919 * by it for a symbol of the given name. Search order is
2920 * breadth-first. Returns a pointer to the symbol, or NULL if no
2921 * definition was found.
2922 */
2785static const Elf_Sym *
2786symlook_needed(const char *name, unsigned long hash, const Needed_Entry *needed,
2787 const Obj_Entry **defobj_out, const Ver_Entry *ventry, int flags,
2788 DoneList *dlp)
2923static int
2924symlook_needed(SymLook *req, const Needed_Entry *needed, DoneList *dlp)
2789{
2790 const Elf_Sym *def, *def_w;
2791 const Needed_Entry *n;
2925{
2926 const Elf_Sym *def, *def_w;
2927 const Needed_Entry *n;
2792 const Obj_Entry *obj, *defobj, *defobj1;
2928 const Obj_Entry *defobj, *defobj1;
2929 SymLook req1;
2930 int res;
2793
2794 def = def_w = NULL;
2795 defobj = NULL;
2931
2932 def = def_w = NULL;
2933 defobj = NULL;
2934 symlook_init_from_req(&req1, req);
2796 for (n = needed; n != NULL; n = n->next) {
2935 for (n = needed; n != NULL; n = n->next) {
2797 if ((obj = n->obj) == NULL ||
2798 donelist_check(dlp, obj) ||
2799 (def = symlook_obj(name, hash, obj, ventry, flags)) == NULL)
2936 if (n->obj == NULL || donelist_check(dlp, n->obj) ||
2937 (res = symlook_obj(&req1, n->obj)) != 0)
2800 continue;
2938 continue;
2801 defobj = obj;
2939 def = req1.sym_out;
2940 defobj = req1.defobj_out;
2802 if (ELF_ST_BIND(def->st_info) != STB_WEAK) {
2941 if (ELF_ST_BIND(def->st_info) != STB_WEAK) {
2803 *defobj_out = defobj;
2804 return (def);
2942 req->defobj_out = defobj;
2943 req->sym_out = def;
2944 return (0);
2805 }
2806 }
2807 /*
2808 * There we come when either symbol definition is not found in
2809 * directly needed objects, or found symbol is weak.
2810 */
2811 for (n = needed; n != NULL; n = n->next) {
2945 }
2946 }
2947 /*
2948 * There we come when either symbol definition is not found in
2949 * directly needed objects, or found symbol is weak.
2950 */
2951 for (n = needed; n != NULL; n = n->next) {
2812 if ((obj = n->obj) == NULL)
2952 if (n->obj == NULL)
2813 continue;
2953 continue;
2814 def_w = symlook_needed(name, hash, obj->needed, &defobj1,
2815 ventry, flags, dlp);
2816 if (def_w == NULL)
2954 res = symlook_needed(&req1, n->obj->needed, dlp);
2955 if (res != 0)
2817 continue;
2956 continue;
2957 def_w = req1.sym_out;
2958 defobj1 = req1.defobj_out;
2818 if (def == NULL || ELF_ST_BIND(def_w->st_info) != STB_WEAK) {
2819 def = def_w;
2820 defobj = defobj1;
2821 }
2822 if (ELF_ST_BIND(def_w->st_info) != STB_WEAK)
2823 break;
2824 }
2959 if (def == NULL || ELF_ST_BIND(def_w->st_info) != STB_WEAK) {
2960 def = def_w;
2961 defobj = defobj1;
2962 }
2963 if (ELF_ST_BIND(def_w->st_info) != STB_WEAK)
2964 break;
2965 }
2825 if (def != NULL)
2826 *defobj_out = defobj;
2827 return (def);
2966 if (def != NULL) {
2967 req->sym_out = def;
2968 req->defobj_out = defobj;
2969 return (0);
2970 }
2971 return (ESRCH);
2828}
2829
2830/*
2831 * Search the symbol table of a single shared object for a symbol of
2832 * the given name and version, if requested. Returns a pointer to the
2972}
2973
2974/*
2975 * Search the symbol table of a single shared object for a symbol of
2976 * the given name and version, if requested. Returns a pointer to the
2833 * symbol, or NULL if no definition was found.
2977 * symbol, or NULL if no definition was found. If the object is
2978 * filter, return filtered symbol from filtee.
2834 *
2835 * The symbol's hash value is passed in for efficiency reasons; that
2836 * eliminates many recomputations of the hash value.
2837 */
2979 *
2980 * The symbol's hash value is passed in for efficiency reasons; that
2981 * eliminates many recomputations of the hash value.
2982 */
2838const Elf_Sym *
2839symlook_obj(const char *name, unsigned long hash, const Obj_Entry *obj,
2840 const Ver_Entry *ventry, int flags)
2983int
2984symlook_obj(SymLook *req, const Obj_Entry *obj)
2841{
2985{
2986 DoneList donelist;
2987 SymLook req1;
2988 int res, mres;
2989
2990 mres = symlook_obj1(req, obj);
2991 if (mres == 0) {
2992 if (obj->needed_filtees != NULL) {
2993 load_filtees(__DECONST(Obj_Entry *, obj), 0, req->lockstate);
2994 donelist_init(&donelist);
2995 symlook_init_from_req(&req1, req);
2996 res = symlook_needed(&req1, obj->needed_filtees, &donelist);
2997 if (res == 0) {
2998 req->sym_out = req1.sym_out;
2999 req->defobj_out = req1.defobj_out;
3000 }
3001 return (res);
3002 }
3003 if (obj->needed_aux_filtees != NULL) {
3004 load_filtees(__DECONST(Obj_Entry *, obj), 0, req->lockstate);
3005 donelist_init(&donelist);
3006 symlook_init_from_req(&req1, req);
3007 res = symlook_needed(&req1, obj->needed_aux_filtees, &donelist);
3008 if (res == 0) {
3009 req->sym_out = req1.sym_out;
3010 req->defobj_out = req1.defobj_out;
3011 return (res);
3012 }
3013 }
3014 }
3015 return (mres);
3016}
3017
3018static int
3019symlook_obj1(SymLook *req, const Obj_Entry *obj)
3020{
2842 unsigned long symnum;
2843 const Elf_Sym *vsymp;
2844 Elf_Versym verndx;
2845 int vcount;
2846
2847 if (obj->buckets == NULL)
3021 unsigned long symnum;
3022 const Elf_Sym *vsymp;
3023 Elf_Versym verndx;
3024 int vcount;
3025
3026 if (obj->buckets == NULL)
2848 return NULL;
3027 return (ESRCH);
2849
2850 vsymp = NULL;
2851 vcount = 0;
3028
3029 vsymp = NULL;
3030 vcount = 0;
2852 symnum = obj->buckets[hash % obj->nbuckets];
3031 symnum = obj->buckets[req->hash % obj->nbuckets];
2853
2854 for (; symnum != STN_UNDEF; symnum = obj->chains[symnum]) {
2855 const Elf_Sym *symp;
2856 const char *strp;
2857
2858 if (symnum >= obj->nchains)
3032
3033 for (; symnum != STN_UNDEF; symnum = obj->chains[symnum]) {
3034 const Elf_Sym *symp;
3035 const char *strp;
3036
3037 if (symnum >= obj->nchains)
2859 return NULL; /* Bad object */
3038 return (ESRCH); /* Bad object */
2860
2861 symp = obj->symtab + symnum;
2862 strp = obj->strtab + symp->st_name;
2863
2864 switch (ELF_ST_TYPE(symp->st_info)) {
2865 case STT_FUNC:
2866 case STT_NOTYPE:
2867 case STT_OBJECT:
2868 if (symp->st_value == 0)
2869 continue;
2870 /* fallthrough */
2871 case STT_TLS:
2872 if (symp->st_shndx != SHN_UNDEF)
2873 break;
2874#ifndef __mips__
3039
3040 symp = obj->symtab + symnum;
3041 strp = obj->strtab + symp->st_name;
3042
3043 switch (ELF_ST_TYPE(symp->st_info)) {
3044 case STT_FUNC:
3045 case STT_NOTYPE:
3046 case STT_OBJECT:
3047 if (symp->st_value == 0)
3048 continue;
3049 /* fallthrough */
3050 case STT_TLS:
3051 if (symp->st_shndx != SHN_UNDEF)
3052 break;
3053#ifndef __mips__
2875 else if (((flags & SYMLOOK_IN_PLT) == 0) &&
3054 else if (((req->flags & SYMLOOK_IN_PLT) == 0) &&
2876 (ELF_ST_TYPE(symp->st_info) == STT_FUNC))
2877 break;
2878 /* fallthrough */
2879#endif
2880 default:
2881 continue;
2882 }
3055 (ELF_ST_TYPE(symp->st_info) == STT_FUNC))
3056 break;
3057 /* fallthrough */
3058#endif
3059 default:
3060 continue;
3061 }
2883 if (name[0] != strp[0] || strcmp(name, strp) != 0)
3062 if (req->name[0] != strp[0] || strcmp(req->name, strp) != 0)
2884 continue;
2885
3063 continue;
3064
2886 if (ventry == NULL) {
3065 if (req->ventry == NULL) {
2887 if (obj->versyms != NULL) {
2888 verndx = VER_NDX(obj->versyms[symnum]);
2889 if (verndx > obj->vernum) {
2890 _rtld_error("%s: symbol %s references wrong version %d",
2891 obj->path, obj->strtab + symnum, verndx);
2892 continue;
2893 }
2894 /*
2895 * If we are not called from dlsym (i.e. this is a normal
3066 if (obj->versyms != NULL) {
3067 verndx = VER_NDX(obj->versyms[symnum]);
3068 if (verndx > obj->vernum) {
3069 _rtld_error("%s: symbol %s references wrong version %d",
3070 obj->path, obj->strtab + symnum, verndx);
3071 continue;
3072 }
3073 /*
3074 * If we are not called from dlsym (i.e. this is a normal
2896 * relocation from unversioned binary, accept the symbol
3075 * relocation from unversioned binary), accept the symbol
2897 * immediately if it happens to have first version after
2898 * this shared object became versioned. Otherwise, if
2899 * symbol is versioned and not hidden, remember it. If it
2900 * is the only symbol with this name exported by the
2901 * shared object, it will be returned as a match at the
2902 * end of the function. If symbol is global (verndx < 2)
2903 * accept it unconditionally.
2904 */
3076 * immediately if it happens to have first version after
3077 * this shared object became versioned. Otherwise, if
3078 * symbol is versioned and not hidden, remember it. If it
3079 * is the only symbol with this name exported by the
3080 * shared object, it will be returned as a match at the
3081 * end of the function. If symbol is global (verndx < 2)
3082 * accept it unconditionally.
3083 */
2905 if ((flags & SYMLOOK_DLSYM) == 0 && verndx == VER_NDX_GIVEN)
2906 return symp;
2907 else if (verndx >= VER_NDX_GIVEN) {
3084 if ((req->flags & SYMLOOK_DLSYM) == 0 &&
3085 verndx == VER_NDX_GIVEN) {
3086 req->sym_out = symp;
3087 req->defobj_out = obj;
3088 return (0);
3089 }
3090 else if (verndx >= VER_NDX_GIVEN) {
2908 if ((obj->versyms[symnum] & VER_NDX_HIDDEN) == 0) {
2909 if (vsymp == NULL)
2910 vsymp = symp;
2911 vcount ++;
2912 }
2913 continue;
2914 }
2915 }
3091 if ((obj->versyms[symnum] & VER_NDX_HIDDEN) == 0) {
3092 if (vsymp == NULL)
3093 vsymp = symp;
3094 vcount ++;
3095 }
3096 continue;
3097 }
3098 }
2916 return symp;
3099 req->sym_out = symp;
3100 req->defobj_out = obj;
3101 return (0);
2917 } else {
2918 if (obj->versyms == NULL) {
3102 } else {
3103 if (obj->versyms == NULL) {
2919 if (object_match_name(obj, ventry->name)) {
3104 if (object_match_name(obj, req->ventry->name)) {
2920 _rtld_error("%s: object %s should provide version %s for "
3105 _rtld_error("%s: object %s should provide version %s for "
2921 "symbol %s", obj_rtld.path, obj->path, ventry->name,
2922 obj->strtab + symnum);
3106 "symbol %s", obj_rtld.path, obj->path,
3107 req->ventry->name, obj->strtab + symnum);
2923 continue;
2924 }
2925 } else {
2926 verndx = VER_NDX(obj->versyms[symnum]);
2927 if (verndx > obj->vernum) {
2928 _rtld_error("%s: symbol %s references wrong version %d",
2929 obj->path, obj->strtab + symnum, verndx);
2930 continue;
2931 }
3108 continue;
3109 }
3110 } else {
3111 verndx = VER_NDX(obj->versyms[symnum]);
3112 if (verndx > obj->vernum) {
3113 _rtld_error("%s: symbol %s references wrong version %d",
3114 obj->path, obj->strtab + symnum, verndx);
3115 continue;
3116 }
2932 if (obj->vertab[verndx].hash != ventry->hash ||
2933 strcmp(obj->vertab[verndx].name, ventry->name)) {
3117 if (obj->vertab[verndx].hash != req->ventry->hash ||
3118 strcmp(obj->vertab[verndx].name, req->ventry->name)) {
2934 /*
2935 * Version does not match. Look if this is a global symbol
2936 * and if it is not hidden. If global symbol (verndx < 2)
2937 * is available, use it. Do not return symbol if we are
2938 * called by dlvsym, because dlvsym looks for a specific
2939 * version and default one is not what dlvsym wants.
2940 */
3119 /*
3120 * Version does not match. Look if this is a global symbol
3121 * and if it is not hidden. If global symbol (verndx < 2)
3122 * is available, use it. Do not return symbol if we are
3123 * called by dlvsym, because dlvsym looks for a specific
3124 * version and default one is not what dlvsym wants.
3125 */
2941 if ((flags & SYMLOOK_DLSYM) ||
3126 if ((req->flags & SYMLOOK_DLSYM) ||
2942 (obj->versyms[symnum] & VER_NDX_HIDDEN) ||
2943 (verndx >= VER_NDX_GIVEN))
2944 continue;
2945 }
2946 }
3127 (obj->versyms[symnum] & VER_NDX_HIDDEN) ||
3128 (verndx >= VER_NDX_GIVEN))
3129 continue;
3130 }
3131 }
2947 return symp;
3132 req->sym_out = symp;
3133 req->defobj_out = obj;
3134 return (0);
2948 }
2949 }
3135 }
3136 }
2950 return (vcount == 1) ? vsymp : NULL;
3137 if (vcount == 1) {
3138 req->sym_out = vsymp;
3139 req->defobj_out = obj;
3140 return (0);
3141 }
3142 return (ESRCH);
2951}
2952
2953static void
2954trace_loaded_objects(Obj_Entry *obj)
2955{
2956 char *fmt1, *fmt2, *fmt, *main_local, *list_containers;
2957 int c;
2958

--- 107 unchanged lines hidden (view full) ---

3066
3067 /* Unmap all objects that are no longer referenced. */
3068 linkp = &obj_list->next;
3069 while ((obj = *linkp) != NULL) {
3070 if (obj->refcount == 0) {
3071 LD_UTRACE(UTRACE_UNLOAD_OBJECT, obj, obj->mapbase, obj->mapsize, 0,
3072 obj->path);
3073 dbg("unloading \"%s\"", obj->path);
3143}
3144
3145static void
3146trace_loaded_objects(Obj_Entry *obj)
3147{
3148 char *fmt1, *fmt2, *fmt, *main_local, *list_containers;
3149 int c;
3150

--- 107 unchanged lines hidden (view full) ---

3258
3259 /* Unmap all objects that are no longer referenced. */
3260 linkp = &obj_list->next;
3261 while ((obj = *linkp) != NULL) {
3262 if (obj->refcount == 0) {
3263 LD_UTRACE(UTRACE_UNLOAD_OBJECT, obj, obj->mapbase, obj->mapsize, 0,
3264 obj->path);
3265 dbg("unloading \"%s\"", obj->path);
3266 unload_filtees(root);
3074 munmap(obj->mapbase, obj->mapsize);
3075 linkmap_delete(obj);
3076 *linkp = obj->next;
3077 obj_count--;
3078 obj_free(obj);
3079 } else
3080 linkp = &obj->next;
3081 }

--- 40 unchanged lines hidden (view full) ---

3122
3123/*
3124 * Common code for MD __tls_get_addr().
3125 */
3126void *
3127tls_get_addr_common(Elf_Addr** dtvp, int index, size_t offset)
3128{
3129 Elf_Addr* dtv = *dtvp;
3267 munmap(obj->mapbase, obj->mapsize);
3268 linkmap_delete(obj);
3269 *linkp = obj->next;
3270 obj_count--;
3271 obj_free(obj);
3272 } else
3273 linkp = &obj->next;
3274 }

--- 40 unchanged lines hidden (view full) ---

3315
3316/*
3317 * Common code for MD __tls_get_addr().
3318 */
3319void *
3320tls_get_addr_common(Elf_Addr** dtvp, int index, size_t offset)
3321{
3322 Elf_Addr* dtv = *dtvp;
3130 int lockstate;
3323 RtldLockState lockstate;
3131
3132 /* Check dtv generation in case new modules have arrived */
3133 if (dtv[0] != tls_dtv_generation) {
3134 Elf_Addr* newdtv;
3135 int to_copy;
3136
3324
3325 /* Check dtv generation in case new modules have arrived */
3326 if (dtv[0] != tls_dtv_generation) {
3327 Elf_Addr* newdtv;
3328 int to_copy;
3329
3137 lockstate = wlock_acquire(rtld_bind_lock);
3330 wlock_acquire(rtld_bind_lock, &lockstate);
3138 newdtv = calloc(1, (tls_max_index + 2) * sizeof(Elf_Addr));
3139 to_copy = dtv[1];
3140 if (to_copy > tls_max_index)
3141 to_copy = tls_max_index;
3142 memcpy(&newdtv[2], &dtv[2], to_copy * sizeof(Elf_Addr));
3143 newdtv[0] = tls_dtv_generation;
3144 newdtv[1] = tls_max_index;
3145 free(dtv);
3331 newdtv = calloc(1, (tls_max_index + 2) * sizeof(Elf_Addr));
3332 to_copy = dtv[1];
3333 if (to_copy > tls_max_index)
3334 to_copy = tls_max_index;
3335 memcpy(&newdtv[2], &dtv[2], to_copy * sizeof(Elf_Addr));
3336 newdtv[0] = tls_dtv_generation;
3337 newdtv[1] = tls_max_index;
3338 free(dtv);
3146 wlock_release(rtld_bind_lock, lockstate);
3339 lock_release(rtld_bind_lock, &lockstate);
3147 *dtvp = newdtv;
3148 }
3149
3150 /* Dynamically allocate module TLS if necessary */
3151 if (!dtv[index + 1]) {
3152 /* Signal safe, wlock will block out signals. */
3340 *dtvp = newdtv;
3341 }
3342
3343 /* Dynamically allocate module TLS if necessary */
3344 if (!dtv[index + 1]) {
3345 /* Signal safe, wlock will block out signals. */
3153 lockstate = wlock_acquire(rtld_bind_lock);
3346 wlock_acquire(rtld_bind_lock, &lockstate);
3154 if (!dtv[index + 1])
3155 dtv[index + 1] = (Elf_Addr)allocate_module_tls(index);
3347 if (!dtv[index + 1])
3348 dtv[index + 1] = (Elf_Addr)allocate_module_tls(index);
3156 wlock_release(rtld_bind_lock, lockstate);
3349 lock_release(rtld_bind_lock, &lockstate);
3157 }
3158 return (void*) (dtv[index + 1] + offset);
3159}
3160
3161/* XXX not sure what variants to use for arm. */
3162
3163#if defined(__ia64__) || defined(__powerpc__)
3164

--- 259 unchanged lines hidden (view full) ---

3424 tls_last_size = 0;
3425 }
3426}
3427
3428void *
3429_rtld_allocate_tls(void *oldtls, size_t tcbsize, size_t tcbalign)
3430{
3431 void *ret;
3350 }
3351 return (void*) (dtv[index + 1] + offset);
3352}
3353
3354/* XXX not sure what variants to use for arm. */
3355
3356#if defined(__ia64__) || defined(__powerpc__)
3357

--- 259 unchanged lines hidden (view full) ---

3617 tls_last_size = 0;
3618 }
3619}
3620
3621void *
3622_rtld_allocate_tls(void *oldtls, size_t tcbsize, size_t tcbalign)
3623{
3624 void *ret;
3432 int lockstate;
3625 RtldLockState lockstate;
3433
3626
3434 lockstate = wlock_acquire(rtld_bind_lock);
3627 wlock_acquire(rtld_bind_lock, &lockstate);
3435 ret = allocate_tls(obj_list, oldtls, tcbsize, tcbalign);
3628 ret = allocate_tls(obj_list, oldtls, tcbsize, tcbalign);
3436 wlock_release(rtld_bind_lock, lockstate);
3629 lock_release(rtld_bind_lock, &lockstate);
3437 return (ret);
3438}
3439
3440void
3441_rtld_free_tls(void *tcb, size_t tcbsize, size_t tcbalign)
3442{
3630 return (ret);
3631}
3632
3633void
3634_rtld_free_tls(void *tcb, size_t tcbsize, size_t tcbalign)
3635{
3443 int lockstate;
3636 RtldLockState lockstate;
3444
3637
3445 lockstate = wlock_acquire(rtld_bind_lock);
3638 wlock_acquire(rtld_bind_lock, &lockstate);
3446 free_tls(tcb, tcbsize, tcbalign);
3639 free_tls(tcb, tcbsize, tcbalign);
3447 wlock_release(rtld_bind_lock, lockstate);
3640 lock_release(rtld_bind_lock, &lockstate);
3448}
3449
3450static void
3451object_add_name(Obj_Entry *obj, const char *name)
3452{
3453 Name_Entry *entry;
3454 size_t len;
3455

--- 218 unchanged lines hidden (view full) ---

3674 obj->path, obj->strtab + symnum, vernum);
3675 } else if (obj->vertab[vernum].hash != 0) {
3676 return &obj->vertab[vernum];
3677 }
3678 }
3679 return NULL;
3680}
3681
3641}
3642
3643static void
3644object_add_name(Obj_Entry *obj, const char *name)
3645{
3646 Name_Entry *entry;
3647 size_t len;
3648

--- 218 unchanged lines hidden (view full) ---

3867 obj->path, obj->strtab + symnum, vernum);
3868 } else if (obj->vertab[vernum].hash != 0) {
3869 return &obj->vertab[vernum];
3870 }
3871 }
3872 return NULL;
3873}
3874
3875void
3876symlook_init(SymLook *dst, const char *name)
3877{
3878
3879 bzero(dst, sizeof(*dst));
3880 dst->name = name;
3881 dst->hash = elf_hash(name);
3882}
3883
3884static void
3885symlook_init_from_req(SymLook *dst, const SymLook *src)
3886{
3887
3888 dst->name = src->name;
3889 dst->hash = src->hash;
3890 dst->ventry = src->ventry;
3891 dst->flags = src->flags;
3892 dst->defobj_out = NULL;
3893 dst->sym_out = NULL;
3894 dst->lockstate = src->lockstate;
3895}
3896
3682/*
3683 * Overrides for libc_pic-provided functions.
3684 */
3685
3686int
3687__getosreldate(void)
3688{
3689 size_t len;

--- 23 unchanged lines hidden ---
3897/*
3898 * Overrides for libc_pic-provided functions.
3899 */
3900
3901int
3902__getosreldate(void)
3903{
3904 size_t len;

--- 23 unchanged lines hidden ---