Optimize out an unneeded bzero().
[dragonfly.git] / libexec / rtld-elf / rtld.c
... / ...
CommitLineData
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 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
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: src/libexec/rtld-elf/rtld.c,v 1.43.2.15 2003/02/20 20:42:46 kan Exp $
27 * $DragonFly: src/libexec/rtld-elf/rtld.c,v 1.2 2003/06/17 04:27:08 dillon Exp $
28 */
29
30/*
31 * Dynamic linker for ELF.
32 *
33 * John Polstra <jdp@polstra.com>.
34 */
35
36#ifndef __GNUC__
37#error "GCC is needed to compile this file"
38#endif
39
40#include <sys/param.h>
41#include <sys/mman.h>
42#include <sys/stat.h>
43
44#include <dlfcn.h>
45#include <err.h>
46#include <errno.h>
47#include <fcntl.h>
48#include <stdarg.h>
49#include <stdio.h>
50#include <stdlib.h>
51#include <string.h>
52#include <unistd.h>
53
54#include "debug.h"
55#include "rtld.h"
56
57#define END_SYM "_end"
58#define PATH_RTLD "/usr/libexec/ld-elf.so.1"
59
60/* Types. */
61typedef void (*func_ptr_type)();
62typedef void * (*path_enum_proc) (const char *path, size_t len, void *arg);
63
64/*
65 * This structure provides a reentrant way to keep a list of objects and
66 * check which ones have already been processed in some way.
67 */
68typedef struct Struct_DoneList {
69 const Obj_Entry **objs; /* Array of object pointers */
70 unsigned int num_alloc; /* Allocated size of the array */
71 unsigned int num_used; /* Number of array slots used */
72} DoneList;
73
74/*
75 * Function declarations.
76 */
77static const char *basename(const char *);
78static void die(void);
79static void digest_dynamic(Obj_Entry *);
80static Obj_Entry *digest_phdr(const Elf_Phdr *, int, caddr_t, const char *);
81static Obj_Entry *dlcheck(void *);
82static int do_search_info(const Obj_Entry *obj, int, struct dl_serinfo *);
83static bool donelist_check(DoneList *, const Obj_Entry *);
84static void errmsg_restore(char *);
85static char *errmsg_save(void);
86static void *fill_search_info(const char *, size_t, void *);
87static char *find_library(const char *, const Obj_Entry *);
88static const char *gethints(void);
89static void init_dag(Obj_Entry *);
90static void init_dag1(Obj_Entry *root, Obj_Entry *obj, DoneList *);
91static void init_rtld(caddr_t);
92static void initlist_add_neededs(Needed_Entry *needed, Objlist *list);
93static void initlist_add_objects(Obj_Entry *obj, Obj_Entry **tail,
94 Objlist *list);
95static bool is_exported(const Elf_Sym *);
96static void linkmap_add(Obj_Entry *);
97static void linkmap_delete(Obj_Entry *);
98static int load_needed_objects(Obj_Entry *);
99static int load_preload_objects(void);
100static Obj_Entry *load_object(char *);
101static void lock_check(void);
102static Obj_Entry *obj_from_addr(const void *);
103static void objlist_call_fini(Objlist *);
104static void objlist_call_init(Objlist *);
105static void objlist_clear(Objlist *);
106static Objlist_Entry *objlist_find(Objlist *, const Obj_Entry *);
107static void objlist_init(Objlist *);
108static void objlist_push_head(Objlist *, Obj_Entry *);
109static void objlist_push_tail(Objlist *, Obj_Entry *);
110static void objlist_remove(Objlist *, Obj_Entry *);
111static void objlist_remove_unref(Objlist *);
112static void *path_enumerate(const char *, path_enum_proc, void *);
113static int relocate_objects(Obj_Entry *, bool);
114static int rtld_dirname(const char *, char *);
115static void rtld_exit(void);
116static char *search_library_path(const char *, const char *);
117static const void **get_program_var_addr(const char *name);
118static void set_program_var(const char *, const void *);
119static const Elf_Sym *symlook_default(const char *, unsigned long hash,
120 const Obj_Entry *refobj, const Obj_Entry **defobj_out, bool in_plt);
121static const Elf_Sym *symlook_list(const char *, unsigned long,
122 Objlist *, const Obj_Entry **, bool in_plt, DoneList *);
123static void trace_loaded_objects(Obj_Entry *obj);
124static void unlink_object(Obj_Entry *);
125static void unload_object(Obj_Entry *);
126static void unref_dag(Obj_Entry *);
127
128void r_debug_state(struct r_debug*, struct link_map*);
129
130/*
131 * Data declarations.
132 */
133static char *error_message; /* Message for dlerror(), or NULL */
134struct r_debug r_debug; /* for GDB; */
135static bool trust; /* False for setuid and setgid programs */
136static char *ld_bind_now; /* Environment variable for immediate binding */
137static char *ld_debug; /* Environment variable for debugging */
138static char *ld_library_path; /* Environment variable for search path */
139static char *ld_preload; /* Environment variable for libraries to
140 load first */
141static char *ld_tracing; /* Called from ldd to print libs */
142static Obj_Entry *obj_list; /* Head of linked list of shared objects */
143static Obj_Entry **obj_tail; /* Link field of last object in list */
144static Obj_Entry *obj_main; /* The main program shared object */
145static Obj_Entry obj_rtld; /* The dynamic linker shared object */
146static unsigned int obj_count; /* Number of objects in obj_list */
147
148static Objlist list_global = /* Objects dlopened with RTLD_GLOBAL */
149 STAILQ_HEAD_INITIALIZER(list_global);
150static Objlist list_main = /* Objects loaded at program startup */
151 STAILQ_HEAD_INITIALIZER(list_main);
152static Objlist list_fini = /* Objects needing fini() calls */
153 STAILQ_HEAD_INITIALIZER(list_fini);
154
155static LockInfo lockinfo;
156
157static Elf_Sym sym_zero; /* For resolving undefined weak refs. */
158
159#define GDB_STATE(s,m) r_debug.r_state = s; r_debug_state(&r_debug,m);
160
161extern Elf_Dyn _DYNAMIC;
162#pragma weak _DYNAMIC
163
164/*
165 * These are the functions the dynamic linker exports to application
166 * programs. They are the only symbols the dynamic linker is willing
167 * to export from itself.
168 */
169static func_ptr_type exports[] = {
170 (func_ptr_type) &_rtld_error,
171 (func_ptr_type) &dlclose,
172 (func_ptr_type) &dlerror,
173 (func_ptr_type) &dlopen,
174 (func_ptr_type) &dlsym,
175 (func_ptr_type) &dladdr,
176 (func_ptr_type) &dllockinit,
177 (func_ptr_type) &dlinfo,
178 NULL
179};
180
181/*
182 * Global declarations normally provided by crt1. The dynamic linker is
183 * not built with crt1, so we have to provide them ourselves.
184 */
185char *__progname;
186char **environ;
187
188/*
189 * Fill in a DoneList with an allocation large enough to hold all of
190 * the currently-loaded objects. Keep this as a macro since it calls
191 * alloca and we want that to occur within the scope of the caller.
192 */
193#define donelist_init(dlp) \
194 ((dlp)->objs = alloca(obj_count * sizeof (dlp)->objs[0]), \
195 assert((dlp)->objs != NULL), \
196 (dlp)->num_alloc = obj_count, \
197 (dlp)->num_used = 0)
198
199static __inline void
200rlock_acquire(void)
201{
202 lockinfo.rlock_acquire(lockinfo.thelock);
203 atomic_incr_int(&lockinfo.rcount);
204 lock_check();
205}
206
207static __inline void
208wlock_acquire(void)
209{
210 lockinfo.wlock_acquire(lockinfo.thelock);
211 atomic_incr_int(&lockinfo.wcount);
212 lock_check();
213}
214
215static __inline void
216rlock_release(void)
217{
218 atomic_decr_int(&lockinfo.rcount);
219 lockinfo.rlock_release(lockinfo.thelock);
220}
221
222static __inline void
223wlock_release(void)
224{
225 atomic_decr_int(&lockinfo.wcount);
226 lockinfo.wlock_release(lockinfo.thelock);
227}
228
229/*
230 * Main entry point for dynamic linking. The first argument is the
231 * stack pointer. The stack is expected to be laid out as described
232 * in the SVR4 ABI specification, Intel 386 Processor Supplement.
233 * Specifically, the stack pointer points to a word containing
234 * ARGC. Following that in the stack is a null-terminated sequence
235 * of pointers to argument strings. Then comes a null-terminated
236 * sequence of pointers to environment strings. Finally, there is a
237 * sequence of "auxiliary vector" entries.
238 *
239 * The second argument points to a place to store the dynamic linker's
240 * exit procedure pointer and the third to a place to store the main
241 * program's object.
242 *
243 * The return value is the main program's entry point.
244 */
245func_ptr_type
246_rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
247{
248 Elf_Auxinfo *aux_info[AT_COUNT];
249 int i;
250 int argc;
251 char **argv;
252 char **env;
253 Elf_Auxinfo *aux;
254 Elf_Auxinfo *auxp;
255 const char *argv0;
256 Obj_Entry *obj;
257 Obj_Entry **preload_tail;
258 Objlist initlist;
259
260 /*
261 * On entry, the dynamic linker itself has not been relocated yet.
262 * Be very careful not to reference any global data until after
263 * init_rtld has returned. It is OK to reference file-scope statics
264 * and string constants, and to call static and global functions.
265 */
266
267 /* Find the auxiliary vector on the stack. */
268 argc = *sp++;
269 argv = (char **) sp;
270 sp += argc + 1; /* Skip over arguments and NULL terminator */
271 env = (char **) sp;
272 while (*sp++ != 0) /* Skip over environment, and NULL terminator */
273 ;
274 aux = (Elf_Auxinfo *) sp;
275
276 /* Digest the auxiliary vector. */
277 for (i = 0; i < AT_COUNT; i++)
278 aux_info[i] = NULL;
279 for (auxp = aux; auxp->a_type != AT_NULL; auxp++) {
280 if (auxp->a_type < AT_COUNT)
281 aux_info[auxp->a_type] = auxp;
282 }
283
284 /* Initialize and relocate ourselves. */
285 assert(aux_info[AT_BASE] != NULL);
286 init_rtld((caddr_t) aux_info[AT_BASE]->a_un.a_ptr);
287
288 __progname = obj_rtld.path;
289 argv0 = argv[0] != NULL ? argv[0] : "(null)";
290 environ = env;
291
292 trust = geteuid() == getuid() && getegid() == getgid();
293
294 ld_bind_now = getenv("LD_BIND_NOW");
295 if (trust) {
296 ld_debug = getenv("LD_DEBUG");
297 ld_library_path = getenv("LD_LIBRARY_PATH");
298 ld_preload = getenv("LD_PRELOAD");
299 }
300 ld_tracing = getenv("LD_TRACE_LOADED_OBJECTS");
301
302 if (ld_debug != NULL && *ld_debug != '\0')
303 debug = 1;
304 dbg("%s is initialized, base address = %p", __progname,
305 (caddr_t) aux_info[AT_BASE]->a_un.a_ptr);
306 dbg("RTLD dynamic = %p", obj_rtld.dynamic);
307 dbg("RTLD pltgot = %p", obj_rtld.pltgot);
308
309 /*
310 * Load the main program, or process its program header if it is
311 * already loaded.
312 */
313 if (aux_info[AT_EXECFD] != NULL) { /* Load the main program. */
314 int fd = aux_info[AT_EXECFD]->a_un.a_val;
315 dbg("loading main program");
316 obj_main = map_object(fd, argv0, NULL);
317 close(fd);
318 if (obj_main == NULL)
319 die();
320 } else { /* Main program already loaded. */
321 const Elf_Phdr *phdr;
322 int phnum;
323 caddr_t entry;
324
325 dbg("processing main program's program header");
326 assert(aux_info[AT_PHDR] != NULL);
327 phdr = (const Elf_Phdr *) aux_info[AT_PHDR]->a_un.a_ptr;
328 assert(aux_info[AT_PHNUM] != NULL);
329 phnum = aux_info[AT_PHNUM]->a_un.a_val;
330 assert(aux_info[AT_PHENT] != NULL);
331 assert(aux_info[AT_PHENT]->a_un.a_val == sizeof(Elf_Phdr));
332 assert(aux_info[AT_ENTRY] != NULL);
333 entry = (caddr_t) aux_info[AT_ENTRY]->a_un.a_ptr;
334 if ((obj_main = digest_phdr(phdr, phnum, entry, argv0)) == NULL)
335 die();
336 }
337
338 obj_main->path = xstrdup(argv0);
339 obj_main->mainprog = true;
340
341 /*
342 * Get the actual dynamic linker pathname from the executable if
343 * possible. (It should always be possible.) That ensures that
344 * gdb will find the right dynamic linker even if a non-standard
345 * one is being used.
346 */
347 if (obj_main->interp != NULL &&
348 strcmp(obj_main->interp, obj_rtld.path) != 0) {
349 free(obj_rtld.path);
350 obj_rtld.path = xstrdup(obj_main->interp);
351 }
352
353 digest_dynamic(obj_main);
354
355 linkmap_add(obj_main);
356 linkmap_add(&obj_rtld);
357
358 /* Link the main program into the list of objects. */
359 *obj_tail = obj_main;
360 obj_tail = &obj_main->next;
361 obj_count++;
362 obj_main->refcount++;
363 /* Make sure we don't call the main program's init and fini functions. */
364 obj_main->init = obj_main->fini = NULL;
365
366 /* Initialize a fake symbol for resolving undefined weak references. */
367 sym_zero.st_info = ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE);
368 sym_zero.st_shndx = SHN_ABS;
369
370 dbg("loading LD_PRELOAD libraries");
371 if (load_preload_objects() == -1)
372 die();
373 preload_tail = obj_tail;
374
375 dbg("loading needed objects");
376 if (load_needed_objects(obj_main) == -1)
377 die();
378
379 /* Make a list of all objects loaded at startup. */
380 for (obj = obj_list; obj != NULL; obj = obj->next)
381 objlist_push_tail(&list_main, obj);
382
383 if (ld_tracing) { /* We're done */
384 trace_loaded_objects(obj_main);
385 exit(0);
386 }
387
388 if (relocate_objects(obj_main,
389 ld_bind_now != NULL && *ld_bind_now != '\0') == -1)
390 die();
391
392 dbg("doing copy relocations");
393 if (do_copy_relocations(obj_main) == -1)
394 die();
395
396 dbg("initializing key program variables");
397 set_program_var("__progname", argv[0] != NULL ? basename(argv[0]) : "");
398 set_program_var("environ", env);
399
400 dbg("initializing thread locks");
401 lockdflt_init(&lockinfo);
402 lockinfo.thelock = lockinfo.lock_create(lockinfo.context);
403
404 /* Make a list of init functions to call. */
405 objlist_init(&initlist);
406 initlist_add_objects(obj_list, preload_tail, &initlist);
407
408 r_debug_state(NULL, &obj_main->linkmap); /* say hello to gdb! */
409
410 objlist_call_init(&initlist);
411 wlock_acquire();
412 objlist_clear(&initlist);
413 wlock_release();
414
415 dbg("transferring control to program entry point = %p", obj_main->entry);
416
417 /* Return the exit procedure and the program entry point. */
418 *exit_proc = rtld_exit;
419 *objp = obj_main;
420 return (func_ptr_type) obj_main->entry;
421}
422
423Elf_Addr
424_rtld_bind(Obj_Entry *obj, Elf_Word reloff)
425{
426 const Elf_Rel *rel;
427 const Elf_Sym *def;
428 const Obj_Entry *defobj;
429 Elf_Addr *where;
430 Elf_Addr target;
431
432 rlock_acquire();
433 if (obj->pltrel)
434 rel = (const Elf_Rel *) ((caddr_t) obj->pltrel + reloff);
435 else
436 rel = (const Elf_Rel *) ((caddr_t) obj->pltrela + reloff);
437
438 where = (Elf_Addr *) (obj->relocbase + rel->r_offset);
439 def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, true, NULL);
440 if (def == NULL)
441 die();
442
443 target = (Elf_Addr)(defobj->relocbase + def->st_value);
444
445 dbg("\"%s\" in \"%s\" ==> %p in \"%s\"",
446 defobj->strtab + def->st_name, basename(obj->path),
447 (void *)target, basename(defobj->path));
448
449 reloc_jmpslot(where, target);
450 rlock_release();
451 return target;
452}
453
454/*
455 * Error reporting function. Use it like printf. If formats the message
456 * into a buffer, and sets things up so that the next call to dlerror()
457 * will return the message.
458 */
459void
460_rtld_error(const char *fmt, ...)
461{
462 static char buf[512];
463 va_list ap;
464
465 va_start(ap, fmt);
466 vsnprintf(buf, sizeof buf, fmt, ap);
467 error_message = buf;
468 va_end(ap);
469}
470
471/*
472 * Return a dynamically-allocated copy of the current error message, if any.
473 */
474static char *
475errmsg_save(void)
476{
477 return error_message == NULL ? NULL : xstrdup(error_message);
478}
479
480/*
481 * Restore the current error message from a copy which was previously saved
482 * by errmsg_save(). The copy is freed.
483 */
484static void
485errmsg_restore(char *saved_msg)
486{
487 if (saved_msg == NULL)
488 error_message = NULL;
489 else {
490 _rtld_error("%s", saved_msg);
491 free(saved_msg);
492 }
493}
494
495static const char *
496basename(const char *name)
497{
498 const char *p = strrchr(name, '/');
499 return p != NULL ? p + 1 : name;
500}
501
502static void
503die(void)
504{
505 const char *msg = dlerror();
506
507 if (msg == NULL)
508 msg = "Fatal error";
509 errx(1, "%s", msg);
510}
511
512/*
513 * Process a shared object's DYNAMIC section, and save the important
514 * information in its Obj_Entry structure.
515 */
516static void
517digest_dynamic(Obj_Entry *obj)
518{
519 const Elf_Dyn *dynp;
520 Needed_Entry **needed_tail = &obj->needed;
521 const Elf_Dyn *dyn_rpath = NULL;
522 int plttype = DT_REL;
523
524 for (dynp = obj->dynamic; dynp->d_tag != DT_NULL; dynp++) {
525 switch (dynp->d_tag) {
526
527 case DT_REL:
528 obj->rel = (const Elf_Rel *) (obj->relocbase + dynp->d_un.d_ptr);
529 break;
530
531 case DT_RELSZ:
532 obj->relsize = dynp->d_un.d_val;
533 break;
534
535 case DT_RELENT:
536 assert(dynp->d_un.d_val == sizeof(Elf_Rel));
537 break;
538
539 case DT_JMPREL:
540 obj->pltrel = (const Elf_Rel *)
541 (obj->relocbase + dynp->d_un.d_ptr);
542 break;
543
544 case DT_PLTRELSZ:
545 obj->pltrelsize = dynp->d_un.d_val;
546 break;
547
548 case DT_RELA:
549 obj->rela = (const Elf_Rela *) (obj->relocbase + dynp->d_un.d_ptr);
550 break;
551
552 case DT_RELASZ:
553 obj->relasize = dynp->d_un.d_val;
554 break;
555
556 case DT_RELAENT:
557 assert(dynp->d_un.d_val == sizeof(Elf_Rela));
558 break;
559
560 case DT_PLTREL:
561 plttype = dynp->d_un.d_val;
562 assert(dynp->d_un.d_val == DT_REL || plttype == DT_RELA);
563 break;
564
565 case DT_SYMTAB:
566 obj->symtab = (const Elf_Sym *)
567 (obj->relocbase + dynp->d_un.d_ptr);
568 break;
569
570 case DT_SYMENT:
571 assert(dynp->d_un.d_val == sizeof(Elf_Sym));
572 break;
573
574 case DT_STRTAB:
575 obj->strtab = (const char *) (obj->relocbase + dynp->d_un.d_ptr);
576 break;
577
578 case DT_STRSZ:
579 obj->strsize = dynp->d_un.d_val;
580 break;
581
582 case DT_HASH:
583 {
584 const Elf_Addr *hashtab = (const Elf_Addr *)
585 (obj->relocbase + dynp->d_un.d_ptr);
586 obj->nbuckets = hashtab[0];
587 obj->nchains = hashtab[1];
588 obj->buckets = hashtab + 2;
589 obj->chains = obj->buckets + obj->nbuckets;
590 }
591 break;
592
593 case DT_NEEDED:
594 if (!obj->rtld) {
595 Needed_Entry *nep = NEW(Needed_Entry);
596 nep->name = dynp->d_un.d_val;
597 nep->obj = NULL;
598 nep->next = NULL;
599
600 *needed_tail = nep;
601 needed_tail = &nep->next;
602 }
603 break;
604
605 case DT_PLTGOT:
606 obj->pltgot = (Elf_Addr *) (obj->relocbase + dynp->d_un.d_ptr);
607 break;
608
609 case DT_TEXTREL:
610 obj->textrel = true;
611 break;
612
613 case DT_SYMBOLIC:
614 obj->symbolic = true;
615 break;
616
617 case DT_RPATH:
618 /*
619 * We have to wait until later to process this, because we
620 * might not have gotten the address of the string table yet.
621 */
622 dyn_rpath = dynp;
623 break;
624
625 case DT_SONAME:
626 /* Not used by the dynamic linker. */
627 break;
628
629 case DT_INIT:
630 obj->init = (InitFunc) (obj->relocbase + dynp->d_un.d_ptr);
631 break;
632
633 case DT_FINI:
634 obj->fini = (InitFunc) (obj->relocbase + dynp->d_un.d_ptr);
635 break;
636
637 case DT_DEBUG:
638 /* XXX - not implemented yet */
639 dbg("Filling in DT_DEBUG entry");
640 ((Elf_Dyn*)dynp)->d_un.d_ptr = (Elf_Addr) &r_debug;
641 break;
642
643 default:
644 dbg("Ignoring d_tag %d = %#x", dynp->d_tag, dynp->d_tag);
645 break;
646 }
647 }
648
649 obj->traced = false;
650
651 if (plttype == DT_RELA) {
652 obj->pltrela = (const Elf_Rela *) obj->pltrel;
653 obj->pltrel = NULL;
654 obj->pltrelasize = obj->pltrelsize;
655 obj->pltrelsize = 0;
656 }
657
658 if (dyn_rpath != NULL)
659 obj->rpath = obj->strtab + dyn_rpath->d_un.d_val;
660}
661
662/*
663 * Process a shared object's program header. This is used only for the
664 * main program, when the kernel has already loaded the main program
665 * into memory before calling the dynamic linker. It creates and
666 * returns an Obj_Entry structure.
667 */
668static Obj_Entry *
669digest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t entry, const char *path)
670{
671 Obj_Entry *obj;
672 const Elf_Phdr *phlimit = phdr + phnum;
673 const Elf_Phdr *ph;
674 int nsegs = 0;
675
676 obj = obj_new();
677 for (ph = phdr; ph < phlimit; ph++) {
678 switch (ph->p_type) {
679
680 case PT_PHDR:
681 if ((const Elf_Phdr *)ph->p_vaddr != phdr) {
682 _rtld_error("%s: invalid PT_PHDR", path);
683 return NULL;
684 }
685 obj->phdr = (const Elf_Phdr *) ph->p_vaddr;
686 obj->phsize = ph->p_memsz;
687 break;
688
689 case PT_INTERP:
690 obj->interp = (const char *) ph->p_vaddr;
691 break;
692
693 case PT_LOAD:
694 if (nsegs == 0) { /* First load segment */
695 obj->vaddrbase = trunc_page(ph->p_vaddr);
696 obj->mapbase = (caddr_t) obj->vaddrbase;
697 obj->relocbase = obj->mapbase - obj->vaddrbase;
698 obj->textsize = round_page(ph->p_vaddr + ph->p_memsz) -
699 obj->vaddrbase;
700 } else { /* Last load segment */
701 obj->mapsize = round_page(ph->p_vaddr + ph->p_memsz) -
702 obj->vaddrbase;
703 }
704 nsegs++;
705 break;
706
707 case PT_DYNAMIC:
708 obj->dynamic = (const Elf_Dyn *) ph->p_vaddr;
709 break;
710 }
711 }
712 if (nsegs < 1) {
713 _rtld_error("%s: too few PT_LOAD segments", path);
714 return NULL;
715 }
716
717 obj->entry = entry;
718 return obj;
719}
720
721static Obj_Entry *
722dlcheck(void *handle)
723{
724 Obj_Entry *obj;
725
726 for (obj = obj_list; obj != NULL; obj = obj->next)
727 if (obj == (Obj_Entry *) handle)
728 break;
729
730 if (obj == NULL || obj->refcount == 0 || obj->dl_refcount == 0) {
731 _rtld_error("Invalid shared object handle %p", handle);
732 return NULL;
733 }
734 return obj;
735}
736
737/*
738 * If the given object is already in the donelist, return true. Otherwise
739 * add the object to the list and return false.
740 */
741static bool
742donelist_check(DoneList *dlp, const Obj_Entry *obj)
743{
744 unsigned int i;
745
746 for (i = 0; i < dlp->num_used; i++)
747 if (dlp->objs[i] == obj)
748 return true;
749 /*
750 * Our donelist allocation should always be sufficient. But if
751 * our threads locking isn't working properly, more shared objects
752 * could have been loaded since we allocated the list. That should
753 * never happen, but we'll handle it properly just in case it does.
754 */
755 if (dlp->num_used < dlp->num_alloc)
756 dlp->objs[dlp->num_used++] = obj;
757 return false;
758}
759
760/*
761 * Hash function for symbol table lookup. Don't even think about changing
762 * this. It is specified by the System V ABI.
763 */
764unsigned long
765elf_hash(const char *name)
766{
767 const unsigned char *p = (const unsigned char *) name;
768 unsigned long h = 0;
769 unsigned long g;
770
771 while (*p != '\0') {
772 h = (h << 4) + *p++;
773 if ((g = h & 0xf0000000) != 0)
774 h ^= g >> 24;
775 h &= ~g;
776 }
777 return h;
778}
779
780/*
781 * Find the library with the given name, and return its full pathname.
782 * The returned string is dynamically allocated. Generates an error
783 * message and returns NULL if the library cannot be found.
784 *
785 * If the second argument is non-NULL, then it refers to an already-
786 * loaded shared object, whose library search path will be searched.
787 *
788 * The search order is:
789 * rpath in the referencing file
790 * LD_LIBRARY_PATH
791 * ldconfig hints
792 * /usr/lib
793 */
794static char *
795find_library(const char *name, const Obj_Entry *refobj)
796{
797 char *pathname;
798
799 if (strchr(name, '/') != NULL) { /* Hard coded pathname */
800 if (name[0] != '/' && !trust) {
801 _rtld_error("Absolute pathname required for shared object \"%s\"",
802 name);
803 return NULL;
804 }
805 return xstrdup(name);
806 }
807
808 dbg(" Searching for \"%s\"", name);
809
810 if ((pathname = search_library_path(name, ld_library_path)) != NULL ||
811 (refobj != NULL &&
812 (pathname = search_library_path(name, refobj->rpath)) != NULL) ||
813 (pathname = search_library_path(name, gethints())) != NULL ||
814 (pathname = search_library_path(name, STANDARD_LIBRARY_PATH)) != NULL)
815 return pathname;
816
817 _rtld_error("Shared object \"%s\" not found", name);
818 return NULL;
819}
820
821/*
822 * Given a symbol number in a referencing object, find the corresponding
823 * definition of the symbol. Returns a pointer to the symbol, or NULL if
824 * no definition was found. Returns a pointer to the Obj_Entry of the
825 * defining object via the reference parameter DEFOBJ_OUT.
826 */
827const Elf_Sym *
828find_symdef(unsigned long symnum, const Obj_Entry *refobj,
829 const Obj_Entry **defobj_out, bool in_plt, SymCache *cache)
830{
831 const Elf_Sym *ref;
832 const Elf_Sym *def;
833 const Obj_Entry *defobj;
834 const char *name;
835 unsigned long hash;
836
837 /*
838 * If we have already found this symbol, get the information from
839 * the cache.
840 */
841 if (symnum >= refobj->nchains)
842 return NULL; /* Bad object */
843 if (cache != NULL && cache[symnum].sym != NULL) {
844 *defobj_out = cache[symnum].obj;
845 return cache[symnum].sym;
846 }
847
848 ref = refobj->symtab + symnum;
849 name = refobj->strtab + ref->st_name;
850 hash = elf_hash(name);
851 defobj = NULL;
852
853 def = symlook_default(name, hash, refobj, &defobj, in_plt);
854
855 /*
856 * If we found no definition and the reference is weak, treat the
857 * symbol as having the value zero.
858 */
859 if (def == NULL && ELF_ST_BIND(ref->st_info) == STB_WEAK) {
860 def = &sym_zero;
861 defobj = obj_main;
862 }
863
864 if (def != NULL) {
865 *defobj_out = defobj;
866 /* Record the information in the cache to avoid subsequent lookups. */
867 if (cache != NULL) {
868 cache[symnum].sym = def;
869 cache[symnum].obj = defobj;
870 }
871 } else
872 _rtld_error("%s: Undefined symbol \"%s\"", refobj->path, name);
873 return def;
874}
875
876/*
877 * Return the search path from the ldconfig hints file, reading it if
878 * necessary. Returns NULL if there are problems with the hints file,
879 * or if the search path there is empty.
880 */
881static const char *
882gethints(void)
883{
884 static char *hints;
885
886 if (hints == NULL) {
887 int fd;
888 struct elfhints_hdr hdr;
889 char *p;
890
891 /* Keep from trying again in case the hints file is bad. */
892 hints = "";
893
894 if ((fd = open(_PATH_ELF_HINTS, O_RDONLY)) == -1)
895 return NULL;
896 if (read(fd, &hdr, sizeof hdr) != sizeof hdr ||
897 hdr.magic != ELFHINTS_MAGIC ||
898 hdr.version != 1) {
899 close(fd);
900 return NULL;
901 }
902 p = xmalloc(hdr.dirlistlen + 1);
903 if (lseek(fd, hdr.strtab + hdr.dirlist, SEEK_SET) == -1 ||
904 read(fd, p, hdr.dirlistlen + 1) != hdr.dirlistlen + 1) {
905 free(p);
906 close(fd);
907 return NULL;
908 }
909 hints = p;
910 close(fd);
911 }
912 return hints[0] != '\0' ? hints : NULL;
913}
914
915static void
916init_dag(Obj_Entry *root)
917{
918 DoneList donelist;
919
920 donelist_init(&donelist);
921 init_dag1(root, root, &donelist);
922}
923
924static void
925init_dag1(Obj_Entry *root, Obj_Entry *obj, DoneList *dlp)
926{
927 const Needed_Entry *needed;
928
929 if (donelist_check(dlp, obj))
930 return;
931 objlist_push_tail(&obj->dldags, root);
932 objlist_push_tail(&root->dagmembers, obj);
933 for (needed = obj->needed; needed != NULL; needed = needed->next)
934 if (needed->obj != NULL)
935 init_dag1(root, needed->obj, dlp);
936}
937
938/*
939 * Initialize the dynamic linker. The argument is the address at which
940 * the dynamic linker has been mapped into memory. The primary task of
941 * this function is to relocate the dynamic linker.
942 */
943static void
944init_rtld(caddr_t mapbase)
945{
946 /*
947 * Conjure up an Obj_Entry structure for the dynamic linker.
948 *
949 * The "path" member is supposed to be dynamically-allocated, but we
950 * aren't yet initialized sufficiently to do that. Below we will
951 * replace the static version with a dynamically-allocated copy.
952 */
953 obj_rtld.path = PATH_RTLD;
954 obj_rtld.rtld = true;
955 obj_rtld.mapbase = mapbase;
956#ifdef PIC
957 obj_rtld.relocbase = mapbase;
958#endif
959 if (&_DYNAMIC != 0) {
960 obj_rtld.dynamic = rtld_dynamic(&obj_rtld);
961 digest_dynamic(&obj_rtld);
962 assert(obj_rtld.needed == NULL);
963 assert(!obj_rtld.textrel);
964
965 /*
966 * Temporarily put the dynamic linker entry into the object list, so
967 * that symbols can be found.
968 */
969 obj_list = &obj_rtld;
970 obj_tail = &obj_rtld.next;
971 obj_count = 1;
972
973 relocate_objects(&obj_rtld, true);
974 }
975
976 /* Make the object list empty again. */
977 obj_list = NULL;
978 obj_tail = &obj_list;
979 obj_count = 0;
980
981 /* Replace the path with a dynamically allocated copy. */
982 obj_rtld.path = xstrdup(obj_rtld.path);
983
984 r_debug.r_brk = r_debug_state;
985 r_debug.r_state = RT_CONSISTENT;
986}
987
988/*
989 * Add the init functions from a needed object list (and its recursive
990 * needed objects) to "list". This is not used directly; it is a helper
991 * function for initlist_add_objects(). The write lock must be held
992 * when this function is called.
993 */
994static void
995initlist_add_neededs(Needed_Entry *needed, Objlist *list)
996{
997 /* Recursively process the successor needed objects. */
998 if (needed->next != NULL)
999 initlist_add_neededs(needed->next, list);
1000
1001 /* Process the current needed object. */
1002 if (needed->obj != NULL)
1003 initlist_add_objects(needed->obj, &needed->obj->next, list);
1004}
1005
1006/*
1007 * Scan all of the DAGs rooted in the range of objects from "obj" to
1008 * "tail" and add their init functions to "list". This recurses over
1009 * the DAGs and ensure the proper init ordering such that each object's
1010 * needed libraries are initialized before the object itself. At the
1011 * same time, this function adds the objects to the global finalization
1012 * list "list_fini" in the opposite order. The write lock must be
1013 * held when this function is called.
1014 */
1015static void
1016initlist_add_objects(Obj_Entry *obj, Obj_Entry **tail, Objlist *list)
1017{
1018 if (obj->init_done)
1019 return;
1020 obj->init_done = true;
1021
1022 /* Recursively process the successor objects. */
1023 if (&obj->next != tail)
1024 initlist_add_objects(obj->next, tail, list);
1025
1026 /* Recursively process the needed objects. */
1027 if (obj->needed != NULL)
1028 initlist_add_neededs(obj->needed, list);
1029
1030 /* Add the object to the init list. */
1031 if (obj->init != NULL)
1032 objlist_push_tail(list, obj);
1033
1034 /* Add the object to the global fini list in the reverse order. */
1035 if (obj->fini != NULL)
1036 objlist_push_head(&list_fini, obj);
1037}
1038
1039static bool
1040is_exported(const Elf_Sym *def)
1041{
1042 func_ptr_type value;
1043 const func_ptr_type *p;
1044
1045 value = (func_ptr_type)(obj_rtld.relocbase + def->st_value);
1046 for (p = exports; *p != NULL; p++)
1047 if (*p == value)
1048 return true;
1049 return false;
1050}
1051
1052/*
1053 * Given a shared object, traverse its list of needed objects, and load
1054 * each of them. Returns 0 on success. Generates an error message and
1055 * returns -1 on failure.
1056 */
1057static int
1058load_needed_objects(Obj_Entry *first)
1059{
1060 Obj_Entry *obj;
1061
1062 for (obj = first; obj != NULL; obj = obj->next) {
1063 Needed_Entry *needed;
1064
1065 for (needed = obj->needed; needed != NULL; needed = needed->next) {
1066 const char *name = obj->strtab + needed->name;
1067 char *path = find_library(name, obj);
1068
1069 needed->obj = NULL;
1070 if (path == NULL && !ld_tracing)
1071 return -1;
1072
1073 if (path) {
1074 needed->obj = load_object(path);
1075 if (needed->obj == NULL && !ld_tracing)
1076 return -1; /* XXX - cleanup */
1077 }
1078 }
1079 }
1080
1081 return 0;
1082}
1083
1084static int
1085load_preload_objects(void)
1086{
1087 char *p = ld_preload;
1088 static const char delim[] = " \t:;";
1089
1090 if (p == NULL)
1091 return NULL;
1092
1093 p += strspn(p, delim);
1094 while (*p != '\0') {
1095 size_t len = strcspn(p, delim);
1096 char *path;
1097 char savech;
1098
1099 savech = p[len];
1100 p[len] = '\0';
1101 if ((path = find_library(p, NULL)) == NULL)
1102 return -1;
1103 if (load_object(path) == NULL)
1104 return -1; /* XXX - cleanup */
1105 p[len] = savech;
1106 p += len;
1107 p += strspn(p, delim);
1108 }
1109 return 0;
1110}
1111
1112/*
1113 * Load a shared object into memory, if it is not already loaded. The
1114 * argument must be a string allocated on the heap. This function assumes
1115 * responsibility for freeing it when necessary.
1116 *
1117 * Returns a pointer to the Obj_Entry for the object. Returns NULL
1118 * on failure.
1119 */
1120static Obj_Entry *
1121load_object(char *path)
1122{
1123 Obj_Entry *obj;
1124 int fd = -1;
1125 struct stat sb;
1126
1127 for (obj = obj_list->next; obj != NULL; obj = obj->next)
1128 if (strcmp(obj->path, path) == 0)
1129 break;
1130
1131 /*
1132 * If we didn't find a match by pathname, open the file and check
1133 * again by device and inode. This avoids false mismatches caused
1134 * by multiple links or ".." in pathnames.
1135 *
1136 * To avoid a race, we open the file and use fstat() rather than
1137 * using stat().
1138 */
1139 if (obj == NULL) {
1140 if ((fd = open(path, O_RDONLY)) == -1) {
1141 _rtld_error("Cannot open \"%s\"", path);
1142 return NULL;
1143 }
1144 if (fstat(fd, &sb) == -1) {
1145 _rtld_error("Cannot fstat \"%s\"", path);
1146 close(fd);
1147 return NULL;
1148 }
1149 for (obj = obj_list->next; obj != NULL; obj = obj->next) {
1150 if (obj->ino == sb.st_ino && obj->dev == sb.st_dev) {
1151 close(fd);
1152 break;
1153 }
1154 }
1155 }
1156
1157 if (obj == NULL) { /* First use of this object, so we must map it in */
1158 dbg("loading \"%s\"", path);
1159 obj = map_object(fd, path, &sb);
1160 close(fd);
1161 if (obj == NULL) {
1162 free(path);
1163 return NULL;
1164 }
1165
1166 obj->path = path;
1167 digest_dynamic(obj);
1168
1169 *obj_tail = obj;
1170 obj_tail = &obj->next;
1171 obj_count++;
1172 linkmap_add(obj); /* for GDB & dlinfo() */
1173
1174 dbg(" %p .. %p: %s", obj->mapbase,
1175 obj->mapbase + obj->mapsize - 1, obj->path);
1176 if (obj->textrel)
1177 dbg(" WARNING: %s has impure text", obj->path);
1178 } else
1179 free(path);
1180
1181 obj->refcount++;
1182 return obj;
1183}
1184
1185/*
1186 * Check for locking violations and die if one is found.
1187 */
1188static void
1189lock_check(void)
1190{
1191 int rcount, wcount;
1192
1193 rcount = lockinfo.rcount;
1194 wcount = lockinfo.wcount;
1195 assert(rcount >= 0);
1196 assert(wcount >= 0);
1197 if (wcount > 1 || (wcount != 0 && rcount != 0)) {
1198 _rtld_error("Application locking error: %d readers and %d writers"
1199 " in dynamic linker. See DLLOCKINIT(3) in manual pages.",
1200 rcount, wcount);
1201 die();
1202 }
1203}
1204
1205static Obj_Entry *
1206obj_from_addr(const void *addr)
1207{
1208 unsigned long endhash;
1209 Obj_Entry *obj;
1210
1211 endhash = elf_hash(END_SYM);
1212 for (obj = obj_list; obj != NULL; obj = obj->next) {
1213 const Elf_Sym *endsym;
1214
1215 if (addr < (void *) obj->mapbase)
1216 continue;
1217 if ((endsym = symlook_obj(END_SYM, endhash, obj, true)) == NULL)
1218 continue; /* No "end" symbol?! */
1219 if (addr < (void *) (obj->relocbase + endsym->st_value))
1220 return obj;
1221 }
1222 return NULL;
1223}
1224
1225/*
1226 * Call the finalization functions for each of the objects in "list"
1227 * which are unreferenced. All of the objects are expected to have
1228 * non-NULL fini functions.
1229 */
1230static void
1231objlist_call_fini(Objlist *list)
1232{
1233 Objlist_Entry *elm;
1234 char *saved_msg;
1235
1236 /*
1237 * Preserve the current error message since a fini function might
1238 * call into the dynamic linker and overwrite it.
1239 */
1240 saved_msg = errmsg_save();
1241 STAILQ_FOREACH(elm, list, link) {
1242 if (elm->obj->refcount == 0) {
1243 dbg("calling fini function for %s", elm->obj->path);
1244 (*elm->obj->fini)();
1245 }
1246 }
1247 errmsg_restore(saved_msg);
1248}
1249
1250/*
1251 * Call the initialization functions for each of the objects in
1252 * "list". All of the objects are expected to have non-NULL init
1253 * functions.
1254 */
1255static void
1256objlist_call_init(Objlist *list)
1257{
1258 Objlist_Entry *elm;
1259 char *saved_msg;
1260
1261 /*
1262 * Preserve the current error message since an init function might
1263 * call into the dynamic linker and overwrite it.
1264 */
1265 saved_msg = errmsg_save();
1266 STAILQ_FOREACH(elm, list, link) {
1267 dbg("calling init function for %s", elm->obj->path);
1268 (*elm->obj->init)();
1269 }
1270 errmsg_restore(saved_msg);
1271}
1272
1273static void
1274objlist_clear(Objlist *list)
1275{
1276 Objlist_Entry *elm;
1277
1278 while (!STAILQ_EMPTY(list)) {
1279 elm = STAILQ_FIRST(list);
1280 STAILQ_REMOVE_HEAD(list, link);
1281 free(elm);
1282 }
1283}
1284
1285static Objlist_Entry *
1286objlist_find(Objlist *list, const Obj_Entry *obj)
1287{
1288 Objlist_Entry *elm;
1289
1290 STAILQ_FOREACH(elm, list, link)
1291 if (elm->obj == obj)
1292 return elm;
1293 return NULL;
1294}
1295
1296static void
1297objlist_init(Objlist *list)
1298{
1299 STAILQ_INIT(list);
1300}
1301
1302static void
1303objlist_push_head(Objlist *list, Obj_Entry *obj)
1304{
1305 Objlist_Entry *elm;
1306
1307 elm = NEW(Objlist_Entry);
1308 elm->obj = obj;
1309 STAILQ_INSERT_HEAD(list, elm, link);
1310}
1311
1312static void
1313objlist_push_tail(Objlist *list, Obj_Entry *obj)
1314{
1315 Objlist_Entry *elm;
1316
1317 elm = NEW(Objlist_Entry);
1318 elm->obj = obj;
1319 STAILQ_INSERT_TAIL(list, elm, link);
1320}
1321
1322static void
1323objlist_remove(Objlist *list, Obj_Entry *obj)
1324{
1325 Objlist_Entry *elm;
1326
1327 if ((elm = objlist_find(list, obj)) != NULL) {
1328 STAILQ_REMOVE(list, elm, Struct_Objlist_Entry, link);
1329 free(elm);
1330 }
1331}
1332
1333/*
1334 * Remove all of the unreferenced objects from "list".
1335 */
1336static void
1337objlist_remove_unref(Objlist *list)
1338{
1339 Objlist newlist;
1340 Objlist_Entry *elm;
1341
1342 STAILQ_INIT(&newlist);
1343 while (!STAILQ_EMPTY(list)) {
1344 elm = STAILQ_FIRST(list);
1345 STAILQ_REMOVE_HEAD(list, link);
1346 if (elm->obj->refcount == 0)
1347 free(elm);
1348 else
1349 STAILQ_INSERT_TAIL(&newlist, elm, link);
1350 }
1351 *list = newlist;
1352}
1353
1354/*
1355 * Relocate newly-loaded shared objects. The argument is a pointer to
1356 * the Obj_Entry for the first such object. All objects from the first
1357 * to the end of the list of objects are relocated. Returns 0 on success,
1358 * or -1 on failure.
1359 */
1360static int
1361relocate_objects(Obj_Entry *first, bool bind_now)
1362{
1363 Obj_Entry *obj;
1364
1365 for (obj = first; obj != NULL; obj = obj->next) {
1366 if (obj != &obj_rtld)
1367 dbg("relocating \"%s\"", obj->path);
1368 if (obj->nbuckets == 0 || obj->nchains == 0 || obj->buckets == NULL ||
1369 obj->symtab == NULL || obj->strtab == NULL) {
1370 _rtld_error("%s: Shared object has no run-time symbol table",
1371 obj->path);
1372 return -1;
1373 }
1374
1375 if (obj->textrel) {
1376 /* There are relocations to the write-protected text segment. */
1377 if (mprotect(obj->mapbase, obj->textsize,
1378 PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
1379 _rtld_error("%s: Cannot write-enable text segment: %s",
1380 obj->path, strerror(errno));
1381 return -1;
1382 }
1383 }
1384
1385 /* Process the non-PLT relocations. */
1386 if (reloc_non_plt(obj, &obj_rtld))
1387 return -1;
1388
1389 if (obj->textrel) { /* Re-protected the text segment. */
1390 if (mprotect(obj->mapbase, obj->textsize,
1391 PROT_READ|PROT_EXEC) == -1) {
1392 _rtld_error("%s: Cannot write-protect text segment: %s",
1393 obj->path, strerror(errno));
1394 return -1;
1395 }
1396 }
1397
1398 /* Process the PLT relocations. */
1399 if (reloc_plt(obj) == -1)
1400 return -1;
1401 /* Relocate the jump slots if we are doing immediate binding. */
1402 if (bind_now)
1403 if (reloc_jmpslots(obj) == -1)
1404 return -1;
1405
1406
1407 /*
1408 * Set up the magic number and version in the Obj_Entry. These
1409 * were checked in the crt1.o from the original ElfKit, so we
1410 * set them for backward compatibility.
1411 */
1412 obj->magic = RTLD_MAGIC;
1413 obj->version = RTLD_VERSION;
1414
1415 /* Set the special PLT or GOT entries. */
1416 init_pltgot(obj);
1417 }
1418
1419 return 0;
1420}
1421
1422/*
1423 * Cleanup procedure. It will be called (by the atexit mechanism) just
1424 * before the process exits.
1425 */
1426static void
1427rtld_exit(void)
1428{
1429 Obj_Entry *obj;
1430
1431 dbg("rtld_exit()");
1432 /* Clear all the reference counts so the fini functions will be called. */
1433 for (obj = obj_list; obj != NULL; obj = obj->next)
1434 obj->refcount = 0;
1435 objlist_call_fini(&list_fini);
1436 /* No need to remove the items from the list, since we are exiting. */
1437}
1438
1439static void *
1440path_enumerate(const char *path, path_enum_proc callback, void *arg)
1441{
1442 if (path == NULL)
1443 return (NULL);
1444
1445 path += strspn(path, ":;");
1446 while (*path != '\0') {
1447 size_t len;
1448 char *res;
1449
1450 len = strcspn(path, ":;");
1451 res = callback(path, len, arg);
1452
1453 if (res != NULL)
1454 return (res);
1455
1456 path += len;
1457 path += strspn(path, ":;");
1458 }
1459
1460 return (NULL);
1461}
1462
1463struct try_library_args {
1464 const char *name;
1465 size_t namelen;
1466 char *buffer;
1467 size_t buflen;
1468};
1469
1470static void *
1471try_library_path(const char *dir, size_t dirlen, void *param)
1472{
1473 struct try_library_args *arg;
1474
1475 arg = param;
1476 if (*dir == '/' || trust) {
1477 char *pathname;
1478
1479 if (dirlen + 1 + arg->namelen + 1 > arg->buflen)
1480 return (NULL);
1481
1482 pathname = arg->buffer;
1483 strncpy(pathname, dir, dirlen);
1484 pathname[dirlen] = '/';
1485 strcpy(pathname + dirlen + 1, arg->name);
1486
1487 dbg(" Trying \"%s\"", pathname);
1488 if (access(pathname, F_OK) == 0) { /* We found it */
1489 pathname = xmalloc(dirlen + 1 + arg->namelen + 1);
1490 strcpy(pathname, arg->buffer);
1491 return (pathname);
1492 }
1493 }
1494 return (NULL);
1495}
1496
1497static char *
1498search_library_path(const char *name, const char *path)
1499{
1500 char *p;
1501 struct try_library_args arg;
1502
1503 if (path == NULL)
1504 return NULL;
1505
1506 arg.name = name;
1507 arg.namelen = strlen(name);
1508 arg.buffer = xmalloc(PATH_MAX);
1509 arg.buflen = PATH_MAX;
1510
1511 p = path_enumerate(path, try_library_path, &arg);
1512
1513 free(arg.buffer);
1514
1515 return (p);
1516}
1517
1518int
1519dlclose(void *handle)
1520{
1521 Obj_Entry *root;
1522
1523 wlock_acquire();
1524 root = dlcheck(handle);
1525 if (root == NULL) {
1526 wlock_release();
1527 return -1;
1528 }
1529
1530 /* Unreference the object and its dependencies. */
1531 root->dl_refcount--;
1532 unref_dag(root);
1533
1534 if (root->refcount == 0) {
1535 /*
1536 * The object is no longer referenced, so we must unload it.
1537 * First, call the fini functions with no locks held.
1538 */
1539 wlock_release();
1540 objlist_call_fini(&list_fini);
1541 wlock_acquire();
1542 objlist_remove_unref(&list_fini);
1543
1544 /* Finish cleaning up the newly-unreferenced objects. */
1545 GDB_STATE(RT_DELETE,&root->linkmap);
1546 unload_object(root);
1547 GDB_STATE(RT_CONSISTENT,NULL);
1548 }
1549 wlock_release();
1550 return 0;
1551}
1552
1553const char *
1554dlerror(void)
1555{
1556 char *msg = error_message;
1557 error_message = NULL;
1558 return msg;
1559}
1560
1561/*
1562 * This function is deprecated and has no effect.
1563 */
1564void
1565dllockinit(void *context,
1566 void *(*lock_create)(void *context),
1567 void (*rlock_acquire)(void *lock),
1568 void (*wlock_acquire)(void *lock),
1569 void (*lock_release)(void *lock),
1570 void (*lock_destroy)(void *lock),
1571 void (*context_destroy)(void *context))
1572{
1573 static void *cur_context;
1574 static void (*cur_context_destroy)(void *);
1575
1576 /* Just destroy the context from the previous call, if necessary. */
1577 if (cur_context_destroy != NULL)
1578 cur_context_destroy(cur_context);
1579 cur_context = context;
1580 cur_context_destroy = context_destroy;
1581}
1582
1583void *
1584dlopen(const char *name, int mode)
1585{
1586 Obj_Entry **old_obj_tail;
1587 Obj_Entry *obj;
1588 Objlist initlist;
1589 int result;
1590
1591 ld_tracing = (mode & RTLD_TRACE) == 0 ? NULL : "1";
1592 if (ld_tracing != NULL)
1593 environ = (char **)*get_program_var_addr("environ");
1594
1595 objlist_init(&initlist);
1596
1597 wlock_acquire();
1598 GDB_STATE(RT_ADD,NULL);
1599
1600 old_obj_tail = obj_tail;
1601 obj = NULL;
1602 if (name == NULL) {
1603 obj = obj_main;
1604 obj->refcount++;
1605 } else {
1606 char *path = find_library(name, obj_main);
1607 if (path != NULL)
1608 obj = load_object(path);
1609 }
1610
1611 if (obj) {
1612 obj->dl_refcount++;
1613 if (mode & RTLD_GLOBAL && objlist_find(&list_global, obj) == NULL)
1614 objlist_push_tail(&list_global, obj);
1615 mode &= RTLD_MODEMASK;
1616 if (*old_obj_tail != NULL) { /* We loaded something new. */
1617 assert(*old_obj_tail == obj);
1618
1619 result = load_needed_objects(obj);
1620 if (result != -1 && ld_tracing)
1621 goto trace;
1622
1623 if (result == -1 ||
1624 (init_dag(obj), relocate_objects(obj, mode == RTLD_NOW)) == -1) {
1625 obj->dl_refcount--;
1626 unref_dag(obj);
1627 if (obj->refcount == 0)
1628 unload_object(obj);
1629 obj = NULL;
1630 } else {
1631 /* Make list of init functions to call. */
1632 initlist_add_objects(obj, &obj->next, &initlist);
1633 }
1634 } else if (ld_tracing)
1635 goto trace;
1636 }
1637
1638 GDB_STATE(RT_CONSISTENT,obj ? &obj->linkmap : NULL);
1639
1640 /* Call the init functions with no locks held. */
1641 wlock_release();
1642 objlist_call_init(&initlist);
1643 wlock_acquire();
1644 objlist_clear(&initlist);
1645 wlock_release();
1646 return obj;
1647trace:
1648 trace_loaded_objects(obj);
1649 wlock_release();
1650 exit(0);
1651}
1652
1653void *
1654dlsym(void *handle, const char *name)
1655{
1656 const Obj_Entry *obj;
1657 unsigned long hash;
1658 const Elf_Sym *def;
1659 const Obj_Entry *defobj;
1660
1661 hash = elf_hash(name);
1662 def = NULL;
1663 defobj = NULL;
1664
1665 rlock_acquire();
1666 if (handle == NULL || handle == RTLD_NEXT ||
1667 handle == RTLD_DEFAULT || handle == RTLD_SELF) {
1668 void *retaddr;
1669
1670 retaddr = __builtin_return_address(0); /* __GNUC__ only */
1671 if ((obj = obj_from_addr(retaddr)) == NULL) {
1672 _rtld_error("Cannot determine caller's shared object");
1673 rlock_release();
1674 return NULL;
1675 }
1676 if (handle == NULL) { /* Just the caller's shared object. */
1677 def = symlook_obj(name, hash, obj, true);
1678 defobj = obj;
1679 } else if (handle == RTLD_NEXT || /* Objects after caller's */
1680 handle == RTLD_SELF) { /* ... caller included */
1681 if (handle == RTLD_NEXT)
1682 obj = obj->next;
1683 for (; obj != NULL; obj = obj->next) {
1684 if ((def = symlook_obj(name, hash, obj, true)) != NULL) {
1685 defobj = obj;
1686 break;
1687 }
1688 }
1689 } else {
1690 assert(handle == RTLD_DEFAULT);
1691 def = symlook_default(name, hash, obj, &defobj, true);
1692 }
1693 } else {
1694 if ((obj = dlcheck(handle)) == NULL) {
1695 rlock_release();
1696 return NULL;
1697 }
1698
1699 if (obj->mainprog) {
1700 DoneList donelist;
1701
1702 /* Search main program and all libraries loaded by it. */
1703 donelist_init(&donelist);
1704 def = symlook_list(name, hash, &list_main, &defobj, true,
1705 &donelist);
1706 } else {
1707 /*
1708 * XXX - This isn't correct. The search should include the whole
1709 * DAG rooted at the given object.
1710 */
1711 def = symlook_obj(name, hash, obj, true);
1712 defobj = obj;
1713 }
1714 }
1715
1716 if (def != NULL) {
1717 rlock_release();
1718 return defobj->relocbase + def->st_value;
1719 }
1720
1721 _rtld_error("Undefined symbol \"%s\"", name);
1722 rlock_release();
1723 return NULL;
1724}
1725
1726int
1727dladdr(const void *addr, Dl_info *info)
1728{
1729 const Obj_Entry *obj;
1730 const Elf_Sym *def;
1731 void *symbol_addr;
1732 unsigned long symoffset;
1733
1734 rlock_acquire();
1735 obj = obj_from_addr(addr);
1736 if (obj == NULL) {
1737 _rtld_error("No shared object contains address");
1738 rlock_release();
1739 return 0;
1740 }
1741 info->dli_fname = obj->path;
1742 info->dli_fbase = obj->mapbase;
1743 info->dli_saddr = (void *)0;
1744 info->dli_sname = NULL;
1745
1746 /*
1747 * Walk the symbol list looking for the symbol whose address is
1748 * closest to the address sent in.
1749 */
1750 for (symoffset = 0; symoffset < obj->nchains; symoffset++) {
1751 def = obj->symtab + symoffset;
1752
1753 /*
1754 * For skip the symbol if st_shndx is either SHN_UNDEF or
1755 * SHN_COMMON.
1756 */
1757 if (def->st_shndx == SHN_UNDEF || def->st_shndx == SHN_COMMON)
1758 continue;
1759
1760 /*
1761 * If the symbol is greater than the specified address, or if it
1762 * is further away from addr than the current nearest symbol,
1763 * then reject it.
1764 */
1765 symbol_addr = obj->relocbase + def->st_value;
1766 if (symbol_addr > addr || symbol_addr < info->dli_saddr)
1767 continue;
1768
1769 /* Update our idea of the nearest symbol. */
1770 info->dli_sname = obj->strtab + def->st_name;
1771 info->dli_saddr = symbol_addr;
1772
1773 /* Exact match? */
1774 if (info->dli_saddr == addr)
1775 break;
1776 }
1777 rlock_release();
1778 return 1;
1779}
1780
1781int
1782dlinfo(void *handle, int request, void *p)
1783{
1784 const Obj_Entry *obj;
1785 int error;
1786
1787 rlock_acquire();
1788
1789 if (handle == NULL || handle == RTLD_SELF) {
1790 void *retaddr;
1791
1792 retaddr = __builtin_return_address(0); /* __GNUC__ only */
1793 if ((obj = obj_from_addr(retaddr)) == NULL)
1794 _rtld_error("Cannot determine caller's shared object");
1795 } else
1796 obj = dlcheck(handle);
1797
1798 if (obj == NULL) {
1799 rlock_release();
1800 return (-1);
1801 }
1802
1803 error = 0;
1804 switch (request) {
1805 case RTLD_DI_LINKMAP:
1806 *((struct link_map const **)p) = &obj->linkmap;
1807 break;
1808 case RTLD_DI_ORIGIN:
1809 error = rtld_dirname(obj->path, p);
1810 break;
1811
1812 case RTLD_DI_SERINFOSIZE:
1813 case RTLD_DI_SERINFO:
1814 error = do_search_info(obj, request, (struct dl_serinfo *)p);
1815 break;
1816
1817 default:
1818 _rtld_error("Invalid request %d passed to dlinfo()", request);
1819 error = -1;
1820 }
1821
1822 rlock_release();
1823
1824 return (error);
1825}
1826
1827struct fill_search_info_args {
1828 int request;
1829 unsigned int flags;
1830 Dl_serinfo *serinfo;
1831 Dl_serpath *serpath;
1832 char *strspace;
1833};
1834
1835static void *
1836fill_search_info(const char *dir, size_t dirlen, void *param)
1837{
1838 struct fill_search_info_args *arg;
1839
1840 arg = param;
1841
1842 if (arg->request == RTLD_DI_SERINFOSIZE) {
1843 arg->serinfo->dls_cnt ++;
1844 arg->serinfo->dls_size += dirlen + 1;
1845 } else {
1846 struct dl_serpath *s_entry;
1847
1848 s_entry = arg->serpath;
1849 s_entry->dls_name = arg->strspace;
1850 s_entry->dls_flags = arg->flags;
1851
1852 strncpy(arg->strspace, dir, dirlen);
1853 arg->strspace[dirlen] = '\0';
1854
1855 arg->strspace += dirlen + 1;
1856 arg->serpath++;
1857 }
1858
1859 return (NULL);
1860}
1861
1862static int
1863do_search_info(const Obj_Entry *obj, int request, struct dl_serinfo *info)
1864{
1865 struct dl_serinfo _info;
1866 struct fill_search_info_args args;
1867
1868 args.request = RTLD_DI_SERINFOSIZE;
1869 args.serinfo = &_info;
1870
1871 _info.dls_size = __offsetof(struct dl_serinfo, dls_serpath);
1872 _info.dls_cnt = 0;
1873
1874 path_enumerate(ld_library_path, fill_search_info, &args);
1875 path_enumerate(obj->rpath, fill_search_info, &args);
1876 path_enumerate(gethints(), fill_search_info, &args);
1877 path_enumerate(STANDARD_LIBRARY_PATH, fill_search_info, &args);
1878
1879
1880 if (request == RTLD_DI_SERINFOSIZE) {
1881 info->dls_size = _info.dls_size;
1882 info->dls_cnt = _info.dls_cnt;
1883 return (0);
1884 }
1885
1886 if (info->dls_cnt != _info.dls_cnt || info->dls_size != _info.dls_size) {
1887 _rtld_error("Uninitialized Dl_serinfo struct passed to dlinfo()");
1888 return (-1);
1889 }
1890
1891 args.request = RTLD_DI_SERINFO;
1892 args.serinfo = info;
1893 args.serpath = &info->dls_serpath[0];
1894 args.strspace = (char *)&info->dls_serpath[_info.dls_cnt];
1895
1896 args.flags = LA_SER_LIBPATH;
1897 if (path_enumerate(ld_library_path, fill_search_info, &args) != NULL)
1898 return (-1);
1899
1900 args.flags = LA_SER_RUNPATH;
1901 if (path_enumerate(obj->rpath, fill_search_info, &args) != NULL)
1902 return (-1);
1903
1904 args.flags = LA_SER_CONFIG;
1905 if (path_enumerate(gethints(), fill_search_info, &args) != NULL)
1906 return (-1);
1907
1908 args.flags = LA_SER_DEFAULT;
1909 if (path_enumerate(STANDARD_LIBRARY_PATH, fill_search_info, &args) != NULL)
1910 return (-1);
1911 return (0);
1912}
1913
1914static int
1915rtld_dirname(const char *path, char *bname)
1916{
1917 const char *endp;
1918
1919 /* Empty or NULL string gets treated as "." */
1920 if (path == NULL || *path == '\0') {
1921 bname[0] = '.';
1922 bname[1] = '\0';
1923 return (0);
1924 }
1925
1926 /* Strip trailing slashes */
1927 endp = path + strlen(path) - 1;
1928 while (endp > path && *endp == '/')
1929 endp--;
1930
1931 /* Find the start of the dir */
1932 while (endp > path && *endp != '/')
1933 endp--;
1934
1935 /* Either the dir is "/" or there are no slashes */
1936 if (endp == path) {
1937 bname[0] = *endp == '/' ? '/' : '.';
1938 bname[1] = '\0';
1939 return (0);
1940 } else {
1941 do {
1942 endp--;
1943 } while (endp > path && *endp == '/');
1944 }
1945
1946 if (endp - path + 2 > PATH_MAX)
1947 {
1948 _rtld_error("Filename is too long: %s", path);
1949 return(-1);
1950 }
1951
1952 strncpy(bname, path, endp - path + 1);
1953 bname[endp - path + 1] = '\0';
1954 return (0);
1955}
1956
1957static void
1958linkmap_add(Obj_Entry *obj)
1959{
1960 struct link_map *l = &obj->linkmap;
1961 struct link_map *prev;
1962
1963 obj->linkmap.l_name = obj->path;
1964 obj->linkmap.l_addr = obj->mapbase;
1965 obj->linkmap.l_ld = obj->dynamic;
1966#ifdef __mips__
1967 /* GDB needs load offset on MIPS to use the symbols */
1968 obj->linkmap.l_offs = obj->relocbase;
1969#endif
1970
1971 if (r_debug.r_map == NULL) {
1972 r_debug.r_map = l;
1973 return;
1974 }
1975
1976 /*
1977 * Scan to the end of the list, but not past the entry for the
1978 * dynamic linker, which we want to keep at the very end.
1979 */
1980 for (prev = r_debug.r_map;
1981 prev->l_next != NULL && prev->l_next != &obj_rtld.linkmap;
1982 prev = prev->l_next)
1983 ;
1984
1985 /* Link in the new entry. */
1986 l->l_prev = prev;
1987 l->l_next = prev->l_next;
1988 if (l->l_next != NULL)
1989 l->l_next->l_prev = l;
1990 prev->l_next = l;
1991}
1992
1993static void
1994linkmap_delete(Obj_Entry *obj)
1995{
1996 struct link_map *l = &obj->linkmap;
1997
1998 if (l->l_prev == NULL) {
1999 if ((r_debug.r_map = l->l_next) != NULL)
2000 l->l_next->l_prev = NULL;
2001 return;
2002 }
2003
2004 if ((l->l_prev->l_next = l->l_next) != NULL)
2005 l->l_next->l_prev = l->l_prev;
2006}
2007
2008/*
2009 * Function for the debugger to set a breakpoint on to gain control.
2010 *
2011 * The two parameters allow the debugger to easily find and determine
2012 * what the runtime loader is doing and to whom it is doing it.
2013 *
2014 * When the loadhook trap is hit (r_debug_state, set at program
2015 * initialization), the arguments can be found on the stack:
2016 *
2017 * +8 struct link_map *m
2018 * +4 struct r_debug *rd
2019 * +0 RetAddr
2020 */
2021void
2022r_debug_state(struct r_debug* rd, struct link_map *m)
2023{
2024}
2025
2026/*
2027 * Get address of the pointer variable in the main program.
2028 */
2029static const void **
2030get_program_var_addr(const char *name)
2031{
2032 const Obj_Entry *obj;
2033 unsigned long hash;
2034
2035 hash = elf_hash(name);
2036 for (obj = obj_main; obj != NULL; obj = obj->next) {
2037 const Elf_Sym *def;
2038
2039 if ((def = symlook_obj(name, hash, obj, false)) != NULL) {
2040 const void **addr;
2041
2042 addr = (const void **)(obj->relocbase + def->st_value);
2043 return addr;
2044 }
2045 }
2046 return NULL;
2047}
2048
2049/*
2050 * Set a pointer variable in the main program to the given value. This
2051 * is used to set key variables such as "environ" before any of the
2052 * init functions are called.
2053 */
2054static void
2055set_program_var(const char *name, const void *value)
2056{
2057 const void **addr;
2058
2059 if ((addr = get_program_var_addr(name)) != NULL) {
2060 dbg("\"%s\": *%p <-- %p", name, addr, value);
2061 *addr = value;
2062 }
2063}
2064
2065/*
2066 * Given a symbol name in a referencing object, find the corresponding
2067 * definition of the symbol. Returns a pointer to the symbol, or NULL if
2068 * no definition was found. Returns a pointer to the Obj_Entry of the
2069 * defining object via the reference parameter DEFOBJ_OUT.
2070 */
2071static const Elf_Sym *
2072symlook_default(const char *name, unsigned long hash,
2073 const Obj_Entry *refobj, const Obj_Entry **defobj_out, bool in_plt)
2074{
2075 DoneList donelist;
2076 const Elf_Sym *def;
2077 const Elf_Sym *symp;
2078 const Obj_Entry *obj;
2079 const Obj_Entry *defobj;
2080 const Objlist_Entry *elm;
2081 def = NULL;
2082 defobj = NULL;
2083 donelist_init(&donelist);
2084
2085 /* Look first in the referencing object if linked symbolically. */
2086 if (refobj->symbolic && !donelist_check(&donelist, refobj)) {
2087 symp = symlook_obj(name, hash, refobj, in_plt);
2088 if (symp != NULL) {
2089 def = symp;
2090 defobj = refobj;
2091 }
2092 }
2093
2094 /* Search all objects loaded at program start up. */
2095 if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
2096 symp = symlook_list(name, hash, &list_main, &obj, in_plt, &donelist);
2097 if (symp != NULL &&
2098 (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
2099 def = symp;
2100 defobj = obj;
2101 }
2102 }
2103
2104 /* Search all DAGs whose roots are RTLD_GLOBAL objects. */
2105 STAILQ_FOREACH(elm, &list_global, link) {
2106 if (def != NULL && ELF_ST_BIND(def->st_info) != STB_WEAK)
2107 break;
2108 symp = symlook_list(name, hash, &elm->obj->dagmembers, &obj, in_plt,
2109 &donelist);
2110 if (symp != NULL &&
2111 (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
2112 def = symp;
2113 defobj = obj;
2114 }
2115 }
2116
2117 /* Search all dlopened DAGs containing the referencing object. */
2118 STAILQ_FOREACH(elm, &refobj->dldags, link) {
2119 if (def != NULL && ELF_ST_BIND(def->st_info) != STB_WEAK)
2120 break;
2121 symp = symlook_list(name, hash, &elm->obj->dagmembers, &obj, in_plt,
2122 &donelist);
2123 if (symp != NULL &&
2124 (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
2125 def = symp;
2126 defobj = obj;
2127 }
2128 }
2129
2130 /*
2131 * Search the dynamic linker itself, and possibly resolve the
2132 * symbol from there. This is how the application links to
2133 * dynamic linker services such as dlopen. Only the values listed
2134 * in the "exports" array can be resolved from the dynamic linker.
2135 */
2136 if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
2137 symp = symlook_obj(name, hash, &obj_rtld, in_plt);
2138 if (symp != NULL && is_exported(symp)) {
2139 def = symp;
2140 defobj = &obj_rtld;
2141 }
2142 }
2143
2144 if (def != NULL)
2145 *defobj_out = defobj;
2146 return def;
2147}
2148
2149static const Elf_Sym *
2150symlook_list(const char *name, unsigned long hash, Objlist *objlist,
2151 const Obj_Entry **defobj_out, bool in_plt, DoneList *dlp)
2152{
2153 const Elf_Sym *symp;
2154 const Elf_Sym *def;
2155 const Obj_Entry *defobj;
2156 const Objlist_Entry *elm;
2157
2158 def = NULL;
2159 defobj = NULL;
2160 STAILQ_FOREACH(elm, objlist, link) {
2161 if (donelist_check(dlp, elm->obj))
2162 continue;
2163 if ((symp = symlook_obj(name, hash, elm->obj, in_plt)) != NULL) {
2164 if (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK) {
2165 def = symp;
2166 defobj = elm->obj;
2167 if (ELF_ST_BIND(def->st_info) != STB_WEAK)
2168 break;
2169 }
2170 }
2171 }
2172 if (def != NULL)
2173 *defobj_out = defobj;
2174 return def;
2175}
2176
2177/*
2178 * Search the symbol table of a single shared object for a symbol of
2179 * the given name. Returns a pointer to the symbol, or NULL if no
2180 * definition was found.
2181 *
2182 * The symbol's hash value is passed in for efficiency reasons; that
2183 * eliminates many recomputations of the hash value.
2184 */
2185const Elf_Sym *
2186symlook_obj(const char *name, unsigned long hash, const Obj_Entry *obj,
2187 bool in_plt)
2188{
2189 if (obj->buckets != NULL) {
2190 unsigned long symnum = obj->buckets[hash % obj->nbuckets];
2191
2192 while (symnum != STN_UNDEF) {
2193 const Elf_Sym *symp;
2194 const char *strp;
2195
2196 if (symnum >= obj->nchains)
2197 return NULL; /* Bad object */
2198 symp = obj->symtab + symnum;
2199 strp = obj->strtab + symp->st_name;
2200
2201 if (name[0] == strp[0] && strcmp(name, strp) == 0)
2202 return symp->st_shndx != SHN_UNDEF ||
2203 (!in_plt && symp->st_value != 0 &&
2204 ELF_ST_TYPE(symp->st_info) == STT_FUNC) ? symp : NULL;
2205
2206 symnum = obj->chains[symnum];
2207 }
2208 }
2209 return NULL;
2210}
2211
2212static void
2213trace_loaded_objects(Obj_Entry *obj)
2214{
2215 char *fmt1, *fmt2, *fmt, *main_local;
2216 int c;
2217
2218 if ((main_local = getenv("LD_TRACE_LOADED_OBJECTS_PROGNAME")) == NULL)
2219 main_local = "";
2220
2221 if ((fmt1 = getenv("LD_TRACE_LOADED_OBJECTS_FMT1")) == NULL)
2222 fmt1 = "\t%o => %p (%x)\n";
2223
2224 if ((fmt2 = getenv("LD_TRACE_LOADED_OBJECTS_FMT2")) == NULL)
2225 fmt2 = "\t%o (%x)\n";
2226
2227 for (; obj; obj = obj->next) {
2228 Needed_Entry *needed;
2229 char *name, *path;
2230 bool is_lib;
2231
2232 for (needed = obj->needed; needed; needed = needed->next) {
2233 if (needed->obj != NULL) {
2234 if (needed->obj->traced)
2235 continue;
2236 needed->obj->traced = true;
2237 path = needed->obj->path;
2238 } else
2239 path = "not found";
2240
2241 name = (char *)obj->strtab + needed->name;
2242 is_lib = strncmp(name, "lib", 3) == 0; /* XXX - bogus */
2243
2244 fmt = is_lib ? fmt1 : fmt2;
2245 while ((c = *fmt++) != '\0') {
2246 switch (c) {
2247 default:
2248 putchar(c);
2249 continue;
2250 case '\\':
2251 switch (c = *fmt) {
2252 case '\0':
2253 continue;
2254 case 'n':
2255 putchar('\n');
2256 break;
2257 case 't':
2258 putchar('\t');
2259 break;
2260 }
2261 break;
2262 case '%':
2263 switch (c = *fmt) {
2264 case '\0':
2265 continue;
2266 case '%':
2267 default:
2268 putchar(c);
2269 break;
2270 case 'A':
2271 printf("%s", main_local);
2272 break;
2273 case 'a':
2274 printf("%s", obj_main->path);
2275 break;
2276 case 'o':
2277 printf("%s", name);
2278 break;
2279#if 0
2280 case 'm':
2281 printf("%d", sodp->sod_major);
2282 break;
2283 case 'n':
2284 printf("%d", sodp->sod_minor);
2285 break;
2286#endif
2287 case 'p':
2288 printf("%s", path);
2289 break;
2290 case 'x':
2291 printf("%p", needed->obj ? needed->obj->mapbase : 0);
2292 break;
2293 }
2294 break;
2295 }
2296 ++fmt;
2297 }
2298 }
2299 }
2300}
2301
2302/*
2303 * Unload a dlopened object and its dependencies from memory and from
2304 * our data structures. It is assumed that the DAG rooted in the
2305 * object has already been unreferenced, and that the object has a
2306 * reference count of 0.
2307 */
2308static void
2309unload_object(Obj_Entry *root)
2310{
2311 Obj_Entry *obj;
2312 Obj_Entry **linkp;
2313
2314 assert(root->refcount == 0);
2315
2316 /*
2317 * Pass over the DAG removing unreferenced objects from
2318 * appropriate lists.
2319 */
2320 unlink_object(root);
2321
2322 /* Unmap all objects that are no longer referenced. */
2323 linkp = &obj_list->next;
2324 while ((obj = *linkp) != NULL) {
2325 if (obj->refcount == 0) {
2326 dbg("unloading \"%s\"", obj->path);
2327 munmap(obj->mapbase, obj->mapsize);
2328 linkmap_delete(obj);
2329 *linkp = obj->next;
2330 obj_count--;
2331 obj_free(obj);
2332 } else
2333 linkp = &obj->next;
2334 }
2335 obj_tail = linkp;
2336}
2337
2338static void
2339unlink_object(Obj_Entry *root)
2340{
2341 const Needed_Entry *needed;
2342 Objlist_Entry *elm;
2343
2344 if (root->refcount == 0) {
2345 /* Remove the object from the RTLD_GLOBAL list. */
2346 objlist_remove(&list_global, root);
2347
2348 /* Remove the object from all objects' DAG lists. */
2349 STAILQ_FOREACH(elm, &root->dagmembers , link)
2350 objlist_remove(&elm->obj->dldags, root);
2351 }
2352
2353 for (needed = root->needed; needed != NULL; needed = needed->next)
2354 if (needed->obj != NULL)
2355 unlink_object(needed->obj);
2356}
2357
2358static void
2359unref_dag(Obj_Entry *root)
2360{
2361 const Needed_Entry *needed;
2362
2363 if (root->refcount == 0)
2364 return;
2365 root->refcount--;
2366 if (root->refcount == 0)
2367 for (needed = root->needed; needed != NULL; needed = needed->next)
2368 if (needed->obj != NULL)
2369 unref_dag(needed->obj);
2370}