rtld.c revision 90172
1176771Sraj/*-
2192532Sraj * Copyright 1996, 1997, 1998, 1999, 2000 John D. Polstra.
3176771Sraj * All rights reserved.
4176771Sraj *
5176771Sraj * Redistribution and use in source and binary forms, with or without
6176771Sraj * modification, are permitted provided that the following conditions
7176771Sraj * are met:
8176771Sraj * 1. Redistributions of source code must retain the above copyright
9176771Sraj *    notice, this list of conditions and the following disclaimer.
10176771Sraj * 2. Redistributions in binary form must reproduce the above copyright
11176771Sraj *    notice, this list of conditions and the following disclaimer in the
12176771Sraj *    documentation and/or other materials provided with the distribution.
13176771Sraj *
14176771Sraj * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15176771Sraj * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16176771Sraj * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17176771Sraj * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18176771Sraj * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19176771Sraj * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20176771Sraj * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21176771Sraj * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22176771Sraj * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23176771Sraj * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24176771Sraj *
25176771Sraj * $FreeBSD: head/libexec/rtld-elf/rtld.c 90172 2002-02-04 10:33:48Z sobomax $
26176771Sraj */
27176771Sraj
28176771Sraj/*
29176771Sraj * Dynamic linker for ELF.
30176771Sraj *
31176771Sraj * John Polstra <jdp@polstra.com>.
32176771Sraj */
33176771Sraj
34176771Sraj#ifndef __GNUC__
35176771Sraj#error "GCC is needed to compile this file"
36176771Sraj#endif
37176771Sraj
38176771Sraj#include <sys/param.h>
39176771Sraj#include <sys/mman.h>
40176771Sraj#include <sys/stat.h>
41176771Sraj
42176771Sraj#include <dlfcn.h>
43176771Sraj#include <err.h>
44176771Sraj#include <errno.h>
45176771Sraj#include <fcntl.h>
46176771Sraj#include <stdarg.h>
47176771Sraj#include <stdio.h>
48176771Sraj#include <stdlib.h>
49176771Sraj#include <string.h>
50176771Sraj#include <unistd.h>
51176771Sraj
52176771Sraj#include "debug.h"
53176771Sraj#include "rtld.h"
54176771Sraj
55176771Sraj#define END_SYM		"_end"
56176771Sraj#define PATH_RTLD	"/usr/libexec/ld-elf.so.1"
57176771Sraj
58176771Sraj/* Types. */
59176771Srajtypedef void (*func_ptr_type)();
60176771Sraj
61176771Sraj/*
62176771Sraj * This structure provides a reentrant way to keep a list of objects and
63176771Sraj * check which ones have already been processed in some way.
64176771Sraj */
65176771Srajtypedef struct Struct_DoneList {
66176771Sraj    const Obj_Entry **objs;		/* Array of object pointers */
67176771Sraj    unsigned int num_alloc;		/* Allocated size of the array */
68176771Sraj    unsigned int num_used;		/* Number of array slots used */
69176771Sraj} DoneList;
70176771Sraj
71176771Sraj/*
72176771Sraj * Function declarations.
73176771Sraj */
74176771Srajstatic const char *basename(const char *);
75176771Srajstatic void die(void);
76176771Srajstatic void digest_dynamic(Obj_Entry *);
77176771Srajstatic Obj_Entry *digest_phdr(const Elf_Phdr *, int, caddr_t, const char *);
78192532Srajstatic Obj_Entry *dlcheck(void *);
79176771Srajstatic bool donelist_check(DoneList *, const Obj_Entry *);
80176771Srajstatic void errmsg_restore(char *);
81176771Srajstatic char *errmsg_save(void);
82176771Srajstatic char *find_library(const char *, const Obj_Entry *);
83176771Srajstatic const char *gethints(void);
84176771Srajstatic void init_dag(Obj_Entry *);
85192532Srajstatic void init_dag1(Obj_Entry *root, Obj_Entry *obj, DoneList *);
86192532Srajstatic void init_rtld(caddr_t);
87192532Srajstatic void initlist_add_neededs(Needed_Entry *needed, Objlist *list);
88192532Srajstatic void initlist_add_objects(Obj_Entry *obj, Obj_Entry **tail,
89176771Sraj  Objlist *list);
90176771Srajstatic bool is_exported(const Elf_Sym *);
91176771Srajstatic void linkmap_add(Obj_Entry *);
92176771Srajstatic void linkmap_delete(Obj_Entry *);
93176771Srajstatic int load_needed_objects(Obj_Entry *);
94176771Srajstatic int load_preload_objects(void);
95176771Srajstatic Obj_Entry *load_object(char *);
96176771Srajstatic void lock_check(void);
97176771Srajstatic Obj_Entry *obj_from_addr(const void *);
98176771Srajstatic void objlist_call_fini(Objlist *);
99176771Srajstatic void objlist_call_init(Objlist *);
100176771Srajstatic void objlist_clear(Objlist *);
101176771Srajstatic Objlist_Entry *objlist_find(Objlist *, const Obj_Entry *);
102176771Srajstatic void objlist_init(Objlist *);
103176771Srajstatic void objlist_push_head(Objlist *, Obj_Entry *);
104176771Srajstatic void objlist_push_tail(Objlist *, Obj_Entry *);
105176771Srajstatic void objlist_remove(Objlist *, Obj_Entry *);
106176771Srajstatic void objlist_remove_unref(Objlist *);
107176771Srajstatic int relocate_objects(Obj_Entry *, bool);
108176771Srajstatic void rtld_exit(void);
109176771Srajstatic char *search_library_path(const char *, const char *);
110176771Srajstatic const void **get_program_var_addr(const char *name);
111176771Srajstatic void set_program_var(const char *, const void *);
112176771Srajstatic const Elf_Sym *symlook_default(const char *, unsigned long hash,
113176771Sraj  const Obj_Entry *refobj, const Obj_Entry **defobj_out, bool in_plt);
114176771Srajstatic const Elf_Sym *symlook_list(const char *, unsigned long,
115176771Sraj  Objlist *, const Obj_Entry **, bool in_plt, DoneList *);
116176771Srajstatic void trace_loaded_objects(Obj_Entry *obj);
117176771Srajstatic void unload_object(Obj_Entry *);
118176771Srajstatic void unref_dag(Obj_Entry *);
119176771Sraj
120176771Srajvoid r_debug_state(struct r_debug*, struct link_map*);
121176771Srajvoid xprintf(const char *, ...) __printflike(1, 2);
122176771Sraj
123176771Sraj/*
124176771Sraj * Data declarations.
125176771Sraj */
126176771Srajstatic char *error_message;	/* Message for dlerror(), or NULL */
127176771Srajstruct r_debug r_debug;	/* for GDB; */
128176771Srajstatic bool trust;		/* False for setuid and setgid programs */
129176771Srajstatic char *ld_bind_now;	/* Environment variable for immediate binding */
130176771Srajstatic char *ld_debug;		/* Environment variable for debugging */
131176771Srajstatic char *ld_library_path;	/* Environment variable for search path */
132176771Srajstatic char *ld_preload;	/* Environment variable for libraries to
133176771Sraj				   load first */
134176771Srajstatic char *ld_tracing;	/* Called from ldd to print libs */
135187153Srajstatic Obj_Entry *obj_list;	/* Head of linked list of shared objects */
136176771Srajstatic Obj_Entry **obj_tail;	/* Link field of last object in list */
137176771Srajstatic Obj_Entry *obj_main;	/* The main program shared object */
138176771Srajstatic Obj_Entry obj_rtld;	/* The dynamic linker shared object */
139176771Srajstatic unsigned int obj_count;	/* Number of objects in obj_list */
140176771Sraj
141176771Srajstatic Objlist list_global =	/* Objects dlopened with RTLD_GLOBAL */
142176771Sraj  STAILQ_HEAD_INITIALIZER(list_global);
143176771Srajstatic Objlist list_main =	/* Objects loaded at program startup */
144176771Sraj  STAILQ_HEAD_INITIALIZER(list_main);
145176771Srajstatic Objlist list_fini =	/* Objects needing fini() calls */
146176771Sraj  STAILQ_HEAD_INITIALIZER(list_fini);
147176771Sraj
148176771Srajstatic LockInfo lockinfo;
149176771Sraj
150176771Srajstatic Elf_Sym sym_zero;	/* For resolving undefined weak refs. */
151176771Sraj
152176771Sraj#define GDB_STATE(s,m)	r_debug.r_state = s; r_debug_state(&r_debug,m);
153176771Sraj
154176771Srajextern Elf_Dyn _DYNAMIC;
155176771Sraj#pragma weak _DYNAMIC
156176771Sraj
157176771Sraj/*
158176771Sraj * These are the functions the dynamic linker exports to application
159176771Sraj * programs.  They are the only symbols the dynamic linker is willing
160176771Sraj * to export from itself.
161176771Sraj */
162176771Srajstatic func_ptr_type exports[] = {
163176771Sraj    (func_ptr_type) &_rtld_error,
164176771Sraj    (func_ptr_type) &dlclose,
165176771Sraj    (func_ptr_type) &dlerror,
166176771Sraj    (func_ptr_type) &dlopen,
167176771Sraj    (func_ptr_type) &dlsym,
168176771Sraj    (func_ptr_type) &dladdr,
169176771Sraj    (func_ptr_type) &dllockinit,
170176771Sraj    NULL
171176771Sraj};
172176771Sraj
173176771Sraj/*
174176771Sraj * Global declarations normally provided by crt1.  The dynamic linker is
175176771Sraj * not built with crt1, so we have to provide them ourselves.
176176771Sraj */
177176771Srajchar *__progname;
178176771Srajchar **environ;
179176771Sraj
180176771Sraj/*
181176771Sraj * Fill in a DoneList with an allocation large enough to hold all of
182176771Sraj * the currently-loaded objects.  Keep this as a macro since it calls
183176771Sraj * alloca and we want that to occur within the scope of the caller.
184176771Sraj */
185176771Sraj#define donelist_init(dlp)					\
186176771Sraj    ((dlp)->objs = alloca(obj_count * sizeof (dlp)->objs[0]),	\
187176771Sraj    assert((dlp)->objs != NULL),				\
188176771Sraj    (dlp)->num_alloc = obj_count,				\
189176771Sraj    (dlp)->num_used = 0)
190176771Sraj
191176771Srajstatic __inline void
192176771Srajrlock_acquire(void)
193176771Sraj{
194176771Sraj    lockinfo.rlock_acquire(lockinfo.thelock);
195176771Sraj    atomic_incr_int(&lockinfo.rcount);
196176771Sraj    lock_check();
197176771Sraj}
198176771Sraj
199176771Srajstatic __inline void
200176771Srajwlock_acquire(void)
201176771Sraj{
202176771Sraj    lockinfo.wlock_acquire(lockinfo.thelock);
203176771Sraj    atomic_incr_int(&lockinfo.wcount);
204176771Sraj    lock_check();
205176771Sraj}
206189101Sraj
207189101Srajstatic __inline void
208176771Srajrlock_release(void)
209176771Sraj{
210176771Sraj    atomic_decr_int(&lockinfo.rcount);
211189101Sraj    lockinfo.rlock_release(lockinfo.thelock);
212189101Sraj}
213176771Sraj
214189101Srajstatic __inline void
215189100Srajwlock_release(void)
216189100Sraj{
217189101Sraj    atomic_decr_int(&lockinfo.wcount);
218176771Sraj    lockinfo.wlock_release(lockinfo.thelock);
219176771Sraj}
220176771Sraj
221189101Sraj/*
222189101Sraj * Main entry point for dynamic linking.  The first argument is the
223176771Sraj * stack pointer.  The stack is expected to be laid out as described
224176771Sraj * in the SVR4 ABI specification, Intel 386 Processor Supplement.
225176771Sraj * Specifically, the stack pointer points to a word containing
226176771Sraj * ARGC.  Following that in the stack is a null-terminated sequence
227176771Sraj * of pointers to argument strings.  Then comes a null-terminated
228176771Sraj * sequence of pointers to environment strings.  Finally, there is a
229176771Sraj * sequence of "auxiliary vector" entries.
230176771Sraj *
231176771Sraj * The second argument points to a place to store the dynamic linker's
232176771Sraj * exit procedure pointer and the third to a place to store the main
233176771Sraj * program's object.
234176771Sraj *
235176771Sraj * The return value is the main program's entry point.
236176771Sraj */
237176771Srajfunc_ptr_type
238176771Sraj_rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
239176771Sraj{
240176771Sraj    Elf_Auxinfo *aux_info[AT_COUNT];
241176771Sraj    int i;
242189100Sraj    int argc;
243189100Sraj    char **argv;
244189100Sraj    char **env;
245176771Sraj    Elf_Auxinfo *aux;
246176771Sraj    Elf_Auxinfo *auxp;
247176771Sraj    const char *argv0;
248176771Sraj    Obj_Entry *obj;
249176771Sraj    Obj_Entry **preload_tail;
250176771Sraj    Objlist initlist;
251176771Sraj
252176771Sraj    /*
253176771Sraj     * On entry, the dynamic linker itself has not been relocated yet.
254176771Sraj     * Be very careful not to reference any global data until after
255176771Sraj     * init_rtld has returned.  It is OK to reference file-scope statics
256176771Sraj     * and string constants, and to call static and global functions.
257176771Sraj     */
258176771Sraj
259176771Sraj    /* Find the auxiliary vector on the stack. */
260176771Sraj    argc = *sp++;
261176771Sraj    argv = (char **) sp;
262176771Sraj    sp += argc + 1;	/* Skip over arguments and NULL terminator */
263187153Sraj    env = (char **) sp;
264176771Sraj    while (*sp++ != 0)	/* Skip over environment, and NULL terminator */
265176771Sraj	;
266176771Sraj    aux = (Elf_Auxinfo *) sp;
267176771Sraj
268176771Sraj    /* Digest the auxiliary vector. */
269176771Sraj    for (i = 0;  i < AT_COUNT;  i++)
270176771Sraj	aux_info[i] = NULL;
271176771Sraj    for (auxp = aux;  auxp->a_type != AT_NULL;  auxp++) {
272176771Sraj	if (auxp->a_type < AT_COUNT)
273192532Sraj	    aux_info[auxp->a_type] = auxp;
274176771Sraj    }
275176771Sraj
276176771Sraj    /* Initialize and relocate ourselves. */
277176771Sraj    assert(aux_info[AT_BASE] != NULL);
278176771Sraj    init_rtld((caddr_t) aux_info[AT_BASE]->a_un.a_ptr);
279176771Sraj
280176771Sraj    __progname = obj_rtld.path;
281176771Sraj    argv0 = argv[0] != NULL ? argv[0] : "(null)";
282176771Sraj    environ = env;
283176771Sraj
284176771Sraj    trust = geteuid() == getuid() && getegid() == getgid();
285176771Sraj
286176771Sraj    ld_bind_now = getenv("LD_BIND_NOW");
287176771Sraj    if (trust) {
288176771Sraj	ld_debug = getenv("LD_DEBUG");
289176771Sraj	ld_library_path = getenv("LD_LIBRARY_PATH");
290176771Sraj	ld_preload = getenv("LD_PRELOAD");
291176771Sraj    }
292176771Sraj    ld_tracing = getenv("LD_TRACE_LOADED_OBJECTS");
293176771Sraj
294176771Sraj    if (ld_debug != NULL && *ld_debug != '\0')
295176771Sraj	debug = 1;
296176771Sraj    dbg("%s is initialized, base address = %p", __progname,
297176771Sraj	(caddr_t) aux_info[AT_BASE]->a_un.a_ptr);
298176771Sraj    dbg("RTLD dynamic = %p", obj_rtld.dynamic);
299176771Sraj    dbg("RTLD pltgot  = %p", obj_rtld.pltgot);
300176771Sraj
301176771Sraj    /*
302176771Sraj     * Load the main program, or process its program header if it is
303176771Sraj     * already loaded.
304176771Sraj     */
305176771Sraj    if (aux_info[AT_EXECFD] != NULL) {	/* Load the main program. */
306176771Sraj	int fd = aux_info[AT_EXECFD]->a_un.a_val;
307176771Sraj	dbg("loading main program");
308192532Sraj	obj_main = map_object(fd, argv0, NULL);
309176771Sraj	close(fd);
310176771Sraj	if (obj_main == NULL)
311176771Sraj	    die();
312176771Sraj    } else {				/* Main program already loaded. */
313176771Sraj	const Elf_Phdr *phdr;
314176771Sraj	int phnum;
315176771Sraj	caddr_t entry;
316176771Sraj
317176771Sraj	dbg("processing main program's program header");
318176771Sraj	assert(aux_info[AT_PHDR] != NULL);
319176771Sraj	phdr = (const Elf_Phdr *) aux_info[AT_PHDR]->a_un.a_ptr;
320176771Sraj	assert(aux_info[AT_PHNUM] != NULL);
321176771Sraj	phnum = aux_info[AT_PHNUM]->a_un.a_val;
322176771Sraj	assert(aux_info[AT_PHENT] != NULL);
323176771Sraj	assert(aux_info[AT_PHENT]->a_un.a_val == sizeof(Elf_Phdr));
324176771Sraj	assert(aux_info[AT_ENTRY] != NULL);
325176771Sraj	entry = (caddr_t) aux_info[AT_ENTRY]->a_un.a_ptr;
326192532Sraj	if ((obj_main = digest_phdr(phdr, phnum, entry, argv0)) == NULL)
327192532Sraj	    die();
328192532Sraj    }
329192532Sraj
330192532Sraj    obj_main->path = xstrdup(argv0);
331192532Sraj    obj_main->mainprog = true;
332192532Sraj
333215119Sraj    /*
334192532Sraj     * Get the actual dynamic linker pathname from the executable if
335192532Sraj     * possible.  (It should always be possible.)  That ensures that
336192532Sraj     * gdb will find the right dynamic linker even if a non-standard
337192532Sraj     * one is being used.
338192532Sraj     */
339192532Sraj    if (obj_main->interp != NULL &&
340192532Sraj      strcmp(obj_main->interp, obj_rtld.path) != 0) {
341192532Sraj	free(obj_rtld.path);
342192532Sraj	obj_rtld.path = xstrdup(obj_main->interp);
343192532Sraj    }
344192532Sraj
345192532Sraj    digest_dynamic(obj_main);
346192532Sraj
347192532Sraj    linkmap_add(obj_main);
348192532Sraj    linkmap_add(&obj_rtld);
349192532Sraj
350176771Sraj    /* Link the main program into the list of objects. */
351192532Sraj    *obj_tail = obj_main;
352192532Sraj    obj_tail = &obj_main->next;
353192532Sraj    obj_count++;
354192532Sraj    obj_main->refcount++;
355192532Sraj    /* Make sure we don't call the main program's init and fini functions. */
356192532Sraj    obj_main->init = obj_main->fini = NULL;
357192532Sraj
358192532Sraj    /* Initialize a fake symbol for resolving undefined weak references. */
359192532Sraj    sym_zero.st_info = ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE);
360192532Sraj    sym_zero.st_shndx = SHN_ABS;
361192532Sraj
362192532Sraj    dbg("loading LD_PRELOAD libraries");
363192532Sraj    if (load_preload_objects() == -1)
364192532Sraj	die();
365192532Sraj    preload_tail = obj_tail;
366192532Sraj
367215119Sraj    dbg("loading needed objects");
368192532Sraj    if (load_needed_objects(obj_main) == -1)
369192532Sraj	die();
370192532Sraj
371192532Sraj    /* Make a list of all objects loaded at startup. */
372192532Sraj    for (obj = obj_list;  obj != NULL;  obj = obj->next)
373192532Sraj	objlist_push_tail(&list_main, obj);
374192532Sraj
375192532Sraj    if (ld_tracing) {		/* We're done */
376176771Sraj	trace_loaded_objects(obj_main);
377176771Sraj	exit(0);
378176771Sraj    }
379176771Sraj
380176771Sraj    if (relocate_objects(obj_main,
381176771Sraj	ld_bind_now != NULL && *ld_bind_now != '\0') == -1)
382176771Sraj	die();
383176771Sraj
384176771Sraj    dbg("doing copy relocations");
385176771Sraj    if (do_copy_relocations(obj_main) == -1)
386176771Sraj	die();
387176771Sraj
388176771Sraj    dbg("initializing key program variables");
389176771Sraj    set_program_var("__progname", argv[0] != NULL ? basename(argv[0]) : "");
390176771Sraj    set_program_var("environ", env);
391176771Sraj
392176771Sraj    dbg("initializing thread locks");
393176771Sraj    lockdflt_init(&lockinfo);
394176771Sraj    lockinfo.thelock = lockinfo.lock_create(lockinfo.context);
395176771Sraj
396187153Sraj    /* Make a list of init functions to call. */
397176771Sraj    objlist_init(&initlist);
398187153Sraj    initlist_add_objects(obj_list, preload_tail, &initlist);
399176771Sraj
400176771Sraj    r_debug_state(NULL, &obj_main->linkmap); /* say hello to gdb! */
401176771Sraj
402176771Sraj    objlist_call_init(&initlist);
403176771Sraj    wlock_acquire();
404176771Sraj    objlist_clear(&initlist);
405176771Sraj    wlock_release();
406176771Sraj
407176771Sraj    dbg("transferring control to program entry point = %p", obj_main->entry);
408187153Sraj
409176771Sraj    /* Return the exit procedure and the program entry point. */
410187153Sraj    *exit_proc = rtld_exit;
411176771Sraj    *objp = obj_main;
412176771Sraj    return (func_ptr_type) obj_main->entry;
413176771Sraj}
414176771Sraj
415176771SrajElf_Addr
416176771Sraj_rtld_bind(Obj_Entry *obj, Elf_Word reloff)
417176771Sraj{
418176771Sraj    const Elf_Rel *rel;
419176771Sraj    const Elf_Sym *def;
420187153Sraj    const Obj_Entry *defobj;
421176771Sraj    Elf_Addr *where;
422187153Sraj    Elf_Addr target;
423176771Sraj
424176771Sraj    rlock_acquire();
425176771Sraj    if (obj->pltrel)
426176771Sraj	rel = (const Elf_Rel *) ((caddr_t) obj->pltrel + reloff);
427176771Sraj    else
428176771Sraj	rel = (const Elf_Rel *) ((caddr_t) obj->pltrela + reloff);
429187153Sraj
430176771Sraj    where = (Elf_Addr *) (obj->relocbase + rel->r_offset);
431187153Sraj    def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, true, NULL);
432176771Sraj    if (def == NULL)
433176771Sraj	die();
434176771Sraj
435176771Sraj    target = (Elf_Addr)(defobj->relocbase + def->st_value);
436176771Sraj
437176771Sraj    dbg("\"%s\" in \"%s\" ==> %p in \"%s\"",
438187153Sraj      defobj->strtab + def->st_name, basename(obj->path),
439176771Sraj      (void *)target, basename(defobj->path));
440187153Sraj
441176771Sraj    /*
442176771Sraj     * Write the new contents for the jmpslot. Note that depending on
443176771Sraj     * architecture, the value which we need to return back to the
444205495Smarcel     * lazy binding trampoline may or may not be the target
445176771Sraj     * address. The value returned from reloc_jmpslot() is the value
446176771Sraj     * that the trampoline needs.
447176771Sraj     */
448176771Sraj    target = reloc_jmpslot(where, target, defobj);
449176771Sraj    rlock_release();
450176771Sraj    return target;
451176771Sraj}
452176771Sraj
453176771Sraj/*
454176771Sraj * Error reporting function.  Use it like printf.  If formats the message
455176771Sraj * into a buffer, and sets things up so that the next call to dlerror()
456176771Sraj * will return the message.
457176771Sraj */
458176771Srajvoid
459176771Sraj_rtld_error(const char *fmt, ...)
460176771Sraj{
461187153Sraj    static char buf[512];
462176771Sraj    va_list ap;
463187153Sraj
464176771Sraj    va_start(ap, fmt);
465176771Sraj    vsnprintf(buf, sizeof buf, fmt, ap);
466176771Sraj    error_message = buf;
467176771Sraj    va_end(ap);
468176771Sraj}
469176771Sraj
470187153Sraj/*
471176771Sraj * Return a dynamically-allocated copy of the current error message, if any.
472187153Sraj */
473176771Srajstatic char *
474176771Srajerrmsg_save(void)
475176771Sraj{
476176771Sraj    return error_message == NULL ? NULL : xstrdup(error_message);
477176771Sraj}
478176771Sraj
479176771Sraj/*
480176771Sraj * Restore the current error message from a copy which was previously saved
481187153Sraj * by errmsg_save().  The copy is freed.
482176771Sraj */
483187153Srajstatic void
484176771Srajerrmsg_restore(char *saved_msg)
485176771Sraj{
486176771Sraj    if (saved_msg == NULL)
487176771Sraj	error_message = NULL;
488176771Sraj    else {
489176771Sraj	_rtld_error("%s", saved_msg);
490187153Sraj	free(saved_msg);
491176771Sraj    }
492187153Sraj}
493176771Sraj
494176771Srajstatic const char *
495176771Srajbasename(const char *name)
496176771Sraj{
497176771Sraj    const char *p = strrchr(name, '/');
498176771Sraj    return p != NULL ? p + 1 : name;
499187153Sraj}
500176771Sraj
501176771Srajstatic void
502187153Srajdie(void)
503187153Sraj{
504176771Sraj    const char *msg = dlerror();
505176771Sraj
506176771Sraj    if (msg == NULL)
507176771Sraj	msg = "Fatal error";
508187153Sraj    errx(1, "%s", msg);
509176771Sraj}
510176771Sraj
511176771Sraj/*
512176771Sraj * Process a shared object's DYNAMIC section, and save the important
513176771Sraj * information in its Obj_Entry structure.
514176771Sraj */
515176771Srajstatic void
516187153Srajdigest_dynamic(Obj_Entry *obj)
517176771Sraj{
518176771Sraj    const Elf_Dyn *dynp;
519192532Sraj    Needed_Entry **needed_tail = &obj->needed;
520176771Sraj    const Elf_Dyn *dyn_rpath = NULL;
521176771Sraj    int plttype = DT_REL;
522176771Sraj
523176771Sraj    for (dynp = obj->dynamic;  dynp->d_tag != DT_NULL;  dynp++) {
524187149Sraj	switch (dynp->d_tag) {
525187149Sraj
526176771Sraj	case DT_REL:
527176771Sraj	    obj->rel = (const Elf_Rel *) (obj->relocbase + dynp->d_un.d_ptr);
528176771Sraj	    break;
529176771Sraj
530176771Sraj	case DT_RELSZ:
531176771Sraj	    obj->relsize = dynp->d_un.d_val;
532176771Sraj	    break;
533176771Sraj
534176771Sraj	case DT_RELENT:
535176771Sraj	    assert(dynp->d_un.d_val == sizeof(Elf_Rel));
536176771Sraj	    break;
537176771Sraj
538176771Sraj	case DT_JMPREL:
539176771Sraj	    obj->pltrel = (const Elf_Rel *)
540176771Sraj	      (obj->relocbase + dynp->d_un.d_ptr);
541176771Sraj	    break;
542176771Sraj
543176771Sraj	case DT_PLTRELSZ:
544176771Sraj	    obj->pltrelsize = dynp->d_un.d_val;
545176771Sraj	    break;
546176771Sraj
547176771Sraj	case DT_RELA:
548176771Sraj	    obj->rela = (const Elf_Rela *) (obj->relocbase + dynp->d_un.d_ptr);
549176771Sraj	    break;
550176771Sraj
551176771Sraj	case DT_RELASZ:
552176771Sraj	    obj->relasize = dynp->d_un.d_val;
553176771Sraj	    break;
554176771Sraj
555176771Sraj	case DT_RELAENT:
556176771Sraj	    assert(dynp->d_un.d_val == sizeof(Elf_Rela));
557176771Sraj	    break;
558176771Sraj
559176771Sraj	case DT_PLTREL:
560176771Sraj	    plttype = dynp->d_un.d_val;
561176771Sraj	    assert(dynp->d_un.d_val == DT_REL || plttype == DT_RELA);
562192532Sraj	    break;
563176771Sraj
564176771Sraj	case DT_SYMTAB:
565176771Sraj	    obj->symtab = (const Elf_Sym *)
566176771Sraj	      (obj->relocbase + dynp->d_un.d_ptr);
567176771Sraj	    break;
568176771Sraj
569176771Sraj	case DT_SYMENT:
570176771Sraj	    assert(dynp->d_un.d_val == sizeof(Elf_Sym));
571176771Sraj	    break;
572176771Sraj
573176771Sraj	case DT_STRTAB:
574176771Sraj	    obj->strtab = (const char *) (obj->relocbase + dynp->d_un.d_ptr);
575176771Sraj	    break;
576176771Sraj
577176771Sraj	case DT_STRSZ:
578176771Sraj	    obj->strsize = dynp->d_un.d_val;
579176771Sraj	    break;
580176771Sraj
581176771Sraj	case DT_HASH:
582176771Sraj	    {
583176771Sraj		const Elf_Hashelt *hashtab = (const Elf_Hashelt *)
584176771Sraj		  (obj->relocbase + dynp->d_un.d_ptr);
585176771Sraj		obj->nbuckets = hashtab[0];
586176771Sraj		obj->nchains = hashtab[1];
587176771Sraj		obj->buckets = hashtab + 2;
588176771Sraj		obj->chains = obj->buckets + obj->nbuckets;
589176771Sraj	    }
590176771Sraj	    break;
591176771Sraj
592176771Sraj	case DT_NEEDED:
593176771Sraj	    if (!obj->rtld) {
594176771Sraj		Needed_Entry *nep = NEW(Needed_Entry);
595176771Sraj		nep->name = dynp->d_un.d_val;
596187149Sraj		nep->obj = NULL;
597176771Sraj		nep->next = NULL;
598187149Sraj
599187149Sraj		*needed_tail = nep;
600176771Sraj		needed_tail = &nep->next;
601176771Sraj	    }
602176771Sraj	    break;
603176771Sraj
604176771Sraj	case DT_PLTGOT:
605176771Sraj	    obj->pltgot = (Elf_Addr *) (obj->relocbase + dynp->d_un.d_ptr);
606187149Sraj	    break;
607187149Sraj
608176771Sraj	case DT_TEXTREL:
609176771Sraj	    obj->textrel = true;
610176771Sraj	    break;
611176771Sraj
612176771Sraj	case DT_SYMBOLIC:
613176771Sraj	    obj->symbolic = true;
614176771Sraj	    break;
615176771Sraj
616176771Sraj	case DT_RPATH:
617187153Sraj	    /*
618187153Sraj	     * We have to wait until later to process this, because we
619187153Sraj	     * might not have gotten the address of the string table yet.
620187153Sraj	     */
621187153Sraj	    dyn_rpath = dynp;
622176771Sraj	    break;
623176771Sraj
624176771Sraj	case DT_SONAME:
625176771Sraj	    /* Not used by the dynamic linker. */
626176771Sraj	    break;
627176771Sraj
628176771Sraj	case DT_INIT:
629176771Sraj	    obj->init = (Elf_Addr) (obj->relocbase + dynp->d_un.d_ptr);
630176771Sraj	    break;
631176771Sraj
632176771Sraj	case DT_FINI:
633187153Sraj	    obj->fini = (Elf_Addr) (obj->relocbase + dynp->d_un.d_ptr);
634187153Sraj	    break;
635187153Sraj
636187153Sraj	case DT_DEBUG:
637187153Sraj	    /* XXX - not implemented yet */
638176771Sraj	    dbg("Filling in DT_DEBUG entry");
639176771Sraj	    ((Elf_Dyn*)dynp)->d_un.d_ptr = (Elf_Addr) &r_debug;
640176771Sraj	    break;
641176771Sraj
642176771Sraj	default:
643176771Sraj	    dbg("Ignoring d_tag %ld = %#lx", (long)dynp->d_tag,
644176771Sraj	        (long)dynp->d_tag);
645187149Sraj	    break;
646176771Sraj	}
647187149Sraj    }
648187149Sraj
649176771Sraj    obj->traced = false;
650176771Sraj
651176771Sraj    if (plttype == DT_RELA) {
652176771Sraj	obj->pltrela = (const Elf_Rela *) obj->pltrel;
653176771Sraj	obj->pltrel = NULL;
654176771Sraj	obj->pltrelasize = obj->pltrelsize;
655176771Sraj	obj->pltrelsize = 0;
656176771Sraj    }
657176771Sraj
658187149Sraj    if (dyn_rpath != NULL)
659187149Sraj	obj->rpath = obj->strtab + dyn_rpath->d_un.d_val;
660176771Sraj}
661187149Sraj
662187149Sraj/*
663187149Sraj * Process a shared object's program header.  This is used only for the
664187149Sraj * main program, when the kernel has already loaded the main program
665187149Sraj * into memory before calling the dynamic linker.  It creates and
666187149Sraj * returns an Obj_Entry structure.
667187149Sraj */
668187149Srajstatic Obj_Entry *
669176771Srajdigest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t entry, const char *path)
670176771Sraj{
671176771Sraj    Obj_Entry *obj;
672187149Sraj    const Elf_Phdr *phlimit = phdr + phnum;
673176771Sraj    const Elf_Phdr *ph;
674187149Sraj    int nsegs = 0;
675187149Sraj
676187149Sraj    obj = obj_new();
677176771Sraj    for (ph = phdr;  ph < phlimit;  ph++) {
678176771Sraj	switch (ph->p_type) {
679176771Sraj
680176771Sraj	case PT_PHDR:
681176771Sraj	    if ((const Elf_Phdr *)ph->p_vaddr != phdr) {
682176771Sraj		_rtld_error("%s: invalid PT_PHDR", path);
683176771Sraj		return NULL;
684176771Sraj	    }
685176771Sraj	    obj->phdr = (const Elf_Phdr *) ph->p_vaddr;
686176771Sraj	    obj->phsize = ph->p_memsz;
687176771Sraj	    break;
688176771Sraj
689176771Sraj	case PT_INTERP:
690176771Sraj	    obj->interp = (const char *) ph->p_vaddr;
691176771Sraj	    break;
692176771Sraj
693176771Sraj	case PT_LOAD:
694176771Sraj	    if (nsegs >= 2) {
695176771Sraj		_rtld_error("%s: too many PT_LOAD segments", path);
696176771Sraj		return NULL;
697176771Sraj	    }
698176771Sraj	    if (nsegs == 0) {	/* First load segment */
699176771Sraj		obj->vaddrbase = trunc_page(ph->p_vaddr);
700176771Sraj		obj->mapbase = (caddr_t) obj->vaddrbase;
701187153Sraj		obj->relocbase = obj->mapbase - obj->vaddrbase;
702176771Sraj		obj->textsize = round_page(ph->p_vaddr + ph->p_memsz) -
703176771Sraj		  obj->vaddrbase;
704176771Sraj	    } else {		/* Last load segment */
705187153Sraj		obj->mapsize = round_page(ph->p_vaddr + ph->p_memsz) -
706176771Sraj		  obj->vaddrbase;
707176771Sraj	    }
708192532Sraj	    nsegs++;
709176771Sraj	    break;
710176771Sraj
711176771Sraj	case PT_DYNAMIC:
712176771Sraj	    obj->dynamic = (const Elf_Dyn *) ph->p_vaddr;
713176771Sraj	    break;
714176771Sraj	}
715176771Sraj    }
716176771Sraj    if (nsegs < 2) {
717176771Sraj	_rtld_error("%s: too few PT_LOAD segments", path);
718176771Sraj	return NULL;
719176771Sraj    }
720176771Sraj
721176771Sraj    obj->entry = entry;
722176771Sraj    return obj;
723176771Sraj}
724176771Sraj
725176771Srajstatic Obj_Entry *
726176771Srajdlcheck(void *handle)
727176771Sraj{
728176771Sraj    Obj_Entry *obj;
729176771Sraj
730176771Sraj    for (obj = obj_list;  obj != NULL;  obj = obj->next)
731187153Sraj	if (obj == (Obj_Entry *) handle)
732176771Sraj	    break;
733187153Sraj
734176771Sraj    if (obj == NULL || obj->refcount == 0 || obj->dl_refcount == 0) {
735176771Sraj	_rtld_error("Invalid shared object handle %p", handle);
736176771Sraj	return NULL;
737176771Sraj    }
738176771Sraj    return obj;
739176771Sraj}
740176771Sraj
741176771Sraj/*
742176771Sraj * If the given object is already in the donelist, return true.  Otherwise
743176771Sraj * add the object to the list and return false.
744176771Sraj */
745176771Srajstatic bool
746176771Srajdonelist_check(DoneList *dlp, const Obj_Entry *obj)
747176771Sraj{
748187153Sraj    unsigned int i;
749176771Sraj
750176771Sraj    for (i = 0;  i < dlp->num_used;  i++)
751176771Sraj	if (dlp->objs[i] == obj)
752176771Sraj	    return true;
753176771Sraj    /*
754176771Sraj     * Our donelist allocation should always be sufficient.  But if
755176771Sraj     * our threads locking isn't working properly, more shared objects
756176771Sraj     * could have been loaded since we allocated the list.  That should
757176771Sraj     * never happen, but we'll handle it properly just in case it does.
758176771Sraj     */
759176771Sraj    if (dlp->num_used < dlp->num_alloc)
760176771Sraj	dlp->objs[dlp->num_used++] = obj;
761176771Sraj    return false;
762176771Sraj}
763176771Sraj
764176771Sraj/*
765176771Sraj * Hash function for symbol table lookup.  Don't even think about changing
766176771Sraj * this.  It is specified by the System V ABI.
767176771Sraj */
768176771Srajunsigned long
769187153Srajelf_hash(const char *name)
770176771Sraj{
771187153Sraj    const unsigned char *p = (const unsigned char *) name;
772176771Sraj    unsigned long h = 0;
773176771Sraj    unsigned long g;
774176771Sraj
775176771Sraj    while (*p != '\0') {
776176771Sraj	h = (h << 4) + *p++;
777176771Sraj	if ((g = h & 0xf0000000) != 0)
778176771Sraj	    h ^= g >> 24;
779176771Sraj	h &= ~g;
780176771Sraj    }
781176771Sraj    return h;
782176771Sraj}
783176771Sraj
784176771Sraj/*
785176771Sraj * Find the library with the given name, and return its full pathname.
786176771Sraj * The returned string is dynamically allocated.  Generates an error
787176771Sraj * message and returns NULL if the library cannot be found.
788176771Sraj *
789176771Sraj * If the second argument is non-NULL, then it refers to an already-
790187153Sraj * loaded shared object, whose library search path will be searched.
791187153Sraj *
792176771Sraj * The search order is:
793176771Sraj *   rpath in the referencing file
794176771Sraj *   LD_LIBRARY_PATH
795176771Sraj *   ldconfig hints
796176771Sraj *   /usr/lib
797176771Sraj */
798176771Srajstatic char *
799176771Srajfind_library(const char *name, const Obj_Entry *refobj)
800176771Sraj{
801176771Sraj    char *pathname;
802176771Sraj
803176771Sraj    if (strchr(name, '/') != NULL) {	/* Hard coded pathname */
804176771Sraj	if (name[0] != '/' && !trust) {
805176771Sraj	    _rtld_error("Absolute pathname required for shared object \"%s\"",
806176771Sraj	      name);
807176771Sraj	    return NULL;
808176771Sraj	}
809176771Sraj	return xstrdup(name);
810176771Sraj    }
811176771Sraj
812178628Smarcel    dbg(" Searching for \"%s\"", name);
813178628Smarcel
814176771Sraj    if ((pathname = search_library_path(name, ld_library_path)) != NULL ||
815176771Sraj      (refobj != NULL &&
816176771Sraj      (pathname = search_library_path(name, refobj->rpath)) != NULL) ||
817187153Sraj      (pathname = search_library_path(name, gethints())) != NULL ||
818176771Sraj      (pathname = search_library_path(name, STANDARD_LIBRARY_PATH)) != NULL)
819176771Sraj	return pathname;
820176771Sraj
821187153Sraj    _rtld_error("Shared object \"%s\" not found", name);
822187153Sraj    return NULL;
823176771Sraj}
824176771Sraj
825176771Sraj/*
826176771Sraj * Given a symbol number in a referencing object, find the corresponding
827176771Sraj * definition of the symbol.  Returns a pointer to the symbol, or NULL if
828176771Sraj * no definition was found.  Returns a pointer to the Obj_Entry of the
829176771Sraj * defining object via the reference parameter DEFOBJ_OUT.
830176771Sraj */
831176771Srajconst Elf_Sym *
832176771Srajfind_symdef(unsigned long symnum, const Obj_Entry *refobj,
833176771Sraj    const Obj_Entry **defobj_out, bool in_plt, SymCache *cache)
834176771Sraj{
835176771Sraj    const Elf_Sym *ref;
836176771Sraj    const Elf_Sym *def;
837176771Sraj    const Obj_Entry *defobj;
838176771Sraj    const char *name;
839176771Sraj    unsigned long hash;
840176771Sraj
841176771Sraj    /*
842176771Sraj     * If we have already found this symbol, get the information from
843176771Sraj     * the cache.
844176771Sraj     */
845176771Sraj    if (symnum >= refobj->nchains)
846187153Sraj	return NULL;	/* Bad object */
847176771Sraj    if (cache != NULL && cache[symnum].sym != NULL) {
848187153Sraj	*defobj_out = cache[symnum].obj;
849176771Sraj	return cache[symnum].sym;
850176771Sraj    }
851176771Sraj
852176771Sraj    ref = refobj->symtab + symnum;
853176771Sraj    name = refobj->strtab + ref->st_name;
854176771Sraj    hash = elf_hash(name);
855176771Sraj    defobj = NULL;
856176771Sraj
857192532Sraj    def = symlook_default(name, hash, refobj, &defobj, in_plt);
858192532Sraj
859192532Sraj    /*
860192532Sraj     * If we found no definition and the reference is weak, treat the
861192532Sraj     * symbol as having the value zero.
862192532Sraj     */
863215119Sraj    if (def == NULL && ELF_ST_BIND(ref->st_info) == STB_WEAK) {
864192532Sraj	def = &sym_zero;
865192532Sraj	defobj = obj_main;
866192532Sraj    }
867192532Sraj
868192532Sraj    if (def != NULL) {
869192532Sraj	*defobj_out = defobj;
870192532Sraj	/* Record the information in the cache to avoid subsequent lookups. */
871192532Sraj	if (cache != NULL) {
872192532Sraj	    cache[symnum].sym = def;
873192532Sraj	    cache[symnum].obj = defobj;
874215119Sraj	}
875192532Sraj    } else {
876192532Sraj	if (refobj != &obj_rtld)
877192532Sraj	    _rtld_error("%s: Undefined symbol \"%s\"", refobj->path, name);
878192532Sraj    }
879215119Sraj    return def;
880192532Sraj}
881192532Sraj
882192532Sraj/*
883192532Sraj * Return the search path from the ldconfig hints file, reading it if
884192532Sraj * necessary.  Returns NULL if there are problems with the hints file,
885192532Sraj * or if the search path there is empty.
886192532Sraj */
887192532Srajstatic const char *
888192532Srajgethints(void)
889192532Sraj{
890192532Sraj    static char *hints;
891
892    if (hints == NULL) {
893	int fd;
894	struct elfhints_hdr hdr;
895	char *p;
896
897	/* Keep from trying again in case the hints file is bad. */
898	hints = "";
899
900	if ((fd = open(_PATH_ELF_HINTS, O_RDONLY)) == -1)
901	    return NULL;
902	if (read(fd, &hdr, sizeof hdr) != sizeof hdr ||
903	  hdr.magic != ELFHINTS_MAGIC ||
904	  hdr.version != 1) {
905	    close(fd);
906	    return NULL;
907	}
908	p = xmalloc(hdr.dirlistlen + 1);
909	if (lseek(fd, hdr.strtab + hdr.dirlist, SEEK_SET) == -1 ||
910	  read(fd, p, hdr.dirlistlen + 1) != hdr.dirlistlen + 1) {
911	    free(p);
912	    close(fd);
913	    return NULL;
914	}
915	hints = p;
916	close(fd);
917    }
918    return hints[0] != '\0' ? hints : NULL;
919}
920
921static void
922init_dag(Obj_Entry *root)
923{
924    DoneList donelist;
925
926    donelist_init(&donelist);
927    init_dag1(root, root, &donelist);
928}
929
930static void
931init_dag1(Obj_Entry *root, Obj_Entry *obj, DoneList *dlp)
932{
933    const Needed_Entry *needed;
934
935    if (donelist_check(dlp, obj))
936	return;
937    objlist_push_tail(&obj->dldags, root);
938    objlist_push_tail(&root->dagmembers, obj);
939    for (needed = obj->needed;  needed != NULL;  needed = needed->next)
940	if (needed->obj != NULL)
941	    init_dag1(root, needed->obj, dlp);
942}
943
944/*
945 * Initialize the dynamic linker.  The argument is the address at which
946 * the dynamic linker has been mapped into memory.  The primary task of
947 * this function is to relocate the dynamic linker.
948 */
949static void
950init_rtld(caddr_t mapbase)
951{
952    /*
953     * Conjure up an Obj_Entry structure for the dynamic linker.
954     *
955     * The "path" member is supposed to be dynamically-allocated, but we
956     * aren't yet initialized sufficiently to do that.  Below we will
957     * replace the static version with a dynamically-allocated copy.
958     */
959    obj_rtld.path = PATH_RTLD;
960    obj_rtld.rtld = true;
961    obj_rtld.mapbase = mapbase;
962#ifdef PIC
963    obj_rtld.relocbase = mapbase;
964#endif
965    if (&_DYNAMIC != 0) {
966	obj_rtld.dynamic = rtld_dynamic(&obj_rtld);
967	digest_dynamic(&obj_rtld);
968	assert(obj_rtld.needed == NULL);
969	assert(!obj_rtld.textrel);
970
971	/*
972	 * Temporarily put the dynamic linker entry into the object list, so
973	 * that symbols can be found.
974	 */
975	obj_list = &obj_rtld;
976	obj_tail = &obj_rtld.next;
977	obj_count = 1;
978
979	relocate_objects(&obj_rtld, true);
980    }
981
982    /* Make the object list empty again. */
983    obj_list = NULL;
984    obj_tail = &obj_list;
985    obj_count = 0;
986
987    /* Replace the path with a dynamically allocated copy. */
988    obj_rtld.path = xstrdup(obj_rtld.path);
989
990    r_debug.r_brk = r_debug_state;
991    r_debug.r_state = RT_CONSISTENT;
992}
993
994/*
995 * Add the init functions from a needed object list (and its recursive
996 * needed objects) to "list".  This is not used directly; it is a helper
997 * function for initlist_add_objects().  The write lock must be held
998 * when this function is called.
999 */
1000static void
1001initlist_add_neededs(Needed_Entry *needed, Objlist *list)
1002{
1003    /* Recursively process the successor needed objects. */
1004    if (needed->next != NULL)
1005	initlist_add_neededs(needed->next, list);
1006
1007    /* Process the current needed object. */
1008    if (needed->obj != NULL)
1009	initlist_add_objects(needed->obj, &needed->obj->next, list);
1010}
1011
1012/*
1013 * Scan all of the DAGs rooted in the range of objects from "obj" to
1014 * "tail" and add their init functions to "list".  This recurses over
1015 * the DAGs and ensure the proper init ordering such that each object's
1016 * needed libraries are initialized before the object itself.  At the
1017 * same time, this function adds the objects to the global finalization
1018 * list "list_fini" in the opposite order.  The write lock must be
1019 * held when this function is called.
1020 */
1021static void
1022initlist_add_objects(Obj_Entry *obj, Obj_Entry **tail, Objlist *list)
1023{
1024    if (obj->init_done)
1025	return;
1026    obj->init_done = true;
1027
1028    /* Recursively process the successor objects. */
1029    if (&obj->next != tail)
1030	initlist_add_objects(obj->next, tail, list);
1031
1032    /* Recursively process the needed objects. */
1033    if (obj->needed != NULL)
1034	initlist_add_neededs(obj->needed, list);
1035
1036    /* Add the object to the init list. */
1037    if (obj->init != NULL)
1038	objlist_push_tail(list, obj);
1039
1040    /* Add the object to the global fini list in the reverse order. */
1041    if (obj->fini != NULL)
1042	objlist_push_head(&list_fini, obj);
1043}
1044
1045#ifndef FPTR_TARGET
1046#define FPTR_TARGET(f)	((Elf_Addr) (f))
1047#endif
1048
1049static bool
1050is_exported(const Elf_Sym *def)
1051{
1052    Elf_Addr value;
1053    const func_ptr_type *p;
1054
1055    value = (Elf_Addr)(obj_rtld.relocbase + def->st_value);
1056    for (p = exports;  *p != NULL;  p++)
1057	if (FPTR_TARGET(*p) == value)
1058	    return true;
1059    return false;
1060}
1061
1062/*
1063 * Given a shared object, traverse its list of needed objects, and load
1064 * each of them.  Returns 0 on success.  Generates an error message and
1065 * returns -1 on failure.
1066 */
1067static int
1068load_needed_objects(Obj_Entry *first)
1069{
1070    Obj_Entry *obj;
1071
1072    for (obj = first;  obj != NULL;  obj = obj->next) {
1073	Needed_Entry *needed;
1074
1075	for (needed = obj->needed;  needed != NULL;  needed = needed->next) {
1076	    const char *name = obj->strtab + needed->name;
1077	    char *path = find_library(name, obj);
1078
1079	    needed->obj = NULL;
1080	    if (path == NULL && !ld_tracing)
1081		return -1;
1082
1083	    if (path) {
1084		needed->obj = load_object(path);
1085		if (needed->obj == NULL && !ld_tracing)
1086		    return -1;		/* XXX - cleanup */
1087	    }
1088	}
1089    }
1090
1091    return 0;
1092}
1093
1094static int
1095load_preload_objects(void)
1096{
1097    char *p = ld_preload;
1098    static const char delim[] = " \t:;";
1099
1100    if (p == NULL)
1101	return NULL;
1102
1103    p += strspn(p, delim);
1104    while (*p != '\0') {
1105	size_t len = strcspn(p, delim);
1106	char *path;
1107	char savech;
1108
1109	savech = p[len];
1110	p[len] = '\0';
1111	if ((path = find_library(p, NULL)) == NULL)
1112	    return -1;
1113	if (load_object(path) == NULL)
1114	    return -1;	/* XXX - cleanup */
1115	p[len] = savech;
1116	p += len;
1117	p += strspn(p, delim);
1118    }
1119    return 0;
1120}
1121
1122/*
1123 * Load a shared object into memory, if it is not already loaded.  The
1124 * argument must be a string allocated on the heap.  This function assumes
1125 * responsibility for freeing it when necessary.
1126 *
1127 * Returns a pointer to the Obj_Entry for the object.  Returns NULL
1128 * on failure.
1129 */
1130static Obj_Entry *
1131load_object(char *path)
1132{
1133    Obj_Entry *obj;
1134    int fd = -1;
1135    struct stat sb;
1136
1137    for (obj = obj_list->next;  obj != NULL;  obj = obj->next)
1138	if (strcmp(obj->path, path) == 0)
1139	    break;
1140
1141    /*
1142     * If we didn't find a match by pathname, open the file and check
1143     * again by device and inode.  This avoids false mismatches caused
1144     * by multiple links or ".." in pathnames.
1145     *
1146     * To avoid a race, we open the file and use fstat() rather than
1147     * using stat().
1148     */
1149    if (obj == NULL) {
1150	if ((fd = open(path, O_RDONLY)) == -1) {
1151	    _rtld_error("Cannot open \"%s\"", path);
1152	    return NULL;
1153	}
1154	if (fstat(fd, &sb) == -1) {
1155	    _rtld_error("Cannot fstat \"%s\"", path);
1156	    close(fd);
1157	    return NULL;
1158	}
1159	for (obj = obj_list->next;  obj != NULL;  obj = obj->next) {
1160	    if (obj->ino == sb.st_ino && obj->dev == sb.st_dev) {
1161		close(fd);
1162		break;
1163	    }
1164	}
1165    }
1166
1167    if (obj == NULL) {	/* First use of this object, so we must map it in */
1168	dbg("loading \"%s\"", path);
1169	obj = map_object(fd, path, &sb);
1170	close(fd);
1171	if (obj == NULL) {
1172	    free(path);
1173	    return NULL;
1174	}
1175
1176	obj->path = path;
1177	digest_dynamic(obj);
1178
1179	*obj_tail = obj;
1180	obj_tail = &obj->next;
1181	obj_count++;
1182	linkmap_add(obj);	/* for GDB */
1183
1184	dbg("  %p .. %p: %s", obj->mapbase,
1185	  obj->mapbase + obj->mapsize - 1, obj->path);
1186	if (obj->textrel)
1187	    dbg("  WARNING: %s has impure text", obj->path);
1188    } else
1189	free(path);
1190
1191    obj->refcount++;
1192    return obj;
1193}
1194
1195/*
1196 * Check for locking violations and die if one is found.
1197 */
1198static void
1199lock_check(void)
1200{
1201    int rcount, wcount;
1202
1203    rcount = lockinfo.rcount;
1204    wcount = lockinfo.wcount;
1205    assert(rcount >= 0);
1206    assert(wcount >= 0);
1207    if (wcount > 1 || (wcount != 0 && rcount != 0)) {
1208	_rtld_error("Application locking error: %d readers and %d writers"
1209	  " in dynamic linker.  See DLLOCKINIT(3) in manual pages.",
1210	  rcount, wcount);
1211	die();
1212    }
1213}
1214
1215static Obj_Entry *
1216obj_from_addr(const void *addr)
1217{
1218    unsigned long endhash;
1219    Obj_Entry *obj;
1220
1221    endhash = elf_hash(END_SYM);
1222    for (obj = obj_list;  obj != NULL;  obj = obj->next) {
1223	const Elf_Sym *endsym;
1224
1225	if (addr < (void *) obj->mapbase)
1226	    continue;
1227	if ((endsym = symlook_obj(END_SYM, endhash, obj, true)) == NULL)
1228	    continue;	/* No "end" symbol?! */
1229	if (addr < (void *) (obj->relocbase + endsym->st_value))
1230	    return obj;
1231    }
1232    return NULL;
1233}
1234
1235/*
1236 * Call the finalization functions for each of the objects in "list"
1237 * which are unreferenced.  All of the objects are expected to have
1238 * non-NULL fini functions.
1239 */
1240static void
1241objlist_call_fini(Objlist *list)
1242{
1243    Objlist_Entry *elm;
1244    char *saved_msg;
1245
1246    /*
1247     * Preserve the current error message since a fini function might
1248     * call into the dynamic linker and overwrite it.
1249     */
1250    saved_msg = errmsg_save();
1251    STAILQ_FOREACH(elm, list, link) {
1252	if (elm->obj->refcount == 0) {
1253	    dbg("calling fini function for %s at %p", elm->obj->path,
1254	        (void *)elm->obj->fini);
1255	    call_initfini_pointer(elm->obj, elm->obj->fini);
1256	}
1257    }
1258    errmsg_restore(saved_msg);
1259}
1260
1261/*
1262 * Call the initialization functions for each of the objects in
1263 * "list".  All of the objects are expected to have non-NULL init
1264 * functions.
1265 */
1266static void
1267objlist_call_init(Objlist *list)
1268{
1269    Objlist_Entry *elm;
1270    char *saved_msg;
1271
1272    /*
1273     * Preserve the current error message since an init function might
1274     * call into the dynamic linker and overwrite it.
1275     */
1276    saved_msg = errmsg_save();
1277    STAILQ_FOREACH(elm, list, link) {
1278	dbg("calling init function for %s at %p", elm->obj->path,
1279	    (void *)elm->obj->init);
1280	call_initfini_pointer(elm->obj, elm->obj->init);
1281    }
1282    errmsg_restore(saved_msg);
1283}
1284
1285static void
1286objlist_clear(Objlist *list)
1287{
1288    Objlist_Entry *elm;
1289
1290    while (!STAILQ_EMPTY(list)) {
1291	elm = STAILQ_FIRST(list);
1292	STAILQ_REMOVE_HEAD(list, link);
1293	free(elm);
1294    }
1295}
1296
1297static Objlist_Entry *
1298objlist_find(Objlist *list, const Obj_Entry *obj)
1299{
1300    Objlist_Entry *elm;
1301
1302    STAILQ_FOREACH(elm, list, link)
1303	if (elm->obj == obj)
1304	    return elm;
1305    return NULL;
1306}
1307
1308static void
1309objlist_init(Objlist *list)
1310{
1311    STAILQ_INIT(list);
1312}
1313
1314static void
1315objlist_push_head(Objlist *list, Obj_Entry *obj)
1316{
1317    Objlist_Entry *elm;
1318
1319    elm = NEW(Objlist_Entry);
1320    elm->obj = obj;
1321    STAILQ_INSERT_HEAD(list, elm, link);
1322}
1323
1324static void
1325objlist_push_tail(Objlist *list, Obj_Entry *obj)
1326{
1327    Objlist_Entry *elm;
1328
1329    elm = NEW(Objlist_Entry);
1330    elm->obj = obj;
1331    STAILQ_INSERT_TAIL(list, elm, link);
1332}
1333
1334static void
1335objlist_remove(Objlist *list, Obj_Entry *obj)
1336{
1337    Objlist_Entry *elm;
1338
1339    if ((elm = objlist_find(list, obj)) != NULL) {
1340	STAILQ_REMOVE(list, elm, Struct_Objlist_Entry, link);
1341	free(elm);
1342    }
1343}
1344
1345/*
1346 * Remove all of the unreferenced objects from "list".
1347 */
1348static void
1349objlist_remove_unref(Objlist *list)
1350{
1351    Objlist newlist;
1352    Objlist_Entry *elm;
1353
1354    STAILQ_INIT(&newlist);
1355    while (!STAILQ_EMPTY(list)) {
1356	elm = STAILQ_FIRST(list);
1357	STAILQ_REMOVE_HEAD(list, link);
1358	if (elm->obj->refcount == 0)
1359	    free(elm);
1360	else
1361	    STAILQ_INSERT_TAIL(&newlist, elm, link);
1362    }
1363    *list = newlist;
1364}
1365
1366/*
1367 * Relocate newly-loaded shared objects.  The argument is a pointer to
1368 * the Obj_Entry for the first such object.  All objects from the first
1369 * to the end of the list of objects are relocated.  Returns 0 on success,
1370 * or -1 on failure.
1371 */
1372static int
1373relocate_objects(Obj_Entry *first, bool bind_now)
1374{
1375    Obj_Entry *obj;
1376
1377    for (obj = first;  obj != NULL;  obj = obj->next) {
1378	if (obj != &obj_rtld)
1379	    dbg("relocating \"%s\"", obj->path);
1380	if (obj->nbuckets == 0 || obj->nchains == 0 || obj->buckets == NULL ||
1381	    obj->symtab == NULL || obj->strtab == NULL) {
1382	    _rtld_error("%s: Shared object has no run-time symbol table",
1383	      obj->path);
1384	    return -1;
1385	}
1386
1387	if (obj->textrel) {
1388	    /* There are relocations to the write-protected text segment. */
1389	    if (mprotect(obj->mapbase, obj->textsize,
1390	      PROT_READ|PROT_WRITE|PROT_EXEC) == -1) {
1391		_rtld_error("%s: Cannot write-enable text segment: %s",
1392		  obj->path, strerror(errno));
1393		return -1;
1394	    }
1395	}
1396
1397	/* Process the non-PLT relocations. */
1398	if (reloc_non_plt(obj, &obj_rtld))
1399		return -1;
1400
1401	if (obj->textrel) {	/* Re-protected the text segment. */
1402	    if (mprotect(obj->mapbase, obj->textsize,
1403	      PROT_READ|PROT_EXEC) == -1) {
1404		_rtld_error("%s: Cannot write-protect text segment: %s",
1405		  obj->path, strerror(errno));
1406		return -1;
1407	    }
1408	}
1409
1410	/* Process the PLT relocations. */
1411	if (reloc_plt(obj) == -1)
1412	    return -1;
1413	/* Relocate the jump slots if we are doing immediate binding. */
1414	if (bind_now)
1415	    if (reloc_jmpslots(obj) == -1)
1416		return -1;
1417
1418
1419	/*
1420	 * Set up the magic number and version in the Obj_Entry.  These
1421	 * were checked in the crt1.o from the original ElfKit, so we
1422	 * set them for backward compatibility.
1423	 */
1424	obj->magic = RTLD_MAGIC;
1425	obj->version = RTLD_VERSION;
1426
1427	/* Set the special PLT or GOT entries. */
1428	init_pltgot(obj);
1429    }
1430
1431    return 0;
1432}
1433
1434/*
1435 * Cleanup procedure.  It will be called (by the atexit mechanism) just
1436 * before the process exits.
1437 */
1438static void
1439rtld_exit(void)
1440{
1441    Obj_Entry *obj;
1442
1443    dbg("rtld_exit()");
1444    wlock_acquire();
1445    /* Clear all the reference counts so the fini functions will be called. */
1446    for (obj = obj_list;  obj != NULL;  obj = obj->next)
1447	obj->refcount = 0;
1448    wlock_release();
1449    objlist_call_fini(&list_fini);
1450    /* No need to remove the items from the list, since we are exiting. */
1451}
1452
1453static char *
1454search_library_path(const char *name, const char *path)
1455{
1456    size_t namelen = strlen(name);
1457    const char *p = path;
1458
1459    if (p == NULL)
1460	return NULL;
1461
1462    p += strspn(p, ":;");
1463    while (*p != '\0') {
1464	size_t len = strcspn(p, ":;");
1465
1466	if (*p == '/' || trust) {
1467	    char *pathname;
1468	    const char *dir = p;
1469	    size_t dirlen = len;
1470
1471	    pathname = xmalloc(dirlen + 1 + namelen + 1);
1472	    strncpy(pathname, dir, dirlen);
1473	    pathname[dirlen] = '/';
1474	    strcpy(pathname + dirlen + 1, name);
1475
1476	    dbg("  Trying \"%s\"", pathname);
1477	    if (access(pathname, F_OK) == 0)		/* We found it */
1478		return pathname;
1479
1480	    free(pathname);
1481	}
1482	p += len;
1483	p += strspn(p, ":;");
1484    }
1485
1486    return NULL;
1487}
1488
1489int
1490dlclose(void *handle)
1491{
1492    Obj_Entry *root;
1493
1494    wlock_acquire();
1495    root = dlcheck(handle);
1496    if (root == NULL) {
1497	wlock_release();
1498	return -1;
1499    }
1500
1501    /* Unreference the object and its dependencies. */
1502    root->dl_refcount--;
1503    unref_dag(root);
1504
1505    if (root->refcount == 0) {
1506	/*
1507	 * The object is no longer referenced, so we must unload it.
1508	 * First, call the fini functions with no locks held.
1509	 */
1510	wlock_release();
1511	objlist_call_fini(&list_fini);
1512	wlock_acquire();
1513	objlist_remove_unref(&list_fini);
1514
1515	/* Finish cleaning up the newly-unreferenced objects. */
1516	GDB_STATE(RT_DELETE,&root->linkmap);
1517	unload_object(root);
1518	GDB_STATE(RT_CONSISTENT,NULL);
1519    }
1520    wlock_release();
1521    return 0;
1522}
1523
1524const char *
1525dlerror(void)
1526{
1527    char *msg = error_message;
1528    error_message = NULL;
1529    return msg;
1530}
1531
1532/*
1533 * This function is deprecated and has no effect.
1534 */
1535void
1536dllockinit(void *context,
1537	   void *(*lock_create)(void *context),
1538           void (*rlock_acquire)(void *lock),
1539           void (*wlock_acquire)(void *lock),
1540           void (*lock_release)(void *lock),
1541           void (*lock_destroy)(void *lock),
1542	   void (*context_destroy)(void *context))
1543{
1544    static void *cur_context;
1545    static void (*cur_context_destroy)(void *);
1546
1547    /* Just destroy the context from the previous call, if necessary. */
1548    if (cur_context_destroy != NULL)
1549	cur_context_destroy(cur_context);
1550    cur_context = context;
1551    cur_context_destroy = context_destroy;
1552}
1553
1554void *
1555dlopen(const char *name, int mode)
1556{
1557    Obj_Entry **old_obj_tail;
1558    Obj_Entry *obj;
1559    Objlist initlist;
1560    int result;
1561
1562    ld_tracing = (mode & RTLD_TRACE) == 0 ? NULL : "1";
1563    if (ld_tracing != NULL)
1564	environ = (char **)*get_program_var_addr("environ");
1565
1566    objlist_init(&initlist);
1567
1568    wlock_acquire();
1569    GDB_STATE(RT_ADD,NULL);
1570
1571    old_obj_tail = obj_tail;
1572    obj = NULL;
1573    if (name == NULL) {
1574	obj = obj_main;
1575	obj->refcount++;
1576    } else {
1577	char *path = find_library(name, obj_main);
1578	if (path != NULL)
1579	    obj = load_object(path);
1580    }
1581
1582    if (obj) {
1583	obj->dl_refcount++;
1584	if (mode & RTLD_GLOBAL && objlist_find(&list_global, obj) == NULL)
1585	    objlist_push_tail(&list_global, obj);
1586	mode &= RTLD_MODEMASK;
1587	if (*old_obj_tail != NULL) {		/* We loaded something new. */
1588	    assert(*old_obj_tail == obj);
1589
1590	    result = load_needed_objects(obj);
1591	    if (result != -1 && ld_tracing) {
1592		trace_loaded_objects(obj);
1593		wlock_release();
1594		exit(0);
1595	    }
1596
1597	    if (result == -1 ||
1598	      (init_dag(obj), relocate_objects(obj, mode == RTLD_NOW)) == -1) {
1599		obj->dl_refcount--;
1600		unref_dag(obj);
1601		if (obj->refcount == 0)
1602		    unload_object(obj);
1603		obj = NULL;
1604	    } else {
1605		/* Make list of init functions to call. */
1606		initlist_add_objects(obj, &obj->next, &initlist);
1607	    }
1608	}
1609    }
1610
1611    GDB_STATE(RT_CONSISTENT,obj ? &obj->linkmap : NULL);
1612
1613    /* Call the init functions with no locks held. */
1614    wlock_release();
1615    objlist_call_init(&initlist);
1616    wlock_acquire();
1617    objlist_clear(&initlist);
1618    wlock_release();
1619    return obj;
1620}
1621
1622void *
1623dlsym(void *handle, const char *name)
1624{
1625    const Obj_Entry *obj;
1626    unsigned long hash;
1627    const Elf_Sym *def;
1628    const Obj_Entry *defobj;
1629
1630    hash = elf_hash(name);
1631    def = NULL;
1632    defobj = NULL;
1633
1634    rlock_acquire();
1635    if (handle == NULL || handle == RTLD_NEXT || handle == RTLD_DEFAULT) {
1636	void *retaddr;
1637
1638	retaddr = __builtin_return_address(0);	/* __GNUC__ only */
1639	if ((obj = obj_from_addr(retaddr)) == NULL) {
1640	    _rtld_error("Cannot determine caller's shared object");
1641	    rlock_release();
1642	    return NULL;
1643	}
1644	if (handle == NULL) {	/* Just the caller's shared object. */
1645	    def = symlook_obj(name, hash, obj, true);
1646	    defobj = obj;
1647	} else if (handle == RTLD_NEXT) {	/* Objects after caller's */
1648	    while ((obj = obj->next) != NULL) {
1649		if ((def = symlook_obj(name, hash, obj, true)) != NULL) {
1650		    defobj = obj;
1651		    break;
1652		}
1653	    }
1654	} else {
1655	    assert(handle == RTLD_DEFAULT);
1656	    def = symlook_default(name, hash, obj, &defobj, true);
1657	}
1658    } else {
1659	if ((obj = dlcheck(handle)) == NULL) {
1660	    rlock_release();
1661	    return NULL;
1662	}
1663
1664	if (obj->mainprog) {
1665	    DoneList donelist;
1666
1667	    /* Search main program and all libraries loaded by it. */
1668	    donelist_init(&donelist);
1669	    def = symlook_list(name, hash, &list_main, &defobj, true,
1670	      &donelist);
1671	} else {
1672	    /*
1673	     * XXX - This isn't correct.  The search should include the whole
1674	     * DAG rooted at the given object.
1675	     */
1676	    def = symlook_obj(name, hash, obj, true);
1677	    defobj = obj;
1678	}
1679    }
1680
1681    if (def != NULL) {
1682	rlock_release();
1683
1684	/*
1685	 * The value required by the caller is derived from the value
1686	 * of the symbol. For the ia64 architecture, we need to
1687	 * construct a function descriptor which the caller can use to
1688	 * call the function with the right 'gp' value. For other
1689	 * architectures and for non-functions, the value is simply
1690	 * the relocated value of the symbol.
1691	 */
1692	if (ELF_ST_TYPE(def->st_info) == STT_FUNC)
1693	    return make_function_pointer(def, defobj);
1694	else
1695	    return defobj->relocbase + def->st_value;
1696    }
1697
1698    _rtld_error("Undefined symbol \"%s\"", name);
1699    rlock_release();
1700    return NULL;
1701}
1702
1703int
1704dladdr(const void *addr, Dl_info *info)
1705{
1706    const Obj_Entry *obj;
1707    const Elf_Sym *def;
1708    void *symbol_addr;
1709    unsigned long symoffset;
1710
1711    rlock_acquire();
1712    obj = obj_from_addr(addr);
1713    if (obj == NULL) {
1714        _rtld_error("No shared object contains address");
1715	rlock_release();
1716        return 0;
1717    }
1718    info->dli_fname = obj->path;
1719    info->dli_fbase = obj->mapbase;
1720    info->dli_saddr = (void *)0;
1721    info->dli_sname = NULL;
1722
1723    /*
1724     * Walk the symbol list looking for the symbol whose address is
1725     * closest to the address sent in.
1726     */
1727    for (symoffset = 0; symoffset < obj->nchains; symoffset++) {
1728        def = obj->symtab + symoffset;
1729
1730        /*
1731         * For skip the symbol if st_shndx is either SHN_UNDEF or
1732         * SHN_COMMON.
1733         */
1734        if (def->st_shndx == SHN_UNDEF || def->st_shndx == SHN_COMMON)
1735            continue;
1736
1737        /*
1738         * If the symbol is greater than the specified address, or if it
1739         * is further away from addr than the current nearest symbol,
1740         * then reject it.
1741         */
1742        symbol_addr = obj->relocbase + def->st_value;
1743        if (symbol_addr > addr || symbol_addr < info->dli_saddr)
1744            continue;
1745
1746        /* Update our idea of the nearest symbol. */
1747        info->dli_sname = obj->strtab + def->st_name;
1748        info->dli_saddr = symbol_addr;
1749
1750        /* Exact match? */
1751        if (info->dli_saddr == addr)
1752            break;
1753    }
1754    rlock_release();
1755    return 1;
1756}
1757
1758static void
1759linkmap_add(Obj_Entry *obj)
1760{
1761    struct link_map *l = &obj->linkmap;
1762    struct link_map *prev;
1763
1764    obj->linkmap.l_name = obj->path;
1765    obj->linkmap.l_addr = obj->mapbase;
1766    obj->linkmap.l_ld = obj->dynamic;
1767#ifdef __mips__
1768    /* GDB needs load offset on MIPS to use the symbols */
1769    obj->linkmap.l_offs = obj->relocbase;
1770#endif
1771
1772    if (r_debug.r_map == NULL) {
1773	r_debug.r_map = l;
1774	return;
1775    }
1776
1777    /*
1778     * Scan to the end of the list, but not past the entry for the
1779     * dynamic linker, which we want to keep at the very end.
1780     */
1781    for (prev = r_debug.r_map;
1782      prev->l_next != NULL && prev->l_next != &obj_rtld.linkmap;
1783      prev = prev->l_next)
1784	;
1785
1786    /* Link in the new entry. */
1787    l->l_prev = prev;
1788    l->l_next = prev->l_next;
1789    if (l->l_next != NULL)
1790	l->l_next->l_prev = l;
1791    prev->l_next = l;
1792}
1793
1794static void
1795linkmap_delete(Obj_Entry *obj)
1796{
1797    struct link_map *l = &obj->linkmap;
1798
1799    if (l->l_prev == NULL) {
1800	if ((r_debug.r_map = l->l_next) != NULL)
1801	    l->l_next->l_prev = NULL;
1802	return;
1803    }
1804
1805    if ((l->l_prev->l_next = l->l_next) != NULL)
1806	l->l_next->l_prev = l->l_prev;
1807}
1808
1809/*
1810 * Function for the debugger to set a breakpoint on to gain control.
1811 *
1812 * The two parameters allow the debugger to easily find and determine
1813 * what the runtime loader is doing and to whom it is doing it.
1814 *
1815 * When the loadhook trap is hit (r_debug_state, set at program
1816 * initialization), the arguments can be found on the stack:
1817 *
1818 *  +8   struct link_map *m
1819 *  +4   struct r_debug  *rd
1820 *  +0   RetAddr
1821 */
1822void
1823r_debug_state(struct r_debug* rd, struct link_map *m)
1824{
1825}
1826
1827/*
1828 * Get address of the pointer variable in the main program.
1829 */
1830static const void **
1831get_program_var_addr(const char *name)
1832{
1833    const Obj_Entry *obj;
1834    unsigned long hash;
1835
1836    hash = elf_hash(name);
1837    for (obj = obj_main;  obj != NULL;  obj = obj->next) {
1838	const Elf_Sym *def;
1839
1840	if ((def = symlook_obj(name, hash, obj, false)) != NULL) {
1841	    const void **addr;
1842
1843	    addr = (const void **)(obj->relocbase + def->st_value);
1844	    return addr;
1845	}
1846    }
1847    return NULL;
1848}
1849
1850/*
1851 * Set a pointer variable in the main program to the given value.  This
1852 * is used to set key variables such as "environ" before any of the
1853 * init functions are called.
1854 */
1855static void
1856set_program_var(const char *name, const void *value)
1857{
1858    const void **addr;
1859
1860    if ((addr = get_program_var_addr(name)) != NULL) {
1861	dbg("\"%s\": *%p <-- %p", name, addr, value);
1862	*addr = value;
1863    }
1864}
1865
1866/*
1867 * Given a symbol name in a referencing object, find the corresponding
1868 * definition of the symbol.  Returns a pointer to the symbol, or NULL if
1869 * no definition was found.  Returns a pointer to the Obj_Entry of the
1870 * defining object via the reference parameter DEFOBJ_OUT.
1871 */
1872static const Elf_Sym *
1873symlook_default(const char *name, unsigned long hash,
1874    const Obj_Entry *refobj, const Obj_Entry **defobj_out, bool in_plt)
1875{
1876    DoneList donelist;
1877    const Elf_Sym *def;
1878    const Elf_Sym *symp;
1879    const Obj_Entry *obj;
1880    const Obj_Entry *defobj;
1881    const Objlist_Entry *elm;
1882    def = NULL;
1883    defobj = NULL;
1884    donelist_init(&donelist);
1885
1886    /* Look first in the referencing object if linked symbolically. */
1887    if (refobj->symbolic && !donelist_check(&donelist, refobj)) {
1888	symp = symlook_obj(name, hash, refobj, in_plt);
1889	if (symp != NULL) {
1890	    def = symp;
1891	    defobj = refobj;
1892	}
1893    }
1894
1895    /* Search all objects loaded at program start up. */
1896    if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
1897	symp = symlook_list(name, hash, &list_main, &obj, in_plt, &donelist);
1898	if (symp != NULL &&
1899	  (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
1900	    def = symp;
1901	    defobj = obj;
1902	}
1903    }
1904
1905    /* Search all dlopened DAGs containing the referencing object. */
1906    STAILQ_FOREACH(elm, &refobj->dldags, link) {
1907	if (def != NULL && ELF_ST_BIND(def->st_info) != STB_WEAK)
1908	    break;
1909	symp = symlook_list(name, hash, &elm->obj->dagmembers, &obj, in_plt,
1910	  &donelist);
1911	if (symp != NULL &&
1912	  (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
1913	    def = symp;
1914	    defobj = obj;
1915	}
1916    }
1917
1918    /* Search all RTLD_GLOBAL objects. */
1919    if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
1920	symp = symlook_list(name, hash, &list_global, &obj, in_plt, &donelist);
1921	if (symp != NULL &&
1922	  (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
1923	    def = symp;
1924	    defobj = obj;
1925	}
1926    }
1927
1928    /*
1929     * Search the dynamic linker itself, and possibly resolve the
1930     * symbol from there.  This is how the application links to
1931     * dynamic linker services such as dlopen.  Only the values listed
1932     * in the "exports" array can be resolved from the dynamic linker.
1933     */
1934    if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
1935	symp = symlook_obj(name, hash, &obj_rtld, in_plt);
1936	if (symp != NULL && is_exported(symp)) {
1937	    def = symp;
1938	    defobj = &obj_rtld;
1939	}
1940    }
1941
1942    if (def != NULL)
1943	*defobj_out = defobj;
1944    return def;
1945}
1946
1947static const Elf_Sym *
1948symlook_list(const char *name, unsigned long hash, Objlist *objlist,
1949  const Obj_Entry **defobj_out, bool in_plt, DoneList *dlp)
1950{
1951    const Elf_Sym *symp;
1952    const Elf_Sym *def;
1953    const Obj_Entry *defobj;
1954    const Objlist_Entry *elm;
1955
1956    def = NULL;
1957    defobj = NULL;
1958    STAILQ_FOREACH(elm, objlist, link) {
1959	if (donelist_check(dlp, elm->obj))
1960	    continue;
1961	if ((symp = symlook_obj(name, hash, elm->obj, in_plt)) != NULL) {
1962	    if (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK) {
1963		def = symp;
1964		defobj = elm->obj;
1965		if (ELF_ST_BIND(def->st_info) != STB_WEAK)
1966		    break;
1967	    }
1968	}
1969    }
1970    if (def != NULL)
1971	*defobj_out = defobj;
1972    return def;
1973}
1974
1975/*
1976 * Search the symbol table of a single shared object for a symbol of
1977 * the given name.  Returns a pointer to the symbol, or NULL if no
1978 * definition was found.
1979 *
1980 * The symbol's hash value is passed in for efficiency reasons; that
1981 * eliminates many recomputations of the hash value.
1982 */
1983const Elf_Sym *
1984symlook_obj(const char *name, unsigned long hash, const Obj_Entry *obj,
1985  bool in_plt)
1986{
1987    if (obj->buckets != NULL) {
1988	unsigned long symnum = obj->buckets[hash % obj->nbuckets];
1989
1990	while (symnum != STN_UNDEF) {
1991	    const Elf_Sym *symp;
1992	    const char *strp;
1993
1994	    if (symnum >= obj->nchains)
1995		return NULL;	/* Bad object */
1996	    symp = obj->symtab + symnum;
1997	    strp = obj->strtab + symp->st_name;
1998
1999	    if (name[0] == strp[0] && strcmp(name, strp) == 0)
2000		return symp->st_shndx != SHN_UNDEF ||
2001		  (!in_plt && symp->st_value != 0 &&
2002		  ELF_ST_TYPE(symp->st_info) == STT_FUNC) ? symp : NULL;
2003
2004	    symnum = obj->chains[symnum];
2005	}
2006    }
2007    return NULL;
2008}
2009
2010static void
2011trace_loaded_objects(Obj_Entry *obj)
2012{
2013    char	*fmt1, *fmt2, *fmt, *main_local;
2014    int		c;
2015
2016    if ((main_local = getenv("LD_TRACE_LOADED_OBJECTS_PROGNAME")) == NULL)
2017	main_local = "";
2018
2019    if ((fmt1 = getenv("LD_TRACE_LOADED_OBJECTS_FMT1")) == NULL)
2020	fmt1 = "\t%o => %p (%x)\n";
2021
2022    if ((fmt2 = getenv("LD_TRACE_LOADED_OBJECTS_FMT2")) == NULL)
2023	fmt2 = "\t%o (%x)\n";
2024
2025    for (; obj; obj = obj->next) {
2026	Needed_Entry		*needed;
2027	char			*name, *path;
2028	bool			is_lib;
2029
2030	for (needed = obj->needed; needed; needed = needed->next) {
2031	    if (needed->obj != NULL) {
2032		if (needed->obj->traced)
2033		    continue;
2034		needed->obj->traced = true;
2035		path = needed->obj->path;
2036	    } else
2037		path = "not found";
2038
2039	    name = (char *)obj->strtab + needed->name;
2040	    is_lib = strncmp(name, "lib", 3) == 0;	/* XXX - bogus */
2041
2042	    fmt = is_lib ? fmt1 : fmt2;
2043	    while ((c = *fmt++) != '\0') {
2044		switch (c) {
2045		default:
2046		    putchar(c);
2047		    continue;
2048		case '\\':
2049		    switch (c = *fmt) {
2050		    case '\0':
2051			continue;
2052		    case 'n':
2053			putchar('\n');
2054			break;
2055		    case 't':
2056			putchar('\t');
2057			break;
2058		    }
2059		    break;
2060		case '%':
2061		    switch (c = *fmt) {
2062		    case '\0':
2063			continue;
2064		    case '%':
2065		    default:
2066			putchar(c);
2067			break;
2068		    case 'A':
2069			printf("%s", main_local);
2070			break;
2071		    case 'a':
2072			printf("%s", obj_main->path);
2073			break;
2074		    case 'o':
2075			printf("%s", name);
2076			break;
2077#if 0
2078		    case 'm':
2079			printf("%d", sodp->sod_major);
2080			break;
2081		    case 'n':
2082			printf("%d", sodp->sod_minor);
2083			break;
2084#endif
2085		    case 'p':
2086			printf("%s", path);
2087			break;
2088		    case 'x':
2089			printf("%p", needed->obj ? needed->obj->mapbase : 0);
2090			break;
2091		    }
2092		    break;
2093		}
2094		++fmt;
2095	    }
2096	}
2097    }
2098}
2099
2100/*
2101 * Unload a dlopened object and its dependencies from memory and from
2102 * our data structures.  It is assumed that the DAG rooted in the
2103 * object has already been unreferenced, and that the object has a
2104 * reference count of 0.
2105 */
2106static void
2107unload_object(Obj_Entry *root)
2108{
2109    Obj_Entry *obj;
2110    Obj_Entry **linkp;
2111    Objlist_Entry *elm;
2112
2113    assert(root->refcount == 0);
2114
2115    /* Remove the DAG from all objects' DAG lists. */
2116    STAILQ_FOREACH(elm, &root->dagmembers , link)
2117	objlist_remove(&elm->obj->dldags, root);
2118
2119    /* Remove the DAG from the RTLD_GLOBAL list. */
2120    objlist_remove(&list_global, root);
2121
2122    /* Unmap all objects that are no longer referenced. */
2123    linkp = &obj_list->next;
2124    while ((obj = *linkp) != NULL) {
2125	if (obj->refcount == 0) {
2126	    dbg("unloading \"%s\"", obj->path);
2127	    munmap(obj->mapbase, obj->mapsize);
2128	    linkmap_delete(obj);
2129	    *linkp = obj->next;
2130	    obj_count--;
2131	    obj_free(obj);
2132	} else
2133	    linkp = &obj->next;
2134    }
2135    obj_tail = linkp;
2136}
2137
2138static void
2139unref_dag(Obj_Entry *root)
2140{
2141    const Needed_Entry *needed;
2142
2143    if (root->refcount == 0)
2144	return;
2145    root->refcount--;
2146    if (root->refcount == 0)
2147	for (needed = root->needed;  needed != NULL;  needed = needed->next)
2148	    if (needed->obj != NULL)
2149		unref_dag(needed->obj);
2150}
2151
2152/*
2153 * Non-mallocing printf, for use by malloc itself.
2154 * XXX - This doesn't belong in this module.
2155 */
2156void
2157xprintf(const char *fmt, ...)
2158{
2159    char buf[256];
2160    va_list ap;
2161
2162    va_start(ap, fmt);
2163    vsprintf(buf, fmt, ap);
2164    (void)write(STDOUT_FILENO, buf, strlen(buf));
2165    va_end(ap);
2166}
2167