xref: /freebsd/libexec/rtld-elf/rtld.c (revision 7f3dea244c40159a41ab22da77a434d7c5b5e85a)
1 /*-
2  * Copyright 1996, 1997, 1998, 1999 John D. Polstra.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  * $FreeBSD$
26  */
27 
28 /*
29  * Dynamic linker for ELF.
30  *
31  * John Polstra <jdp@polstra.com>.
32  */
33 
34 #ifndef __GNUC__
35 #error "GCC is needed to compile this file"
36 #endif
37 
38 #include <sys/param.h>
39 #include <sys/mman.h>
40 
41 #include <dlfcn.h>
42 #include <err.h>
43 #include <errno.h>
44 #include <fcntl.h>
45 #include <stdarg.h>
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <string.h>
49 #include <unistd.h>
50 
51 #include "debug.h"
52 #include "rtld.h"
53 
54 /*
55  * Debugging support.
56  */
57 
58 #define assert(cond)	((cond) ? (void) 0 :\
59     (msg("oops: " __XSTRING(__LINE__) "\n"), abort()))
60 #define msg(s)		(write(1, s, strlen(s)))
61 #define trace()		msg("trace: " __XSTRING(__LINE__) "\n");
62 
63 #define END_SYM		"_end"
64 
65 /* Types. */
66 typedef void (*func_ptr_type)();
67 
68 /*
69  * Function declarations.
70  */
71 static const char *basename(const char *);
72 static void call_fini_functions(Obj_Entry *);
73 static void call_init_functions(Obj_Entry *);
74 static void die(void);
75 static void digest_dynamic(Obj_Entry *);
76 static Obj_Entry *digest_phdr(const Elf_Phdr *, int, caddr_t, const char *);
77 static Obj_Entry *dlcheck(void *);
78 static char *find_library(const char *, const Obj_Entry *);
79 static const char *gethints(void);
80 static void init_rtld(caddr_t);
81 static bool is_exported(const Elf_Sym *);
82 static void linkmap_add(Obj_Entry *);
83 static void linkmap_delete(Obj_Entry *);
84 static int load_needed_objects(Obj_Entry *);
85 static int load_preload_objects(void);
86 static Obj_Entry *load_object(char *);
87 static Obj_Entry *obj_from_addr(const void *);
88 static int relocate_objects(Obj_Entry *, bool);
89 static void rtld_exit(void);
90 static char *search_library_path(const char *, const char *);
91 static void set_program_var(const char *, const void *);
92 static void trace_loaded_objects(Obj_Entry *obj);
93 static void unload_object(Obj_Entry *, bool do_fini_funcs);
94 static void unref_object_dag(Obj_Entry *);
95 
96 void r_debug_state(void);
97 void xprintf(const char *, ...);
98 
99 /*
100  * Data declarations.
101  */
102 static char *error_message;	/* Message for dlerror(), or NULL */
103 struct r_debug r_debug;	/* for GDB; */
104 static bool trust;		/* False for setuid and setgid programs */
105 static char *ld_bind_now;	/* Environment variable for immediate binding */
106 static char *ld_debug;		/* Environment variable for debugging */
107 static char *ld_library_path;	/* Environment variable for search path */
108 static char *ld_preload;	/* Environment variable for libraries to
109 				   load first */
110 static char *ld_tracing;	/* Called from ldd to print libs */
111 static Obj_Entry **main_tail;	/* Value of obj_tail after loading main and
112 				   its needed shared libraries */
113 static Obj_Entry *obj_list;	/* Head of linked list of shared objects */
114 static Obj_Entry **obj_tail;	/* Link field of last object in list */
115 static Obj_Entry *obj_main;	/* The main program shared object */
116 static Obj_Entry obj_rtld;	/* The dynamic linker shared object */
117 
118 static Elf_Sym sym_zero;	/* For resolving undefined weak refs. */
119 
120 #define GDB_STATE(s)	r_debug.r_state = s; r_debug_state();
121 
122 extern Elf_Dyn _DYNAMIC;
123 #pragma weak _DYNAMIC
124 
125 /*
126  * These are the functions the dynamic linker exports to application
127  * programs.  They are the only symbols the dynamic linker is willing
128  * to export from itself.
129  */
130 static func_ptr_type exports[] = {
131     (func_ptr_type) &_rtld_error,
132     (func_ptr_type) &dlclose,
133     (func_ptr_type) &dlerror,
134     (func_ptr_type) &dlopen,
135     (func_ptr_type) &dlsym,
136     (func_ptr_type) &dladdr,
137     NULL
138 };
139 
140 /*
141  * Global declarations normally provided by crt1.  The dynamic linker is
142  * not build with crt1, so we have to provide them ourselves.
143  */
144 char *__progname;
145 char **environ;
146 
147 /*
148  * Main entry point for dynamic linking.  The first argument is the
149  * stack pointer.  The stack is expected to be laid out as described
150  * in the SVR4 ABI specification, Intel 386 Processor Supplement.
151  * Specifically, the stack pointer points to a word containing
152  * ARGC.  Following that in the stack is a null-terminated sequence
153  * of pointers to argument strings.  Then comes a null-terminated
154  * sequence of pointers to environment strings.  Finally, there is a
155  * sequence of "auxiliary vector" entries.
156  *
157  * The second argument points to a place to store the dynamic linker's
158  * exit procedure pointer and the third to a place to store the main
159  * program's object.
160  *
161  * The return value is the main program's entry point.
162  */
163 func_ptr_type
164 _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
165 {
166     Elf_Auxinfo *aux_info[AT_COUNT];
167     int i;
168     int argc;
169     char **argv;
170     char **env;
171     Elf_Auxinfo *aux;
172     Elf_Auxinfo *auxp;
173     const char *argv0;
174 
175     /*
176      * On entry, the dynamic linker itself has not been relocated yet.
177      * Be very careful not to reference any global data until after
178      * init_rtld has returned.  It is OK to reference file-scope statics
179      * and string constants, and to call static and global functions.
180      */
181 
182     /* Find the auxiliary vector on the stack. */
183     argc = *sp++;
184     argv = (char **) sp;
185     sp += argc + 1;	/* Skip over arguments and NULL terminator */
186     env = (char **) sp;
187     while (*sp++ != 0)	/* Skip over environment, and NULL terminator */
188 	;
189     aux = (Elf_Auxinfo *) sp;
190 
191     /* Digest the auxiliary vector. */
192     for (i = 0;  i < AT_COUNT;  i++)
193 	aux_info[i] = NULL;
194     for (auxp = aux;  auxp->a_type != AT_NULL;  auxp++) {
195 	if (auxp->a_type < AT_COUNT)
196 	    aux_info[auxp->a_type] = auxp;
197     }
198 
199     /* Initialize and relocate ourselves. */
200     assert(aux_info[AT_BASE] != NULL);
201     init_rtld((caddr_t) aux_info[AT_BASE]->a_un.a_ptr);
202 
203     __progname = obj_rtld.path;
204     argv0 = argv[0] != NULL ? argv[0] : "(null)";
205     environ = env;
206 
207     trust = geteuid() == getuid() && getegid() == getgid();
208 
209     ld_bind_now = getenv("LD_BIND_NOW");
210     if (trust) {
211 	ld_debug = getenv("LD_DEBUG");
212 	ld_library_path = getenv("LD_LIBRARY_PATH");
213 	ld_preload = getenv("LD_PRELOAD");
214     }
215     ld_tracing = getenv("LD_TRACE_LOADED_OBJECTS");
216 
217     if (ld_debug != NULL && *ld_debug != '\0')
218 	debug = 1;
219     dbg("%s is initialized, base address = %p", __progname,
220 	(caddr_t) aux_info[AT_BASE]->a_un.a_ptr);
221     dbg("RTLD dynamic = %p", obj_rtld.dynamic);
222     dbg("RTLD pltgot  = %p", obj_rtld.pltgot);
223 
224     /*
225      * Load the main program, or process its program header if it is
226      * already loaded.
227      */
228     if (aux_info[AT_EXECFD] != NULL) {	/* Load the main program. */
229 	int fd = aux_info[AT_EXECFD]->a_un.a_val;
230 	dbg("loading main program");
231 	obj_main = map_object(fd, argv0);
232 	close(fd);
233 	if (obj_main == NULL)
234 	    die();
235     } else {				/* Main program already loaded. */
236 	const Elf_Phdr *phdr;
237 	int phnum;
238 	caddr_t entry;
239 
240 	dbg("processing main program's program header");
241 	assert(aux_info[AT_PHDR] != NULL);
242 	phdr = (const Elf_Phdr *) aux_info[AT_PHDR]->a_un.a_ptr;
243 	assert(aux_info[AT_PHNUM] != NULL);
244 	phnum = aux_info[AT_PHNUM]->a_un.a_val;
245 	assert(aux_info[AT_PHENT] != NULL);
246 	assert(aux_info[AT_PHENT]->a_un.a_val == sizeof(Elf_Phdr));
247 	assert(aux_info[AT_ENTRY] != NULL);
248 	entry = (caddr_t) aux_info[AT_ENTRY]->a_un.a_ptr;
249 	if ((obj_main = digest_phdr(phdr, phnum, entry, argv0)) == NULL)
250 	    die();
251     }
252 
253     obj_main->path = xstrdup(argv0);
254     obj_main->mainprog = true;
255     digest_dynamic(obj_main);
256 
257     linkmap_add(obj_main);
258     linkmap_add(&obj_rtld);
259 
260     /* Link the main program into the list of objects. */
261     *obj_tail = obj_main;
262     obj_tail = &obj_main->next;
263     obj_main->refcount++;
264 
265     /* Initialize a fake symbol for resolving undefined weak references. */
266     sym_zero.st_info = ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE);
267     sym_zero.st_shndx = SHN_ABS;
268 
269     dbg("loading LD_PRELOAD libraries");
270     if (load_preload_objects() == -1)
271 	die();
272 
273     dbg("loading needed objects");
274     if (load_needed_objects(obj_main) == -1)
275 	die();
276     main_tail = obj_tail;
277 
278     if (ld_tracing) {		/* We're done */
279 	trace_loaded_objects(obj_main);
280 	exit(0);
281     }
282 
283     dbg("relocating objects");
284     if (relocate_objects(obj_main,
285 	ld_bind_now != NULL && *ld_bind_now != '\0') == -1)
286 	die();
287 
288     dbg("doing copy relocations");
289     if (do_copy_relocations(obj_main) == -1)
290 	die();
291 
292     dbg("initializing key program variables");
293     set_program_var("__progname", argv[0] != NULL ? basename(argv[0]) : "");
294     set_program_var("environ", env);
295 
296     r_debug_state();		/* say hello to gdb! */
297 
298     dbg("calling _init functions");
299     call_init_functions(obj_main->next);
300 
301     dbg("transferring control to program entry point = %p", obj_main->entry);
302 
303     /* Return the exit procedure and the program entry point. */
304     *exit_proc = rtld_exit;
305     *objp = obj_main;
306     return (func_ptr_type) obj_main->entry;
307 }
308 
309 Elf_Addr
310 _rtld_bind(const Obj_Entry *obj, Elf_Word reloff)
311 {
312     const Elf_Rel *rel;
313     const Elf_Sym *def;
314     const Obj_Entry *defobj;
315     Elf_Addr *where;
316     Elf_Addr target;
317 
318     if (obj->pltrel)
319 	rel = (const Elf_Rel *) ((caddr_t) obj->pltrel + reloff);
320     else
321 	rel = (const Elf_Rel *) ((caddr_t) obj->pltrela + reloff);
322 
323     where = (Elf_Addr *) (obj->relocbase + rel->r_offset);
324     def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, true);
325     if (def == NULL)
326 	die();
327 
328     target = (Elf_Addr)(defobj->relocbase + def->st_value);
329 
330     dbg("\"%s\" in \"%s\" ==> %p in \"%s\"",
331       defobj->strtab + def->st_name, basename(obj->path),
332       (void *)target, basename(defobj->path));
333 
334     reloc_jmpslot(where, target);
335     return target;
336 }
337 
338 /*
339  * Error reporting function.  Use it like printf.  If formats the message
340  * into a buffer, and sets things up so that the next call to dlerror()
341  * will return the message.
342  */
343 void
344 _rtld_error(const char *fmt, ...)
345 {
346     static char buf[512];
347     va_list ap;
348 
349     va_start(ap, fmt);
350     vsnprintf(buf, sizeof buf, fmt, ap);
351     error_message = buf;
352     va_end(ap);
353 }
354 
355 static const char *
356 basename(const char *name)
357 {
358     const char *p = strrchr(name, '/');
359     return p != NULL ? p + 1 : name;
360 }
361 
362 static void
363 call_fini_functions(Obj_Entry *first)
364 {
365     Obj_Entry *obj;
366 
367     for (obj = first;  obj != NULL;  obj = obj->next)
368 	if (obj->fini != NULL)
369 	    (*obj->fini)();
370 }
371 
372 static void
373 call_init_functions(Obj_Entry *first)
374 {
375     if (first != NULL) {
376 	call_init_functions(first->next);
377 	if (first->init != NULL)
378 	    (*first->init)();
379     }
380 }
381 
382 static void
383 die(void)
384 {
385     const char *msg = dlerror();
386 
387     if (msg == NULL)
388 	msg = "Fatal error";
389     errx(1, "%s", msg);
390 }
391 
392 /*
393  * Process a shared object's DYNAMIC section, and save the important
394  * information in its Obj_Entry structure.
395  */
396 static void
397 digest_dynamic(Obj_Entry *obj)
398 {
399     const Elf_Dyn *dynp;
400     Needed_Entry **needed_tail = &obj->needed;
401     const Elf_Dyn *dyn_rpath = NULL;
402     int plttype = DT_REL;
403 
404     for (dynp = obj->dynamic;  dynp->d_tag != DT_NULL;  dynp++) {
405 	switch (dynp->d_tag) {
406 
407 	case DT_REL:
408 	    obj->rel = (const Elf_Rel *) (obj->relocbase + dynp->d_un.d_ptr);
409 	    break;
410 
411 	case DT_RELSZ:
412 	    obj->relsize = dynp->d_un.d_val;
413 	    break;
414 
415 	case DT_RELENT:
416 	    assert(dynp->d_un.d_val == sizeof(Elf_Rel));
417 	    break;
418 
419 	case DT_JMPREL:
420 	    obj->pltrel = (const Elf_Rel *)
421 	      (obj->relocbase + dynp->d_un.d_ptr);
422 	    break;
423 
424 	case DT_PLTRELSZ:
425 	    obj->pltrelsize = dynp->d_un.d_val;
426 	    break;
427 
428 	case DT_RELA:
429 	    obj->rela = (const Elf_Rela *) (obj->relocbase + dynp->d_un.d_ptr);
430 	    break;
431 
432 	case DT_RELASZ:
433 	    obj->relasize = dynp->d_un.d_val;
434 	    break;
435 
436 	case DT_RELAENT:
437 	    assert(dynp->d_un.d_val == sizeof(Elf_Rela));
438 	    break;
439 
440 	case DT_PLTREL:
441 	    plttype = dynp->d_un.d_val;
442 	    assert(dynp->d_un.d_val == DT_REL || plttype == DT_RELA);
443 	    break;
444 
445 	case DT_SYMTAB:
446 	    obj->symtab = (const Elf_Sym *)
447 	      (obj->relocbase + dynp->d_un.d_ptr);
448 	    break;
449 
450 	case DT_SYMENT:
451 	    assert(dynp->d_un.d_val == sizeof(Elf_Sym));
452 	    break;
453 
454 	case DT_STRTAB:
455 	    obj->strtab = (const char *) (obj->relocbase + dynp->d_un.d_ptr);
456 	    break;
457 
458 	case DT_STRSZ:
459 	    obj->strsize = dynp->d_un.d_val;
460 	    break;
461 
462 	case DT_HASH:
463 	    {
464 		const Elf_Addr *hashtab = (const Elf_Addr *)
465 		  (obj->relocbase + dynp->d_un.d_ptr);
466 		obj->nbuckets = hashtab[0];
467 		obj->nchains = hashtab[1];
468 		obj->buckets = hashtab + 2;
469 		obj->chains = obj->buckets + obj->nbuckets;
470 	    }
471 	    break;
472 
473 	case DT_NEEDED:
474 	    if (!obj->rtld) {
475 		Needed_Entry *nep = NEW(Needed_Entry);
476 		nep->name = dynp->d_un.d_val;
477 		nep->obj = NULL;
478 		nep->next = NULL;
479 
480 		*needed_tail = nep;
481 		needed_tail = &nep->next;
482 	    }
483 	    break;
484 
485 	case DT_PLTGOT:
486 	    obj->pltgot = (Elf_Addr *) (obj->relocbase + dynp->d_un.d_ptr);
487 	    break;
488 
489 	case DT_TEXTREL:
490 	    obj->textrel = true;
491 	    break;
492 
493 	case DT_SYMBOLIC:
494 	    obj->symbolic = true;
495 	    break;
496 
497 	case DT_RPATH:
498 	    /*
499 	     * We have to wait until later to process this, because we
500 	     * might not have gotten the address of the string table yet.
501 	     */
502 	    dyn_rpath = dynp;
503 	    break;
504 
505 	case DT_SONAME:
506 	    /* Not used by the dynamic linker. */
507 	    break;
508 
509 	case DT_INIT:
510 	    obj->init = (void (*)(void)) (obj->relocbase + dynp->d_un.d_ptr);
511 	    break;
512 
513 	case DT_FINI:
514 	    obj->fini = (void (*)(void)) (obj->relocbase + dynp->d_un.d_ptr);
515 	    break;
516 
517 	case DT_DEBUG:
518 	    /* XXX - not implemented yet */
519 	    dbg("Filling in DT_DEBUG entry");
520 	    ((Elf_Dyn*)dynp)->d_un.d_ptr = (Elf_Addr) &r_debug;
521 	    break;
522 
523 	default:
524 	    xprintf("Ignored d_tag %d\n",dynp->d_tag);
525             break;
526 	}
527     }
528 
529     obj->traced = false;
530 
531     if (plttype == DT_RELA) {
532 	obj->pltrela = (const Elf_Rela *) obj->pltrel;
533 	obj->pltrel = NULL;
534 	obj->pltrelasize = obj->pltrelsize;
535 	obj->pltrelsize = 0;
536     }
537 
538     if (dyn_rpath != NULL)
539 	obj->rpath = obj->strtab + dyn_rpath->d_un.d_val;
540 }
541 
542 /*
543  * Process a shared object's program header.  This is used only for the
544  * main program, when the kernel has already loaded the main program
545  * into memory before calling the dynamic linker.  It creates and
546  * returns an Obj_Entry structure.
547  */
548 static Obj_Entry *
549 digest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t entry, const char *path)
550 {
551     Obj_Entry *obj = CNEW(Obj_Entry);
552     const Elf_Phdr *phlimit = phdr + phnum;
553     const Elf_Phdr *ph;
554     int nsegs = 0;
555 
556     for (ph = phdr;  ph < phlimit;  ph++) {
557 	switch (ph->p_type) {
558 
559 	case PT_PHDR:
560 	    if ((const Elf_Phdr *)ph->p_vaddr != phdr) {
561 		_rtld_error("%s: invalid PT_PHDR", path);
562 		return NULL;
563 	    }
564 	    obj->phdr = (const Elf_Phdr *) ph->p_vaddr;
565 	    obj->phsize = ph->p_memsz;
566 	    break;
567 
568 	case PT_LOAD:
569 	    if (nsegs >= 2) {
570 		_rtld_error("%s: too many PT_LOAD segments", path);
571 		return NULL;
572 	    }
573 	    if (nsegs == 0) {	/* First load segment */
574 		obj->vaddrbase = trunc_page(ph->p_vaddr);
575 		obj->mapbase = (caddr_t) obj->vaddrbase;
576 		obj->relocbase = obj->mapbase - obj->vaddrbase;
577 		obj->textsize = round_page(ph->p_vaddr + ph->p_memsz) -
578 		  obj->vaddrbase;
579 	    } else {		/* Last load segment */
580 		obj->mapsize = round_page(ph->p_vaddr + ph->p_memsz) -
581 		  obj->vaddrbase;
582 	    }
583 	    nsegs++;
584 	    break;
585 
586 	case PT_DYNAMIC:
587 	    obj->dynamic = (const Elf_Dyn *) ph->p_vaddr;
588 	    break;
589 	}
590     }
591     if (nsegs < 2) {
592 	_rtld_error("%s: too few PT_LOAD segments", path);
593 	return NULL;
594     }
595 
596     obj->entry = entry;
597     return obj;
598 }
599 
600 static Obj_Entry *
601 dlcheck(void *handle)
602 {
603     Obj_Entry *obj;
604 
605     for (obj = obj_list;  obj != NULL;  obj = obj->next)
606 	if (obj == (Obj_Entry *) handle)
607 	    break;
608 
609     if (obj == NULL || obj->dl_refcount == 0) {
610 	_rtld_error("Invalid shared object handle %p", handle);
611 	return NULL;
612     }
613     return obj;
614 }
615 
616 /*
617  * Hash function for symbol table lookup.  Don't even think about changing
618  * this.  It is specified by the System V ABI.
619  */
620 unsigned long
621 elf_hash(const char *name)
622 {
623     const unsigned char *p = (const unsigned char *) name;
624     unsigned long h = 0;
625     unsigned long g;
626 
627     while (*p != '\0') {
628 	h = (h << 4) + *p++;
629 	if ((g = h & 0xf0000000) != 0)
630 	    h ^= g >> 24;
631 	h &= ~g;
632     }
633     return h;
634 }
635 
636 /*
637  * Find the library with the given name, and return its full pathname.
638  * The returned string is dynamically allocated.  Generates an error
639  * message and returns NULL if the library cannot be found.
640  *
641  * If the second argument is non-NULL, then it refers to an already-
642  * loaded shared object, whose library search path will be searched.
643  *
644  * The search order is:
645  *   LD_LIBRARY_PATH
646  *   ldconfig hints
647  *   rpath in the referencing file
648  *   /usr/lib
649  */
650 static char *
651 find_library(const char *name, const Obj_Entry *refobj)
652 {
653     char *pathname;
654 
655     if (strchr(name, '/') != NULL) {	/* Hard coded pathname */
656 	if (name[0] != '/' && !trust) {
657 	    _rtld_error("Absolute pathname required for shared object \"%s\"",
658 	      name);
659 	    return NULL;
660 	}
661 	return xstrdup(name);
662     }
663 
664     dbg(" Searching for \"%s\"", name);
665 
666     if ((refobj != NULL &&
667       (pathname = search_library_path(name, refobj->rpath)) != NULL) ||
668       (pathname = search_library_path(name, ld_library_path)) != NULL ||
669       (pathname = search_library_path(name, gethints())) != NULL ||
670       (pathname = search_library_path(name, STANDARD_LIBRARY_PATH)) != NULL)
671 	return pathname;
672 
673     _rtld_error("Shared object \"%s\" not found", name);
674     return NULL;
675 }
676 
677 /*
678  * Given a symbol number in a referencing object, find the corresponding
679  * definition of the symbol.  Returns a pointer to the symbol, or NULL if
680  * no definition was found.  Returns a pointer to the Obj_Entry of the
681  * defining object via the reference parameter DEFOBJ_OUT.
682  */
683 const Elf_Sym *
684 find_symdef(unsigned long symnum, const Obj_Entry *refobj,
685     const Obj_Entry **defobj_out, bool in_plt)
686 {
687     const Elf_Sym *ref;
688     const Elf_Sym *strongdef;
689     const Elf_Sym *weakdef;
690     const Obj_Entry *obj;
691     const Obj_Entry *strongobj;
692     const Obj_Entry *weakobj;
693     const char *name;
694     unsigned long hash;
695 
696     ref = refobj->symtab + symnum;
697     name = refobj->strtab + ref->st_name;
698     hash = elf_hash(name);
699 
700     if (refobj->symbolic) {	/* Look first in the referencing object */
701 	const Elf_Sym *def = symlook_obj(name, hash, refobj, in_plt);
702 	if (def != NULL) {
703 	    *defobj_out = refobj;
704 	    return def;
705 	}
706     }
707 
708     /*
709      * Look in all loaded objects.  Skip the referencing object, if
710      * we have already searched it.  We keep track of the first weak
711      * definition and the first strong definition we encounter.  If
712      * we find a strong definition we stop searching, because there
713      * won't be anything better than that.
714      */
715     strongdef = weakdef = NULL;
716     strongobj = weakobj = NULL;
717     for (obj = obj_list;  obj != NULL;  obj = obj->next) {
718 	if (obj != refobj || !refobj->symbolic) {
719 	    const Elf_Sym *def = symlook_obj(name, hash, obj, in_plt);
720 	    if (def != NULL) {
721 		if (ELF_ST_BIND(def->st_info) == STB_WEAK) {
722 		    if (weakdef == NULL) {
723 			weakdef = def;
724 			weakobj = obj;
725 		    }
726 		} else {
727 		    strongdef = def;
728 		    strongobj = obj;
729 		    break;	/* We are done. */
730 		}
731 	    }
732 	}
733     }
734 
735     /*
736      * If we still don't have a strong definition, search the dynamic
737      * linker itself, and possibly resolve the symbol from there.
738      * This is how the application links to dynamic linker services
739      * such as dlopen.  Only the values listed in the "exports" array
740      * can be resolved from the dynamic linker.
741      */
742     if (strongdef == NULL) {
743 	const Elf_Sym *def = symlook_obj(name, hash, &obj_rtld, in_plt);
744 	if (def != NULL && is_exported(def)) {
745 	    if (ELF_ST_BIND(def->st_info) == STB_WEAK) {
746 		if (weakdef == NULL) {
747 		    weakdef = def;
748 		    weakobj = &obj_rtld;
749 		}
750 	    } else {
751 		strongdef = def;
752 		strongobj = &obj_rtld;
753 	    }
754 	}
755     }
756 
757     if (strongdef != NULL) {
758 	*defobj_out = strongobj;
759 	return strongdef;
760     }
761     if (weakdef != NULL) {
762 	*defobj_out = weakobj;
763 	return weakdef;
764     }
765 
766     if (ELF_ST_BIND(ref->st_info) == STB_WEAK) {
767 	*defobj_out = obj_main;
768 	return &sym_zero;
769     }
770 
771     _rtld_error("%s: Undefined symbol \"%s\"", refobj->path, name);
772     return NULL;
773 }
774 
775 /*
776  * Return the search path from the ldconfig hints file, reading it if
777  * necessary.  Returns NULL if there are problems with the hints file,
778  * or if the search path there is empty.
779  */
780 static const char *
781 gethints(void)
782 {
783     static char *hints;
784 
785     if (hints == NULL) {
786 	int fd;
787 	struct elfhints_hdr hdr;
788 	char *p;
789 
790 	/* Keep from trying again in case the hints file is bad. */
791 	hints = "";
792 
793 	if ((fd = open(_PATH_ELF_HINTS, O_RDONLY)) == -1)
794 	    return NULL;
795 	if (read(fd, &hdr, sizeof hdr) != sizeof hdr ||
796 	  hdr.magic != ELFHINTS_MAGIC ||
797 	  hdr.version != 1) {
798 	    close(fd);
799 	    return NULL;
800 	}
801 	p = xmalloc(hdr.dirlistlen + 1);
802 	if (lseek(fd, hdr.strtab + hdr.dirlist, SEEK_SET) == -1 ||
803 	  read(fd, p, hdr.dirlistlen + 1) != hdr.dirlistlen + 1) {
804 	    free(p);
805 	    close(fd);
806 	    return NULL;
807 	}
808 	hints = p;
809 	close(fd);
810     }
811     return hints[0] != '\0' ? hints : NULL;
812 }
813 
814 /*
815  * Initialize the dynamic linker.  The argument is the address at which
816  * the dynamic linker has been mapped into memory.  The primary task of
817  * this function is to relocate the dynamic linker.
818  */
819 static void
820 init_rtld(caddr_t mapbase)
821 {
822     /*
823      * Conjure up an Obj_Entry structure for the dynamic linker.
824      *
825      * The "path" member is supposed to be dynamically-allocated, but we
826      * aren't yet initialized sufficiently to do that.  Below we will
827      * replace the static version with a dynamically-allocated copy.
828      */
829     obj_rtld.path = "/usr/libexec/ld-elf.so.1";
830     obj_rtld.rtld = true;
831     obj_rtld.mapbase = mapbase;
832 #ifdef PIC
833     obj_rtld.relocbase = mapbase;
834 #endif
835     if (&_DYNAMIC != 0) {
836 	obj_rtld.dynamic = rtld_dynamic(&obj_rtld);
837 	digest_dynamic(&obj_rtld);
838 	assert(obj_rtld.needed == NULL);
839 	assert(!obj_rtld.textrel);
840 
841 	/*
842 	 * Temporarily put the dynamic linker entry into the object list, so
843 	 * that symbols can be found.
844 	 */
845 	obj_list = &obj_rtld;
846 	obj_tail = &obj_rtld.next;
847 
848 	relocate_objects(&obj_rtld, true);
849     }
850 
851     /* Make the object list empty again. */
852     obj_list = NULL;
853     obj_tail = &obj_list;
854 
855     /* Replace the path with a dynamically allocated copy. */
856     obj_rtld.path = xstrdup(obj_rtld.path);
857 
858     r_debug.r_brk = r_debug_state;
859     r_debug.r_state = RT_CONSISTENT;
860 }
861 
862 static bool
863 is_exported(const Elf_Sym *def)
864 {
865     func_ptr_type value;
866     const func_ptr_type *p;
867 
868     value = (func_ptr_type)(obj_rtld.relocbase + def->st_value);
869     for (p = exports;  *p != NULL;  p++)
870 	if (*p == value)
871 	    return true;
872     return false;
873 }
874 
875 /*
876  * Given a shared object, traverse its list of needed objects, and load
877  * each of them.  Returns 0 on success.  Generates an error message and
878  * returns -1 on failure.
879  */
880 static int
881 load_needed_objects(Obj_Entry *first)
882 {
883     Obj_Entry *obj;
884 
885     for (obj = first;  obj != NULL;  obj = obj->next) {
886 	Needed_Entry *needed;
887 
888 	for (needed = obj->needed;  needed != NULL;  needed = needed->next) {
889 	    const char *name = obj->strtab + needed->name;
890 	    char *path = find_library(name, obj);
891 
892 	    needed->obj = NULL;
893 	    if (path == NULL && !ld_tracing)
894 		return -1;
895 
896 	    if (path) {
897 		needed->obj = load_object(path);
898 		if (needed->obj == NULL && !ld_tracing)
899 		    return -1;		/* XXX - cleanup */
900 	    }
901 	}
902     }
903 
904     return 0;
905 }
906 
907 static int
908 load_preload_objects(void)
909 {
910     char *p = ld_preload;
911 
912     if (p == NULL)
913 	return NULL;
914 
915     p += strspn(p, ":;");
916     while (*p != '\0') {
917 	size_t len = strcspn(p, ":;");
918 	char *path;
919 	char savech;
920 
921 	savech = p[len];
922 	p[len] = '\0';
923 	if ((path = find_library(p, NULL)) == NULL)
924 	    return -1;
925 	if (load_object(path) == NULL)
926 	    return -1;	/* XXX - cleanup */
927 	p[len] = savech;
928 	p += len;
929 	p += strspn(p, ":;");
930     }
931     return 0;
932 }
933 
934 /*
935  * Load a shared object into memory, if it is not already loaded.  The
936  * argument must be a string allocated on the heap.  This function assumes
937  * responsibility for freeing it when necessary.
938  *
939  * Returns a pointer to the Obj_Entry for the object.  Returns NULL
940  * on failure.
941  */
942 static Obj_Entry *
943 load_object(char *path)
944 {
945     Obj_Entry *obj;
946 
947     for (obj = obj_list->next;  obj != NULL;  obj = obj->next)
948 	if (strcmp(obj->path, path) == 0)
949 	    break;
950 
951     if (obj == NULL) {	/* First use of this object, so we must map it in */
952 	int fd;
953 
954 	if ((fd = open(path, O_RDONLY)) == -1) {
955 	    _rtld_error("Cannot open \"%s\"", path);
956 	    return NULL;
957 	}
958 	dbg("loading \"%s\"", path);
959 	obj = map_object(fd, path);
960 	close(fd);
961 	if (obj == NULL) {
962 	    free(path);
963 	    return NULL;
964 	}
965 
966 	obj->path = path;
967 	digest_dynamic(obj);
968 
969 	*obj_tail = obj;
970 	obj_tail = &obj->next;
971 	linkmap_add(obj);	/* for GDB */
972 
973 	dbg("  %p .. %p: %s", obj->mapbase,
974 	  obj->mapbase + obj->mapsize - 1, obj->path);
975 	if (obj->textrel)
976 	    dbg("  WARNING: %s has impure text", obj->path);
977     } else
978 	free(path);
979 
980     obj->refcount++;
981     return obj;
982 }
983 
984 static Obj_Entry *
985 obj_from_addr(const void *addr)
986 {
987     unsigned long endhash;
988     Obj_Entry *obj;
989 
990     endhash = elf_hash(END_SYM);
991     for (obj = obj_list;  obj != NULL;  obj = obj->next) {
992 	const Elf_Sym *endsym;
993 
994 	if (addr < (void *) obj->mapbase)
995 	    continue;
996 	if ((endsym = symlook_obj(END_SYM, endhash, obj, true)) == NULL)
997 	    continue;	/* No "end" symbol?! */
998 	if (addr < (void *) (obj->relocbase + endsym->st_value))
999 	    return obj;
1000     }
1001     return NULL;
1002 }
1003 
1004 /*
1005  * Relocate newly-loaded shared objects.  The argument is a pointer to
1006  * the Obj_Entry for the first such object.  All objects from the first
1007  * to the end of the list of objects are relocated.  Returns 0 on success,
1008  * or -1 on failure.
1009  */
1010 static int
1011 relocate_objects(Obj_Entry *first, bool bind_now)
1012 {
1013     Obj_Entry *obj;
1014 
1015     for (obj = first;  obj != NULL;  obj = obj->next) {
1016 	if (obj != &obj_rtld)
1017 	    dbg("relocating \"%s\"", obj->path);
1018 	if (obj->nbuckets == 0 || obj->nchains == 0 || obj->buckets == NULL ||
1019 	    obj->symtab == NULL || obj->strtab == NULL) {
1020 	    _rtld_error("%s: Shared object has no run-time symbol table",
1021 	      obj->path);
1022 	    return -1;
1023 	}
1024 
1025 	if (obj->textrel) {
1026 	    /* There are relocations to the write-protected text segment. */
1027 	    if (mprotect(obj->mapbase, obj->textsize,
1028 	      PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
1029 		_rtld_error("%s: Cannot write-enable text segment: %s",
1030 		  obj->path, strerror(errno));
1031 		return -1;
1032 	    }
1033 	}
1034 
1035 	/* Process the non-PLT relocations. */
1036 	if (reloc_non_plt(obj, &obj_rtld))
1037 		return -1;
1038 
1039 	if (obj->textrel) {	/* Re-protected the text segment. */
1040 	    if (mprotect(obj->mapbase, obj->textsize,
1041 	      PROT_READ|PROT_EXEC) == -1) {
1042 		_rtld_error("%s: Cannot write-protect text segment: %s",
1043 		  obj->path, strerror(errno));
1044 		return -1;
1045 	    }
1046 	}
1047 
1048 	/* Process the PLT relocations. */
1049 	if (reloc_plt(obj, bind_now))
1050 		return -1;
1051 
1052 	/*
1053 	 * Set up the magic number and version in the Obj_Entry.  These
1054 	 * were checked in the crt1.o from the original ElfKit, so we
1055 	 * set them for backward compatibility.
1056 	 */
1057 	obj->magic = RTLD_MAGIC;
1058 	obj->version = RTLD_VERSION;
1059 
1060 	/* Set the special PLT or GOT entries. */
1061 	init_pltgot(obj);
1062     }
1063 
1064     return 0;
1065 }
1066 
1067 /*
1068  * Cleanup procedure.  It will be called (by the atexit mechanism) just
1069  * before the process exits.
1070  */
1071 static void
1072 rtld_exit(void)
1073 {
1074     dbg("rtld_exit()");
1075     call_fini_functions(obj_list->next);
1076 }
1077 
1078 static char *
1079 search_library_path(const char *name, const char *path)
1080 {
1081     size_t namelen = strlen(name);
1082     const char *p = path;
1083 
1084     if (p == NULL)
1085 	return NULL;
1086 
1087     p += strspn(p, ":;");
1088     while (*p != '\0') {
1089 	size_t len = strcspn(p, ":;");
1090 
1091 	if (*p == '/' || trust) {
1092 	    char *pathname;
1093 	    const char *dir = p;
1094 	    size_t dirlen = len;
1095 
1096 	    pathname = xmalloc(dirlen + 1 + namelen + 1);
1097 	    strncpy(pathname, dir, dirlen);
1098 	    pathname[dirlen] = '/';
1099 	    strcpy(pathname + dirlen + 1, name);
1100 
1101 	    dbg("  Trying \"%s\"", pathname);
1102 	    if (access(pathname, F_OK) == 0)		/* We found it */
1103 		return pathname;
1104 
1105 	    free(pathname);
1106 	}
1107 	p += len;
1108 	p += strspn(p, ":;");
1109     }
1110 
1111     return NULL;
1112 }
1113 
1114 int
1115 dlclose(void *handle)
1116 {
1117     Obj_Entry *root = dlcheck(handle);
1118 
1119     if (root == NULL)
1120 	return -1;
1121 
1122     GDB_STATE(RT_DELETE);
1123     unload_object(root, true);
1124     root->dl_refcount--;
1125     GDB_STATE(RT_CONSISTENT);
1126 
1127     return 0;
1128 }
1129 
1130 const char *
1131 dlerror(void)
1132 {
1133     char *msg = error_message;
1134     error_message = NULL;
1135     return msg;
1136 }
1137 
1138 void *
1139 dlopen(const char *name, int mode)
1140 {
1141     Obj_Entry **old_obj_tail = obj_tail;
1142     Obj_Entry *obj = NULL;
1143 
1144     GDB_STATE(RT_ADD);
1145 
1146     if (name == NULL) {
1147 	obj = obj_main;
1148 	obj->refcount++;
1149     } else {
1150 	char *path = find_library(name, obj_main);
1151 	if (path != NULL)
1152 	    obj = load_object(path);
1153     }
1154 
1155     if (obj) {
1156 	obj->dl_refcount++;
1157 	if (*old_obj_tail != NULL) {		/* We loaded something new. */
1158 	    assert(*old_obj_tail == obj);
1159 
1160 	    if (load_needed_objects(obj) == -1 ||
1161 	      relocate_objects(obj, mode == RTLD_NOW) == -1) {
1162 		unload_object(obj, false);
1163 		obj->dl_refcount--;
1164 		obj = NULL;
1165 	    } else
1166 		call_init_functions(obj);
1167 	}
1168     }
1169 
1170     GDB_STATE(RT_CONSISTENT);
1171 
1172     return obj;
1173 }
1174 
1175 void *
1176 dlsym(void *handle, const char *name)
1177 {
1178     const Obj_Entry *obj;
1179     unsigned long hash;
1180     const Elf_Sym *def;
1181 
1182     hash = elf_hash(name);
1183     def = NULL;
1184 
1185     if (handle == NULL || handle == RTLD_NEXT) {
1186 	void *retaddr;
1187 
1188 	retaddr = __builtin_return_address(0);	/* __GNUC__ only */
1189 	if ((obj = obj_from_addr(retaddr)) == NULL) {
1190 	    _rtld_error("Cannot determine caller's shared object");
1191 	    return NULL;
1192 	}
1193 	if (handle == NULL)	/* Just the caller's shared object. */
1194 	    def = symlook_obj(name, hash, obj, true);
1195 	else {			/* All the shared objects after the caller's */
1196 	    while ((obj = obj->next) != NULL)
1197 		if ((def = symlook_obj(name, hash, obj, true)) != NULL)
1198 		    break;
1199 	}
1200     } else {
1201 	if ((obj = dlcheck(handle)) == NULL)
1202 	    return NULL;
1203 
1204 	if (obj->mainprog) {
1205 	    /* Search main program and all libraries loaded by it. */
1206 	    for ( ;  obj != *main_tail;  obj = obj->next)
1207 		if ((def = symlook_obj(name, hash, obj, true)) != NULL)
1208 		    break;
1209 	} else {
1210 	    /*
1211 	     * XXX - This isn't correct.  The search should include the whole
1212 	     * DAG rooted at the given object.
1213 	     */
1214 	    def = symlook_obj(name, hash, obj, true);
1215 	}
1216     }
1217 
1218     if (def != NULL)
1219 	return obj->relocbase + def->st_value;
1220 
1221     _rtld_error("Undefined symbol \"%s\"", name);
1222     return NULL;
1223 }
1224 
1225 int
1226 dladdr(const void *addr, Dl_info *info)
1227 {
1228     const Obj_Entry *obj;
1229     const Elf_Sym *def;
1230     void *symbol_addr;
1231     unsigned long symoffset;
1232 
1233     obj = obj_from_addr(addr);
1234     if (obj == NULL) {
1235         _rtld_error("No shared object contains address");
1236         return 0;
1237     }
1238     info->dli_fname = obj->path;
1239     info->dli_fbase = obj->mapbase;
1240     info->dli_saddr = (void *)0;
1241     info->dli_sname = NULL;
1242 
1243     /*
1244      * Walk the symbol list looking for the symbol whose address is
1245      * closest to the address sent in.
1246      */
1247     for (symoffset = 0; symoffset < obj->nchains; symoffset++) {
1248         def = obj->symtab + symoffset;
1249 
1250         /*
1251          * For skip the symbol if st_shndx is either SHN_UNDEF or
1252          * SHN_COMMON.
1253          */
1254         if (def->st_shndx == SHN_UNDEF || def->st_shndx == SHN_COMMON)
1255             continue;
1256 
1257         /*
1258          * If the symbol is greater than the specified address, or if it
1259          * is further away from addr than the current nearest symbol,
1260          * then reject it.
1261          */
1262         symbol_addr = obj->relocbase + def->st_value;
1263         if (symbol_addr > addr || symbol_addr < info->dli_saddr)
1264             continue;
1265 
1266         /* Update our idea of the nearest symbol. */
1267         info->dli_sname = obj->strtab + def->st_name;
1268         info->dli_saddr = symbol_addr;
1269 
1270         /* Exact match? */
1271         if (info->dli_saddr == addr)
1272             break;
1273     }
1274     return 1;
1275 }
1276 
1277 static void
1278 linkmap_add(Obj_Entry *obj)
1279 {
1280     struct link_map *l = &obj->linkmap;
1281     struct link_map *prev;
1282 
1283     obj->linkmap.l_name = obj->path;
1284     obj->linkmap.l_addr = obj->mapbase;
1285     obj->linkmap.l_ld = obj->dynamic;
1286 #ifdef __mips__
1287     /* GDB needs load offset on MIPS to use the symbols */
1288     obj->linkmap.l_offs = obj->relocbase;
1289 #endif
1290 
1291     if (r_debug.r_map == NULL) {
1292 	r_debug.r_map = l;
1293 	return;
1294     }
1295 
1296     /*
1297      * Scan to the end of the list, but not past the entry for the
1298      * dynamic linker, which we want to keep at the very end.
1299      */
1300     for (prev = r_debug.r_map;
1301       prev->l_next != NULL && prev->l_next != &obj_rtld.linkmap;
1302       prev = prev->l_next)
1303 	;
1304 
1305     /* Link in the new entry. */
1306     l->l_prev = prev;
1307     l->l_next = prev->l_next;
1308     if (l->l_next != NULL)
1309 	l->l_next->l_prev = l;
1310     prev->l_next = l;
1311 }
1312 
1313 static void
1314 linkmap_delete(Obj_Entry *obj)
1315 {
1316     struct link_map *l = &obj->linkmap;
1317 
1318     if (l->l_prev == NULL) {
1319 	if ((r_debug.r_map = l->l_next) != NULL)
1320 	    l->l_next->l_prev = NULL;
1321 	return;
1322     }
1323 
1324     if ((l->l_prev->l_next = l->l_next) != NULL)
1325 	l->l_next->l_prev = l->l_prev;
1326 }
1327 
1328 /*
1329  * Function for the debugger to set a breakpoint on to gain control.
1330  */
1331 void
1332 r_debug_state(void)
1333 {
1334 }
1335 
1336 /*
1337  * Set a pointer variable in the main program to the given value.  This
1338  * is used to set key variables such as "environ" before any of the
1339  * init functions are called.
1340  */
1341 static void
1342 set_program_var(const char *name, const void *value)
1343 {
1344     const Obj_Entry *obj;
1345     unsigned long hash;
1346 
1347     hash = elf_hash(name);
1348     for (obj = obj_main;  obj != NULL;  obj = obj->next) {
1349 	const Elf_Sym *def;
1350 
1351 	if ((def = symlook_obj(name, hash, obj, false)) != NULL) {
1352 	    const void **addr;
1353 
1354 	    addr = (const void **)(obj->relocbase + def->st_value);
1355 	    dbg("\"%s\": *%p <-- %p", name, addr, value);
1356 	    *addr = value;
1357 	    break;
1358 	}
1359     }
1360 }
1361 
1362 /*
1363  * Search the symbol table of a single shared object for a symbol of
1364  * the given name.  Returns a pointer to the symbol, or NULL if no
1365  * definition was found.
1366  *
1367  * The symbol's hash value is passed in for efficiency reasons; that
1368  * eliminates many recomputations of the hash value.
1369  */
1370 const Elf_Sym *
1371 symlook_obj(const char *name, unsigned long hash, const Obj_Entry *obj,
1372   bool in_plt)
1373 {
1374     if (obj->buckets != NULL) {
1375 	unsigned long symnum = obj->buckets[hash % obj->nbuckets];
1376 
1377 	while (symnum != STN_UNDEF) {
1378 	    const Elf_Sym *symp;
1379 	    const char *strp;
1380 
1381 	    if (symnum >= obj->nchains)
1382 		return NULL;	/* Bad object */
1383 	    symp = obj->symtab + symnum;
1384 	    strp = obj->strtab + symp->st_name;
1385 
1386 	    if (strcmp(name, strp) == 0)
1387 		return symp->st_shndx != SHN_UNDEF ||
1388 		  (!in_plt && symp->st_value != 0 &&
1389 		  ELF_ST_TYPE(symp->st_info) == STT_FUNC) ? symp : NULL;
1390 
1391 	    symnum = obj->chains[symnum];
1392 	}
1393     }
1394     return NULL;
1395 }
1396 
1397 static void
1398 trace_loaded_objects(Obj_Entry *obj)
1399 {
1400     char	*fmt1, *fmt2, *fmt, *main_local;
1401     int		c;
1402 
1403     if ((main_local = getenv("LD_TRACE_LOADED_OBJECTS_PROGNAME")) == NULL)
1404 	main_local = "";
1405 
1406     if ((fmt1 = getenv("LD_TRACE_LOADED_OBJECTS_FMT1")) == NULL)
1407 	fmt1 = "\t%o => %p (%x)\n";
1408 
1409     if ((fmt2 = getenv("LD_TRACE_LOADED_OBJECTS_FMT2")) == NULL)
1410 	fmt2 = "\t%o (%x)\n";
1411 
1412     for (; obj; obj = obj->next) {
1413 	Needed_Entry		*needed;
1414 	char			*name, *path;
1415 	bool			is_lib;
1416 
1417 	for (needed = obj->needed; needed; needed = needed->next) {
1418 	    if (needed->obj != NULL) {
1419 		if (needed->obj->traced)
1420 		    continue;
1421 		needed->obj->traced = true;
1422 		path = needed->obj->path;
1423 	    } else
1424 		path = "not found";
1425 
1426 	    name = (char *)obj->strtab + needed->name;
1427 	    is_lib = strncmp(name, "lib", 3) == 0;	/* XXX - bogus */
1428 
1429 	    fmt = is_lib ? fmt1 : fmt2;
1430 	    while ((c = *fmt++) != '\0') {
1431 		switch (c) {
1432 		default:
1433 		    putchar(c);
1434 		    continue;
1435 		case '\\':
1436 		    switch (c = *fmt) {
1437 		    case '\0':
1438 			continue;
1439 		    case 'n':
1440 			putchar('\n');
1441 			break;
1442 		    case 't':
1443 			putchar('\t');
1444 			break;
1445 		    }
1446 		    break;
1447 		case '%':
1448 		    switch (c = *fmt) {
1449 		    case '\0':
1450 			continue;
1451 		    case '%':
1452 		    default:
1453 			putchar(c);
1454 			break;
1455 		    case 'A':
1456 			printf("%s", main_local);
1457 			break;
1458 		    case 'a':
1459 			printf("%s", obj_main->path);
1460 			break;
1461 		    case 'o':
1462 			printf("%s", name);
1463 			break;
1464 #if 0
1465 		    case 'm':
1466 			printf("%d", sodp->sod_major);
1467 			break;
1468 		    case 'n':
1469 			printf("%d", sodp->sod_minor);
1470 			break;
1471 #endif
1472 		    case 'p':
1473 			printf("%s", path);
1474 			break;
1475 		    case 'x':
1476 			printf("%p", needed->obj ? needed->obj->mapbase : 0);
1477 			break;
1478 		    }
1479 		    break;
1480 		}
1481 		++fmt;
1482 	    }
1483 	}
1484     }
1485 }
1486 
1487 static void
1488 unload_object(Obj_Entry *root, bool do_fini_funcs)
1489 {
1490     unref_object_dag(root);
1491     if (root->refcount == 0) {	/* We are finished with some objects. */
1492 	Obj_Entry *obj;
1493 	Obj_Entry **linkp;
1494 
1495 	/* Finalize objects that are about to be unmapped. */
1496 	if (do_fini_funcs)
1497 	    for (obj = obj_list->next;  obj != NULL;  obj = obj->next)
1498 		if (obj->refcount == 0 && obj->fini != NULL)
1499 		    (*obj->fini)();
1500 
1501 	/* Unmap all objects that are no longer referenced. */
1502 	linkp = &obj_list->next;
1503 	while ((obj = *linkp) != NULL) {
1504 	    if (obj->refcount == 0) {
1505 		dbg("unloading \"%s\"", obj->path);
1506 		munmap(obj->mapbase, obj->mapsize);
1507 		free(obj->path);
1508 		while (obj->needed != NULL) {
1509 		    Needed_Entry *needed = obj->needed;
1510 		    obj->needed = needed->next;
1511 		    free(needed);
1512 		}
1513 		linkmap_delete(obj);
1514 		*linkp = obj->next;
1515 		free(obj);
1516 	    } else
1517 		linkp = &obj->next;
1518 	}
1519 	obj_tail = linkp;
1520     }
1521 }
1522 
1523 static void
1524 unref_object_dag(Obj_Entry *root)
1525 {
1526     const Needed_Entry *needed;
1527 
1528     assert(root->refcount != 0);
1529     root->refcount--;
1530     if (root->refcount == 0)
1531 	for (needed = root->needed;  needed != NULL;  needed = needed->next)
1532 	    if (needed->obj != NULL)
1533 		unref_object_dag(needed->obj);
1534 }
1535 
1536 /*
1537  * Non-mallocing printf, for use by malloc itself.
1538  * XXX - This doesn't belong in this module.
1539  */
1540 void
1541 xprintf(const char *fmt, ...)
1542 {
1543     char buf[256];
1544     va_list ap;
1545 
1546     va_start(ap, fmt);
1547     vsprintf(buf, fmt, ap);
1548     (void)write(1, buf, strlen(buf));
1549     va_end(ap);
1550 }
1551