xref: /openbsd-src/libexec/ld.so/loader.c (revision d13be5d47e4149db2549a9828e244d59dbc43f15)
1 /*	$OpenBSD: loader.c,v 1.125 2011/06/27 16:47:50 sthen Exp $ */
2 
3 /*
4  * Copyright (c) 1998 Per Fogelstrom, Opsycon AB
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
16  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
19  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  */
28 
29 #define	_DYN_LOADER
30 
31 #include <sys/types.h>
32 #include <sys/mman.h>
33 #include <sys/exec.h>
34 #include <sys/param.h>
35 #include <sys/sysctl.h>
36 #include <nlist.h>
37 #include <string.h>
38 #include <link.h>
39 #include <dlfcn.h>
40 
41 #include "syscall.h"
42 #include "archdep.h"
43 #include "resolve.h"
44 #include "sod.h"
45 #include "stdlib.h"
46 #include "dl_prebind.h"
47 
48 #include "../../lib/csu/common_elf/os-note-elf.h"
49 
50 /*
51  * Local decls.
52  */
53 static char *_dl_getenv(const char *, char **);
54 static void _dl_unsetenv(const char *, char **);
55 unsigned long _dl_boot(const char **, char **, const long, long *);
56 void _dl_debug_state(void);
57 void _dl_setup_env(char **);
58 void _dl_dtors(void);
59 void _dl_boot_bind(const long, long *, Elf_Dyn *);
60 void _dl_fixup_user_env(void);
61 void _dl_set_sod(const char *, struct sod *);
62 
63 const char *_dl_progname;
64 int  _dl_pagesz;
65 
66 char *_dl_libpath;
67 char *_dl_preload;
68 char *_dl_bindnow;
69 char *_dl_traceld;
70 char *_dl_debug;
71 char *_dl_showmap;
72 char *_dl_norandom;
73 char *_dl_noprebind;
74 char *_dl_prebind_validate;
75 char *_dl_tracefmt1, *_dl_tracefmt2, *_dl_traceprog;
76 
77 struct r_debug *_dl_debug_map;
78 
79 void _dl_dopreload(char *paths);
80 
81 void
82 _dl_set_sod(const char *path, struct sod *sod)
83 {
84 	char *fname = _dl_strrchr(path, '/');
85 
86 	if (fname != NULL)
87 		_dl_build_sod(++fname, sod);
88 	else
89 		_dl_build_sod(path, sod);
90 }
91 
92 /*
93  * Run dtors for all objects that are eligible.
94  */
95 
96 void
97 _dl_run_all_dtors()
98 {
99 	elf_object_t *node;
100 	int fini_complete;
101 	struct dep_node *dnode;
102 
103 	fini_complete = 0;
104 
105 	while (fini_complete == 0) {
106 		fini_complete = 1;
107 		for (node = _dl_objects->next;
108 		    node != NULL;
109 		    node = node->next) {
110 			if ((node->dyn.fini) &&
111 			    (OBJECT_REF_CNT(node) == 0) &&
112 			    (node->status & STAT_INIT_DONE) &&
113 			    ((node->status & STAT_FINI_DONE) == 0)) {
114 				node->status |= STAT_FINI_READY;
115 			    }
116 		}
117 		for (node = _dl_objects->next;
118 		    node != NULL;
119 		    node = node->next ) {
120 			if ((node->dyn.fini) &&
121 			    (OBJECT_REF_CNT(node) == 0) &&
122 			    (node->status & STAT_INIT_DONE) &&
123 			    ((node->status & STAT_FINI_DONE) == 0))
124 				TAILQ_FOREACH(dnode, &node->child_list,
125 				    next_sib)
126 					dnode->data->status &= ~STAT_FINI_READY;
127 		}
128 
129 
130 		for (node = _dl_objects->next;
131 		    node != NULL;
132 		    node = node->next ) {
133 			if (node->status & STAT_FINI_READY) {
134 				DL_DEB(("doing dtors obj %p @%p: [%s]\n",
135 				    node, node->dyn.fini,
136 				    node->load_name));
137 
138 				fini_complete = 0;
139 				node->status |= STAT_FINI_DONE;
140 				node->status &= ~STAT_FINI_READY;
141 				(*node->dyn.fini)();
142 			}
143 		}
144 	}
145 }
146 
147 /*
148  * Routine to walk through all of the objects except the first
149  * (main executable).
150  *
151  * Big question, should dlopen()ed objects be unloaded before or after
152  * the destructor for the main application runs?
153  */
154 void
155 _dl_dtors(void)
156 {
157 	_dl_thread_kern_stop();
158 
159 	/* ORDER? */
160 	_dl_unload_dlopen();
161 
162 	DL_DEB(("doing dtors\n"));
163 
164 	/* main program runs its dtors itself
165 	 * but we want to run dtors on all it's children);
166 	 */
167 	_dl_objects->status |= STAT_FINI_DONE;
168 
169 	_dl_objects->opencount--;
170 	_dl_notify_unload_shlib(_dl_objects);
171 
172 	_dl_run_all_dtors();
173 }
174 
175 void
176 _dl_dopreload(char *paths)
177 {
178 	char		*cp, *dp;
179 	elf_object_t	*shlib;
180 
181 	dp = paths = _dl_strdup(paths);
182 	if (dp == NULL) {
183 		_dl_printf("preload: out of memory");
184 		_dl_exit(1);
185 	}
186 
187 	while ((cp = _dl_strsep(&dp, ":")) != NULL) {
188 		shlib = _dl_load_shlib(cp, _dl_objects, OBJTYPE_LIB,
189 		_dl_objects->obj_flags);
190 		if (shlib == NULL) {
191 			_dl_printf("%s: can't preload library '%s'\n",
192 			    _dl_progname, cp);
193 			_dl_exit(4);
194 		}
195 		_dl_add_object(shlib);
196 		_dl_link_child(shlib, _dl_objects);
197 	}
198 	_dl_free(paths);
199 	return;
200 }
201 
202 /*
203  * grab interesting environment variables, zap bad env vars if
204  * issetugid
205  */
206 char **_dl_so_envp;
207 void
208 _dl_setup_env(char **envp)
209 {
210 	/*
211 	 * Get paths to various things we are going to use.
212 	 */
213 	_dl_libpath = _dl_getenv("LD_LIBRARY_PATH", envp);
214 	_dl_preload = _dl_getenv("LD_PRELOAD", envp);
215 	_dl_bindnow = _dl_getenv("LD_BIND_NOW", envp);
216 	_dl_traceld = _dl_getenv("LD_TRACE_LOADED_OBJECTS", envp);
217 	_dl_tracefmt1 = _dl_getenv("LD_TRACE_LOADED_OBJECTS_FMT1", envp);
218 	_dl_tracefmt2 = _dl_getenv("LD_TRACE_LOADED_OBJECTS_FMT2", envp);
219 	_dl_traceprog = _dl_getenv("LD_TRACE_LOADED_OBJECTS_PROGNAME", envp);
220 	_dl_debug = _dl_getenv("LD_DEBUG", envp);
221 	_dl_norandom = _dl_getenv("LD_NORANDOM", envp);
222 	_dl_noprebind = _dl_getenv("LD_NOPREBIND", envp);
223 	_dl_prebind_validate = _dl_getenv("LD_PREBINDVALIDATE", envp);
224 
225 	/*
226 	 * Don't allow someone to change the search paths if he runs
227 	 * a suid program without credentials high enough.
228 	 */
229 	if (_dl_issetugid()) {	/* Zap paths if s[ug]id... */
230 		if (_dl_libpath) {
231 			_dl_libpath = NULL;
232 			_dl_unsetenv("LD_LIBRARY_PATH", envp);
233 		}
234 		if (_dl_preload) {
235 			_dl_preload = NULL;
236 			_dl_unsetenv("LD_PRELOAD", envp);
237 		}
238 		if (_dl_bindnow) {
239 			_dl_bindnow = NULL;
240 			_dl_unsetenv("LD_BIND_NOW", envp);
241 		}
242 		if (_dl_debug) {
243 			_dl_debug = NULL;
244 			_dl_unsetenv("LD_DEBUG", envp);
245 		}
246 		if (_dl_norandom) {
247 			_dl_norandom = NULL;
248 			_dl_unsetenv("LD_NORANDOM", envp);
249 		}
250 	}
251 	_dl_so_envp = envp;
252 }
253 
254 int
255 _dl_load_dep_libs(elf_object_t *object, int flags, int booting)
256 {
257 	elf_object_t *dynobj;
258 	Elf_Dyn *dynp;
259 	unsigned int loop;
260 	int libcount;
261 	int depflags;
262 
263 	dynobj = object;
264 	while (dynobj) {
265 		DL_DEB(("examining: '%s'\n", dynobj->load_name));
266 		libcount = 0;
267 
268 		/* propagate RTLD_NOW to deplibs (can be set by dynamic tags) */
269 		depflags = flags | (dynobj->obj_flags & RTLD_NOW);
270 
271 		for (dynp = dynobj->load_dyn; dynp->d_tag; dynp++) {
272 			if (dynp->d_tag == DT_NEEDED) {
273 				libcount++;
274 			}
275 		}
276 
277 		if ( libcount != 0) {
278 			struct listent {
279 				Elf_Dyn *dynp;
280 				elf_object_t *depobj;
281 			} *liblist;
282 			int *randomlist;
283 
284 			liblist = _dl_malloc(libcount * sizeof(struct listent));
285 			randomlist =  _dl_malloc(libcount * sizeof(int));
286 
287 			if (liblist == NULL)
288 				_dl_exit(5);
289 
290 			for (dynp = dynobj->load_dyn, loop = 0; dynp->d_tag;
291 			    dynp++)
292 				if (dynp->d_tag == DT_NEEDED)
293 					liblist[loop++].dynp = dynp;
294 
295 			/* Randomize these */
296 			for (loop = 0; loop < libcount; loop++)
297 				randomlist[loop] = loop;
298 
299 			if (!_dl_norandom)
300 				for (loop = 1; loop < libcount; loop++) {
301 					unsigned int rnd;
302 					int cur;
303 					rnd = _dl_random();
304 					rnd = rnd % (loop+1);
305 					cur = randomlist[rnd];
306 					randomlist[rnd] = randomlist[loop];
307 					randomlist[loop] = cur;
308 				}
309 
310 			for (loop = 0; loop < libcount; loop++) {
311 				elf_object_t *depobj;
312 				const char *libname;
313 				libname = dynobj->dyn.strtab;
314 				libname +=
315 				    liblist[randomlist[loop]].dynp->d_un.d_val;
316 				DL_DEB(("loading: %s required by %s\n", libname,
317 				    dynobj->load_name));
318 				depobj = _dl_load_shlib(libname, dynobj,
319 				    OBJTYPE_LIB, depflags);
320 				if (depobj == 0) {
321 					if (booting) {
322 						_dl_printf(
323 						    "%s: can't load library '%s'\n",
324 						    _dl_progname, libname);
325 						_dl_exit(4);
326 					} else  {
327 						DL_DEB(("dlopen: failed to open %s\n",
328 						    libname));
329 						_dl_free(liblist);
330 						return (1);
331 					}
332 				}
333 				liblist[randomlist[loop]].depobj = depobj;
334 			}
335 
336 			for (loop = 0; loop < libcount; loop++) {
337 				_dl_add_object(liblist[loop].depobj);
338 				_dl_link_child(liblist[loop].depobj, dynobj);
339 			}
340 			_dl_free(liblist);
341 		}
342 		dynobj = dynobj->next;
343 	}
344 
345 	/* add first object manually */
346 	_dl_link_grpsym(object, 1);
347 	_dl_cache_grpsym_list_setup(object);
348 
349 	return(0);
350 }
351 
352 
353 #define PFLAGS(X) ((((X) & PF_R) ? PROT_READ : 0) | \
354 		   (((X) & PF_W) ? PROT_WRITE : 0) | \
355 		   (((X) & PF_X) ? PROT_EXEC : 0))
356 
357 /*
358  * This is the dynamic loader entrypoint. When entering here, depending
359  * on architecture type, the stack and registers are set up according
360  * to the architectures ABI specification. The first thing required
361  * to do is to dig out all information we need to accomplish our task.
362  */
363 unsigned long
364 _dl_boot(const char **argv, char **envp, const long dyn_loff, long *dl_data)
365 {
366 	struct elf_object *exe_obj;	/* Pointer to executable object */
367 	struct elf_object *dyn_obj;	/* Pointer to executable object */
368 	struct r_debug **map_link;	/* Where to put pointer for gdb */
369 	struct r_debug *debug_map;
370 	struct load_list *next_load, *load_list = NULL;
371 	Elf_Dyn *dynp;
372 	Elf_Phdr *phdp;
373 	Elf_Ehdr *ehdr;
374 	char *us = NULL;
375 	unsigned int loop;
376 	int failed;
377 	struct dep_node *n;
378 	Elf_Addr minva, maxva, exe_loff;
379 	int align;
380 
381 	_dl_setup_env(envp);
382 
383 	_dl_progname = argv[0];
384 	if (dl_data[AUX_pagesz] != 0)
385 		_dl_pagesz = dl_data[AUX_pagesz];
386 	else
387 		_dl_pagesz = 4096;
388 
389 	align = _dl_pagesz - 1;
390 
391 #define ROUND_PG(x) (((x) + align) & ~(align))
392 #define TRUNC_PG(x) ((x) & ~(align))
393 
394 	/*
395 	 * now that GOT and PLT has been relocated, and we know
396 	 * page size, protect it from modification
397 	 */
398 #ifndef  RTLD_NO_WXORX
399 	{
400 		extern char *__got_start;
401 		extern char *__got_end;
402 #ifdef RTLD_PROTECT_PLT
403 		extern char *__plt_start;
404 		extern char *__plt_end;
405 #endif
406 
407 		_dl_mprotect((void *)ELF_TRUNC((long)&__got_start, _dl_pagesz),
408 		    ELF_ROUND((long)&__got_end,_dl_pagesz) -
409 		    ELF_TRUNC((long)&__got_start, _dl_pagesz),
410 		    GOT_PERMS);
411 
412 #ifdef RTLD_PROTECT_PLT
413 		/* only for DATA_PLT or BSS_PLT */
414 		_dl_mprotect((void *)ELF_TRUNC((long)&__plt_start, _dl_pagesz),
415 		    ELF_ROUND((long)&__plt_end,_dl_pagesz) -
416 		    ELF_TRUNC((long)&__plt_start, _dl_pagesz),
417 		    PROT_READ|PROT_EXEC);
418 #endif
419 	}
420 #endif
421 
422 	DL_DEB(("rtld loading: '%s'\n", _dl_progname));
423 
424 	/* init this in runtime, not statically */
425 	TAILQ_INIT(&_dlopened_child_list);
426 
427 	exe_obj = NULL;
428 	_dl_loading_object = NULL;
429 
430 	minva = ELFDEFNNAME(NO_ADDR);
431 	maxva = exe_loff = 0;
432 
433 	/*
434 	 * Examine the user application and set up object information.
435 	 */
436 	phdp = (Elf_Phdr *)dl_data[AUX_phdr];
437 	for (loop = 0; loop < dl_data[AUX_phnum]; loop++) {
438 		switch (phdp->p_type) {
439 		case PT_PHDR:
440 			exe_loff = (Elf_Addr)dl_data[AUX_phdr] - phdp->p_vaddr;
441 			us += exe_loff;
442 			DL_DEB(("exe load offset:  0x%lx\n", exe_loff));
443 			break;
444 		case PT_DYNAMIC:
445 			minva = TRUNC_PG(minva);
446 			maxva = ROUND_PG(maxva);
447 			exe_obj = _dl_finalize_object(argv[0] ? argv[0] : "",
448 			    (Elf_Dyn *)(phdp->p_vaddr + exe_loff),
449 			    (Elf_Phdr *)dl_data[AUX_phdr],
450 			    dl_data[AUX_phnum], OBJTYPE_EXE, minva + exe_loff,
451 			    exe_loff);
452 			_dl_add_object(exe_obj);
453 			break;
454 		case PT_INTERP:
455 			us += phdp->p_vaddr;
456 			break;
457 		case PT_LOAD:
458 			if (phdp->p_vaddr < minva)
459 				minva = phdp->p_vaddr;
460 			if (phdp->p_vaddr > maxva)
461 				maxva = phdp->p_vaddr + phdp->p_memsz;
462 
463 			next_load = _dl_malloc(sizeof(struct load_list));
464 			next_load->next = load_list;
465 			load_list = next_load;
466 			next_load->start = (char *)TRUNC_PG(phdp->p_vaddr) + exe_loff;
467 			next_load->size = (phdp->p_vaddr & align) + phdp->p_filesz;
468 			next_load->prot = PFLAGS(phdp->p_flags);
469 
470 			if (phdp->p_flags & 0x08000000) {
471 //				dump_prelink(phdp->p_vaddr + exe_loff, phdp->p_memsz);
472 				prebind_load_exe(phdp, exe_obj);
473 			}
474 			break;
475 		}
476 		phdp++;
477 	}
478 	exe_obj->load_list = load_list;
479 	exe_obj->obj_flags |= RTLD_GLOBAL;
480 	exe_obj->load_size = maxva - minva;
481 	_dl_set_sod(exe_obj->load_name, &exe_obj->sod);
482 
483 	n = _dl_malloc(sizeof *n);
484 	if (n == NULL)
485 		_dl_exit(5);
486 	n->data = exe_obj;
487 	TAILQ_INSERT_TAIL(&_dlopened_child_list, n, next_sib);
488 	exe_obj->opencount++;
489 
490 	if (_dl_preload != NULL)
491 		_dl_dopreload(_dl_preload);
492 
493 	_dl_load_dep_libs(exe_obj, exe_obj->obj_flags, 1);
494 
495 	/*
496 	 * Now add the dynamic loader itself last in the object list
497 	 * so we can use the _dl_ code when serving dl.... calls.
498 	 * Intentionally left off the exe child_list.
499 	 */
500 	dynp = (Elf_Dyn *)((void *)_DYNAMIC);
501 	ehdr = (Elf_Ehdr *)dl_data[AUX_base];
502         dyn_obj = _dl_finalize_object(us, dynp,
503 	    (Elf_Phdr *)((char *)dl_data[AUX_base] + ehdr->e_phoff),
504 	    ehdr->e_phnum, OBJTYPE_LDR, dl_data[AUX_base], dyn_loff);
505 	_dl_add_object(dyn_obj);
506 
507 	dyn_obj->refcount++;
508 	_dl_link_grpsym(dyn_obj, 1);
509 
510 	dyn_obj->status |= STAT_RELOC_DONE;
511 	_dl_set_sod(dyn_obj->load_name, &dyn_obj->sod);
512 
513 	/*
514 	 * Everything should be in place now for doing the relocation
515 	 * and binding. Call _dl_rtld to do the job. Fingers crossed.
516 	 */
517 
518 	_dl_prebind_pre_resolve();
519 	failed = 0;
520 	if (_dl_traceld == NULL)
521 		failed = _dl_rtld(_dl_objects);
522 
523 	_dl_prebind_post_resolve();
524 
525 	if (_dl_debug || _dl_traceld)
526 		_dl_show_objects();
527 
528 	DL_DEB(("dynamic loading done, %s.\n",
529 	    (failed == 0) ? "success":"failed"));
530 
531 	if (failed != 0)
532 		_dl_exit(1);
533 
534 	if (_dl_traceld)
535 		_dl_exit(0);
536 
537 	_dl_loading_object = NULL;
538 
539 	_dl_fixup_user_env();
540 
541 	/*
542 	 * Finally make something to help gdb when poking around in the code.
543 	 */
544 #ifdef __mips__
545 	map_link = (struct r_debug **)(exe_obj->Dyn.info[DT_MIPS_RLD_MAP -
546 	    DT_LOPROC + DT_NUM]);
547 #else
548 	map_link = NULL;
549 	for (dynp = exe_obj->load_dyn; dynp->d_tag; dynp++) {
550 		if (dynp->d_tag == DT_DEBUG) {
551 			map_link = (struct r_debug **)&dynp->d_un.d_ptr;
552 			break;
553 		}
554 	}
555 	if (dynp->d_tag != DT_DEBUG)
556 		DL_DEB(("failed to mark DTDEBUG\n"));
557 #endif
558 	if (map_link) {
559 		debug_map = (struct r_debug *)_dl_malloc(sizeof(*debug_map));
560 		debug_map->r_version = 1;
561 		debug_map->r_map = (struct link_map *)_dl_objects;
562 		debug_map->r_brk = (Elf_Addr)_dl_debug_state;
563 		debug_map->r_state = RT_CONSISTENT;
564 		debug_map->r_ldbase = dyn_loff;
565 		_dl_debug_map = debug_map;
566 		*map_link = _dl_debug_map;
567 	}
568 
569 	_dl_debug_state();
570 
571 	/*
572 	 * The first object is the executable itself,
573 	 * it is responsible for running it's own ctors/dtors
574 	 * thus do NOT run the ctors for the executable, all of
575 	 * the shared libraries which follow.
576 	 * Do not run init code if run from ldd.
577 	 */
578 	if (_dl_objects->next != NULL) {
579 		_dl_objects->status |= STAT_INIT_DONE;
580 		_dl_call_init(_dl_objects);
581 	}
582 
583 	/*
584 	 * Schedule a routine to be run at shutdown, by using atexit.
585 	 * Cannot call atexit directly from ld.so?
586 	 * Do not schedule destructors if run from ldd.
587 	 */
588 	{
589 		const elf_object_t *sobj;
590 		const Elf_Sym *sym;
591 		Elf_Addr ooff;
592 
593 		sym = NULL;
594 		ooff = _dl_find_symbol("atexit", &sym,
595 		    SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT,
596 		    NULL, dyn_obj, &sobj);
597 		if (sym == NULL)
598 			_dl_printf("cannot find atexit, destructors will not be run!\n");
599 		else
600 #ifdef MD_ATEXIT
601 			MD_ATEXIT(sobj, sym, (Elf_Addr)&_dl_dtors);
602 #else
603 			(*(void (*)(Elf_Addr))(sym->st_value + ooff))
604 			    ((Elf_Addr)_dl_dtors);
605 #endif
606 	}
607 
608 	DL_DEB(("entry point: 0x%lx\n", dl_data[AUX_entry]));
609 
610 	/*
611 	 * Return the entry point.
612 	 */
613 	return(dl_data[AUX_entry]);
614 }
615 
616 void
617 _dl_boot_bind(const long sp, long *dl_data, Elf_Dyn *dynamicp)
618 {
619 	struct elf_object  dynld;	/* Resolver data for the loader */
620 	AuxInfo		*auxstack;
621 	long		*stack;
622 	Elf_Dyn		*dynp;
623 	int		n, argc;
624 	char **argv, **envp;
625 	long loff;
626 
627 	/*
628 	 * Scan argument and environment vectors. Find dynamic
629 	 * data vector put after them.
630 	 */
631 	stack = (long *)sp;
632 	argc = *stack++;
633 	argv = (char **)stack;
634 	envp = &argv[argc + 1];
635 	stack = (long *)envp;
636 	while (*stack++ != 0L)
637 		;
638 
639 	/*
640 	 * Zero out dl_data.
641 	 */
642 	for (n = 0; n <= AUX_entry; n++)
643 		dl_data[n] = 0;
644 
645 	/*
646 	 * Dig out auxiliary data set up by exec call. Move all known
647 	 * tags to an indexed local table for easy access.
648 	 */
649 	for (auxstack = (AuxInfo *)stack; auxstack->au_id != AUX_null;
650 	    auxstack++) {
651 		if (auxstack->au_id > AUX_entry)
652 			continue;
653 		dl_data[auxstack->au_id] = auxstack->au_v;
654 	}
655 	loff = dl_data[AUX_base];	/* XXX assumes ld.so is linked at 0x0 */
656 
657 	/*
658 	 * We need to do 'selfreloc' in case the code weren't
659 	 * loaded at the address it was linked to.
660 	 *
661 	 * Scan the DYNAMIC section for the loader.
662 	 * Cache the data for easier access.
663 	 */
664 
665 #if defined(__alpha__)
666 	dynp = (Elf_Dyn *)((long)_DYNAMIC);
667 #elif defined(__sparc__) || defined(__sparc64__) || defined(__powerpc__) || \
668     defined(__hppa__) || defined(__sh__)
669 	dynp = dynamicp;
670 #else
671 	dynp = (Elf_Dyn *)((long)_DYNAMIC + loff);
672 #endif
673 	while (dynp != NULL && dynp->d_tag != DT_NULL) {
674 		if (dynp->d_tag < DT_NUM)
675 			dynld.Dyn.info[dynp->d_tag] = dynp->d_un.d_val;
676 		else if (dynp->d_tag >= DT_LOPROC &&
677 		    dynp->d_tag < DT_LOPROC + DT_PROCNUM)
678 			dynld.Dyn.info[dynp->d_tag - DT_LOPROC + DT_NUM] =
679 			    dynp->d_un.d_val;
680 		if (dynp->d_tag == DT_TEXTREL)
681 			dynld.dyn.textrel = 1;
682 		dynp++;
683 	}
684 
685 	/*
686 	 * Do the 'bootstrap relocation'. This is really only needed if
687 	 * the code was loaded at another location than it was linked to.
688 	 * We don't do undefined symbols resolving (to difficult..)
689 	 */
690 
691 	/* "relocate" dyn.X values if they represent addresses */
692 	{
693 		int i, val;
694 		/* must be code, not pic data */
695 		int table[20];
696 
697 		i = 0;
698 		table[i++] = DT_PLTGOT;
699 		table[i++] = DT_HASH;
700 		table[i++] = DT_STRTAB;
701 		table[i++] = DT_SYMTAB;
702 		table[i++] = DT_RELA;
703 		table[i++] = DT_INIT;
704 		table[i++] = DT_FINI;
705 		table[i++] = DT_REL;
706 		table[i++] = DT_JMPREL;
707 		/* other processors insert their extras here */
708 		table[i++] = DT_NULL;
709 		for (i = 0; table[i] != DT_NULL; i++) {
710 			val = table[i];
711 			if (val > DT_HIPROC) /* ??? */
712 				continue;
713 			if (val > DT_LOPROC)
714 				val -= DT_LOPROC + DT_NUM;
715 			if (dynld.Dyn.info[val] != 0)
716 				dynld.Dyn.info[val] += loff;
717 		}
718 	}
719 
720 	{
721 		u_int32_t rs;
722 		Elf_Rel *rp;
723 		int	i;
724 
725 		rp = (Elf_Rel *)(dynld.Dyn.info[DT_REL]);
726 		rs = dynld.dyn.relsz;
727 
728 		for (i = 0; i < rs; i += sizeof (Elf_Rel)) {
729 			Elf_Addr *ra;
730 			const Elf_Sym *sp;
731 
732 			sp = dynld.dyn.symtab;
733 			sp += ELF_R_SYM(rp->r_info);
734 
735 			if (ELF_R_SYM(rp->r_info) && sp->st_value == 0) {
736 #if 0
737 /* cannot printf in this function */
738 				_dl_wrstderr("Dynamic loader failure: self bootstrapping impossible.\n");
739 				_dl_wrstderr("Undefined symbol: ");
740 				_dl_wrstderr((char *)dynld.dyn.strtab +
741 				    sp->st_name);
742 #endif
743 				_dl_exit(5);
744 			}
745 
746 			ra = (Elf_Addr *)(rp->r_offset + loff);
747 			RELOC_REL(rp, sp, ra, loff);
748 			rp++;
749 		}
750 	}
751 
752 	for (n = 0; n < 2; n++) {
753 		unsigned long rs;
754 		Elf_RelA *rp;
755 		int	i;
756 
757 		switch (n) {
758 		case 0:
759 			rp = (Elf_RelA *)(dynld.Dyn.info[DT_JMPREL]);
760 			rs = dynld.dyn.pltrelsz;
761 			break;
762 		case 1:
763 			rp = (Elf_RelA *)(dynld.Dyn.info[DT_RELA]);
764 			rs = dynld.dyn.relasz;
765 			break;
766 		default:
767 			rp = NULL;
768 			rs = 0;
769 		}
770 		for (i = 0; i < rs; i += sizeof (Elf_RelA)) {
771 			Elf_Addr *ra;
772 			const Elf_Sym *sp;
773 
774 			sp = dynld.dyn.symtab;
775 			sp += ELF_R_SYM(rp->r_info);
776 			if (ELF_R_SYM(rp->r_info) && sp->st_value == 0) {
777 #if 0
778 				_dl_wrstderr("Dynamic loader failure: self bootstrapping impossible.\n");
779 				_dl_wrstderr("Undefined symbol: ");
780 				_dl_wrstderr((char *)dynld.dyn.strtab +
781 				    sp->st_name);
782 #endif
783 				_dl_exit(6);
784 			}
785 
786 			ra = (Elf_Addr *)(rp->r_offset + loff);
787 			RELOC_RELA(rp, sp, ra, loff, dynld.dyn.pltgot);
788 			rp++;
789 		}
790 	}
791 
792 	RELOC_GOT(&dynld, loff);
793 
794 	/*
795 	 * we have been fully relocated here, so most things no longer
796 	 * need the loff adjustment
797 	 */
798 }
799 
800 #define DL_SM_SYMBUF_CNT 512
801 sym_cache _dl_sm_symcache_buffer[DL_SM_SYMBUF_CNT];
802 
803 int
804 _dl_rtld(elf_object_t *object)
805 {
806 	size_t sz;
807 	int fails = 0;
808 
809 	if (object->next)
810 		fails += _dl_rtld(object->next);
811 
812 	if (object->status & STAT_RELOC_DONE)
813 		return 0;
814 
815 	sz = 0;
816 	if (object->nchains < DL_SM_SYMBUF_CNT) {
817 		_dl_symcache = _dl_sm_symcache_buffer;
818 //		DL_DEB(("using static buffer for %d entries\n",
819 //		    object->nchains));
820 		_dl_memset(_dl_symcache, 0,
821 		    sizeof (sym_cache) * object->nchains);
822 	} else {
823 		sz = ELF_ROUND(sizeof (sym_cache) * object->nchains,
824 		    _dl_pagesz);
825 //		DL_DEB(("allocating symcache sz %x with mmap\n", sz));
826 
827 		_dl_symcache = (void *)_dl_mmap(0, sz, PROT_READ|PROT_WRITE,
828 		    MAP_PRIVATE|MAP_ANON, -1, 0);
829 		if (_dl_mmap_error(_dl_symcache)) {
830 			sz = 0;
831 			_dl_symcache = NULL;
832 		}
833 	}
834 	prebind_symcache(object, SYM_NOTPLT);
835 
836 	/*
837 	 * Do relocation information first, then GOT.
838 	 */
839 	fails =_dl_md_reloc(object, DT_REL, DT_RELSZ);
840 	fails += _dl_md_reloc(object, DT_RELA, DT_RELASZ);
841 	prebind_symcache(object, SYM_PLT);
842 	fails += _dl_md_reloc_got(object, !(_dl_bindnow ||
843 	    object->obj_flags & RTLD_NOW));
844 
845 	if (_dl_symcache != NULL) {
846 		if (sz != 0)
847 			_dl_munmap( _dl_symcache, sz);
848 		_dl_symcache = NULL;
849 	}
850 	if (fails == 0)
851 		object->status |= STAT_RELOC_DONE;
852 
853 	return (fails);
854 }
855 void
856 _dl_call_init(elf_object_t *object)
857 {
858 	struct dep_node *n;
859 
860 	TAILQ_FOREACH(n, &object->child_list, next_sib) {
861 		if (n->data->status & STAT_INIT_DONE)
862 			continue;
863 		_dl_call_init(n->data);
864 	}
865 
866 	if (object->status & STAT_INIT_DONE)
867 		return;
868 
869 	if (object->dyn.init) {
870 		DL_DEB(("doing ctors obj %p @%p: [%s]\n",
871 		    object, object->dyn.init, object->load_name));
872 		(*object->dyn.init)();
873 	}
874 
875 	/* What about loops? */
876 	object->status |= STAT_INIT_DONE;
877 }
878 
879 static char *
880 _dl_getenv(const char *var, char **env)
881 {
882 	const char *ep;
883 
884 	while ((ep = *env++)) {
885 		const char *vp = var;
886 
887 		while (*vp && *vp == *ep) {
888 			vp++;
889 			ep++;
890 		}
891 		if (*vp == '\0' && *ep++ == '=')
892 			return((char *)ep);
893 	}
894 	return(NULL);
895 }
896 
897 static void
898 _dl_unsetenv(const char *var, char **env)
899 {
900 	char *ep;
901 
902 	while ((ep = *env)) {
903 		const char *vp = var;
904 
905 		while (*vp && *vp == *ep) {
906 			vp++;
907 			ep++;
908 		}
909 		if (*vp == '\0' && *ep++ == '=') {
910 			char **P;
911 
912 			for (P = env;; ++P)
913 				if (!(*P = *(P + 1)))
914 					break;
915 		} else
916 			env++;
917 	}
918 }
919 
920 /*
921  * _dl_fixup_user_env()
922  *
923  * Set the user environment so that programs can use the environment
924  * while running constructors. Specifically, MALLOC_OPTIONS= for malloc()
925  */
926 void
927 _dl_fixup_user_env(void)
928 {
929 	const Elf_Sym *sym;
930 	Elf_Addr ooff;
931 	struct elf_object dummy_obj;
932 
933 	dummy_obj.dyn.symbolic = 0;
934 	dummy_obj.load_name = "ld.so";
935 
936 	sym = NULL;
937 	ooff = _dl_find_symbol("environ", &sym,
938 	    SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT, NULL, &dummy_obj, NULL);
939 	if (sym != NULL)
940 		*((char ***)(sym->st_value + ooff)) = _dl_so_envp;
941 }
942