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