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