xref: /openbsd-src/libexec/ld.so/loader.c (revision 5a38ef86d0b61900239c7913d24a05e7b88a58f0)
1 /*	$OpenBSD: loader.c,v 1.193 2021/11/12 22:28:13 guenther 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/sysctl.h>
35 #include <machine/vmparam.h>
36 #include <nlist.h>
37 #include <string.h>
38 #include <link.h>
39 #include <limits.h>			/* NAME_MAX */
40 #include <dlfcn.h>
41 #include <tib.h>
42 
43 #include "syscall.h"
44 #include "archdep.h"
45 #include "path.h"
46 #include "resolve.h"
47 #include "sod.h"
48 #include "stdlib.h"
49 
50 /*
51  * Local decls.
52  */
53 unsigned long _dl_boot(const char **, char **, const long, long *) __boot;
54 void _dl_debug_state(void);
55 void _dl_setup_env(const char *_argv0, char **_envp) __boot;
56 void _dl_dtors(void);
57 void _dl_dopreload(char *_paths) __boot;
58 void _dl_fixup_user_env(void) __boot;
59 void _dl_call_preinit(elf_object_t *) __boot;
60 void _dl_call_init_recurse(elf_object_t *object, int initfirst);
61 void _dl_clean_boot(void);
62 static inline void unprotect_if_textrel(elf_object_t *_object);
63 static inline void reprotect_if_textrel(elf_object_t *_object);
64 static void _dl_rreloc(elf_object_t *_object);
65 
66 int _dl_pagesz __relro = 4096;
67 int _dl_bindnow __relro = 0;
68 int _dl_debug __relro = 0;
69 int _dl_trust __relro = 0;
70 char **_dl_libpath __relro = NULL;
71 const char **_dl_argv __relro = NULL;
72 int _dl_argc __relro = 0;
73 
74 char *_dl_preload __boot_data = NULL;
75 char *_dl_tracefmt1 __boot_data = NULL;
76 char *_dl_tracefmt2 __boot_data = NULL;
77 char *_dl_traceprog __boot_data = NULL;
78 void *_dl_exec_hint __boot_data = NULL;
79 
80 char **environ = NULL;
81 char *__progname = NULL;
82 
83 int _dl_traceld;
84 struct r_debug *_dl_debug_map;
85 
86 static dl_cb_cb _dl_cb_cb;
87 const struct dl_cb_0 callbacks_0 = {
88 	.dl_allocate_tib	= &_dl_allocate_tib,
89 	.dl_free_tib		= &_dl_free_tib,
90 #if DO_CLEAN_BOOT
91 	.dl_clean_boot		= &_dl_clean_boot,
92 #endif
93 	.dlopen			= &dlopen,
94 	.dlclose		= &dlclose,
95 	.dlsym			= &dlsym,
96 	.dladdr			= &dladdr,
97 	.dlctl			= &dlctl,
98 	.dlerror		= &dlerror,
99 	.dl_iterate_phdr	= &dl_iterate_phdr,
100 };
101 
102 
103 /*
104  * Run dtors for a single object.
105  */
106 void
107 _dl_run_dtors(elf_object_t *obj)
108 {
109 	if (obj->dyn.fini_array) {
110 		int num = obj->dyn.fini_arraysz / sizeof(Elf_Addr);
111 		int i;
112 
113 		DL_DEB(("doing finiarray obj %p @%p: [%s]\n",
114 		    obj, obj->dyn.fini_array, obj->load_name));
115 		for (i = num; i > 0; i--)
116 			(*obj->dyn.fini_array[i-1])();
117 	}
118 
119 	if (obj->dyn.fini) {
120 		DL_DEB(("doing dtors obj %p @%p: [%s]\n",
121 		    obj, obj->dyn.fini, obj->load_name));
122 		(*obj->dyn.fini)();
123 	}
124 }
125 
126 /*
127  * Run dtors for all objects that are eligible.
128  */
129 void
130 _dl_run_all_dtors(void)
131 {
132 	elf_object_t *node;
133 	int fini_complete;
134 	int skip_initfirst;
135 	int initfirst_skipped;
136 
137 	fini_complete = 0;
138 	skip_initfirst = 1;
139 	initfirst_skipped = 0;
140 
141 	while (fini_complete == 0) {
142 		fini_complete = 1;
143 		for (node = _dl_objects;
144 		    node != NULL;
145 		    node = node->next) {
146 			if ((node->dyn.fini || node->dyn.fini_array) &&
147 			    (OBJECT_REF_CNT(node) == 0) &&
148 			    (node->status & STAT_INIT_DONE) &&
149 			    ((node->status & STAT_FINI_DONE) == 0)) {
150 				if (skip_initfirst &&
151 				    (node->obj_flags & DF_1_INITFIRST))
152 					initfirst_skipped = 1;
153 				else
154 					node->status |= STAT_FINI_READY;
155 			    }
156 		}
157 		for (node = _dl_objects;
158 		    node != NULL;
159 		    node = node->next ) {
160 			if ((node->dyn.fini || node->dyn.fini_array) &&
161 			    (OBJECT_REF_CNT(node) == 0) &&
162 			    (node->status & STAT_INIT_DONE) &&
163 			    ((node->status & STAT_FINI_DONE) == 0) &&
164 			    (!skip_initfirst ||
165 			    (node->obj_flags & DF_1_INITFIRST) == 0)) {
166 				struct object_vector vec = node->child_vec;
167 				int i;
168 
169 				for (i = 0; i < vec.len; i++)
170 					vec.vec[i]->status &= ~STAT_FINI_READY;
171 			}
172 		}
173 
174 
175 		for (node = _dl_objects;
176 		    node != NULL;
177 		    node = node->next ) {
178 			if (node->status & STAT_FINI_READY) {
179 				fini_complete = 0;
180 				node->status |= STAT_FINI_DONE;
181 				node->status &= ~STAT_FINI_READY;
182 				_dl_run_dtors(node);
183 			}
184 		}
185 
186 		if (fini_complete && initfirst_skipped)
187 			fini_complete = initfirst_skipped = skip_initfirst = 0;
188 	}
189 }
190 
191 /*
192  * Routine to walk through all of the objects except the first
193  * (main executable).
194  *
195  * Big question, should dlopen()ed objects be unloaded before or after
196  * the destructor for the main application runs?
197  */
198 void
199 _dl_dtors(void)
200 {
201 	_dl_thread_kern_stop();
202 
203 	/* ORDER? */
204 	_dl_unload_dlopen();
205 
206 	DL_DEB(("doing dtors\n"));
207 
208 	_dl_objects->opencount--;
209 	_dl_notify_unload_shlib(_dl_objects);
210 
211 	_dl_run_all_dtors();
212 }
213 
214 #if DO_CLEAN_BOOT
215 void
216 _dl_clean_boot(void)
217 {
218 	extern char boot_text_start[], boot_text_end[];
219 #if 0	/* XXX breaks boehm-gc?!? */
220 	extern char boot_data_start[], boot_data_end[];
221 #endif
222 
223 	_dl_munmap(boot_text_start, boot_text_end - boot_text_start);
224 #if 0	/* XXX breaks boehm-gc?!? */
225 	_dl_munmap(boot_data_start, boot_data_end - boot_data_start);
226 #endif
227 }
228 #endif /* DO_CLEAN_BOOT */
229 
230 void
231 _dl_dopreload(char *paths)
232 {
233 	char		*cp, *dp;
234 	elf_object_t	*shlib;
235 	int		count;
236 
237 	dp = paths = _dl_strdup(paths);
238 	if (dp == NULL)
239 		_dl_oom();
240 
241 	/* preallocate child_vec for the LD_PRELOAD objects */
242 	count = 1;
243 	while (*dp++ != '\0')
244 		if (*dp == ':')
245 			count++;
246 	object_vec_grow(&_dl_objects->child_vec, count);
247 
248 	dp = paths;
249 	while ((cp = _dl_strsep(&dp, ":")) != NULL) {
250 		shlib = _dl_load_shlib(cp, _dl_objects, OBJTYPE_LIB,
251 		    _dl_objects->obj_flags);
252 		if (shlib == NULL)
253 			_dl_die("can't preload library '%s'", cp);
254 		_dl_add_object(shlib);
255 		_dl_link_child(shlib, _dl_objects);
256 	}
257 	_dl_free(paths);
258 	return;
259 }
260 
261 /*
262  * grab interesting environment variables, zap bad env vars if
263  * issetugid, and set the exported environ and __progname variables
264  */
265 void
266 _dl_setup_env(const char *argv0, char **envp)
267 {
268 	static char progname_storage[NAME_MAX+1] = "";
269 
270 	/*
271 	 * Don't allow someone to change the search paths if he runs
272 	 * a suid program without credentials high enough.
273 	 */
274 	_dl_trust = !_dl_issetugid();
275 	if (!_dl_trust) {	/* Zap paths if s[ug]id... */
276 		_dl_unsetenv("LD_DEBUG", envp);
277 		_dl_unsetenv("LD_LIBRARY_PATH", envp);
278 		_dl_unsetenv("LD_PRELOAD", envp);
279 		_dl_unsetenv("LD_BIND_NOW", envp);
280 	} else {
281 		/*
282 		 * Get paths to various things we are going to use.
283 		 */
284 		_dl_debug = _dl_getenv("LD_DEBUG", envp) != NULL;
285 		_dl_libpath = _dl_split_path(_dl_getenv("LD_LIBRARY_PATH",
286 		    envp));
287 		_dl_preload = _dl_getenv("LD_PRELOAD", envp);
288 		_dl_bindnow = _dl_getenv("LD_BIND_NOW", envp) != NULL;
289 	}
290 
291 	/* these are usable even in setugid processes */
292 	_dl_traceld = _dl_getenv("LD_TRACE_LOADED_OBJECTS", envp) != NULL;
293 	_dl_tracefmt1 = _dl_getenv("LD_TRACE_LOADED_OBJECTS_FMT1", envp);
294 	_dl_tracefmt2 = _dl_getenv("LD_TRACE_LOADED_OBJECTS_FMT2", envp);
295 	_dl_traceprog = _dl_getenv("LD_TRACE_LOADED_OBJECTS_PROGNAME", envp);
296 
297 	environ = envp;
298 
299 	_dl_trace_setup(envp);
300 
301 	if (argv0 != NULL) {		/* NULL ptr if argc = 0 */
302 		const char *p = _dl_strrchr(argv0, '/');
303 
304 		if (p == NULL)
305 			p = argv0;
306 		else
307 			p++;
308 		_dl_strlcpy(progname_storage, p, sizeof(progname_storage));
309 	}
310 	__progname = progname_storage;
311 }
312 
313 int
314 _dl_load_dep_libs(elf_object_t *object, int flags, int booting)
315 {
316 	elf_object_t *dynobj;
317 	Elf_Dyn *dynp;
318 	unsigned int loop;
319 	int libcount;
320 	int depflags;
321 
322 	dynobj = object;
323 	while (dynobj) {
324 		DL_DEB(("examining: '%s'\n", dynobj->load_name));
325 		libcount = 0;
326 
327 		/* propagate DF_1_NOW to deplibs (can be set by dynamic tags) */
328 		depflags = flags | (dynobj->obj_flags & DF_1_NOW);
329 
330 		for (dynp = dynobj->load_dyn; dynp->d_tag; dynp++) {
331 			if (dynp->d_tag == DT_NEEDED) {
332 				libcount++;
333 			}
334 		}
335 
336 		if ( libcount != 0) {
337 			struct listent {
338 				Elf_Dyn *dynp;
339 				elf_object_t *depobj;
340 			} *liblist;
341 			int *randomlist;
342 
343 			liblist = _dl_reallocarray(NULL, libcount,
344 			    sizeof(struct listent));
345 			randomlist =  _dl_reallocarray(NULL, libcount,
346 			    sizeof(int));
347 
348 			if (liblist == NULL || randomlist == NULL)
349 				_dl_oom();
350 
351 			for (dynp = dynobj->load_dyn, loop = 0; dynp->d_tag;
352 			    dynp++)
353 				if (dynp->d_tag == DT_NEEDED)
354 					liblist[loop++].dynp = dynp;
355 
356 			/* Randomize these */
357 			for (loop = 0; loop < libcount; loop++)
358 				randomlist[loop] = loop;
359 
360 			for (loop = 1; loop < libcount; loop++) {
361 				unsigned int rnd;
362 				int cur;
363 				rnd = _dl_arc4random();
364 				rnd = rnd % (loop+1);
365 				cur = randomlist[rnd];
366 				randomlist[rnd] = randomlist[loop];
367 				randomlist[loop] = cur;
368 			}
369 
370 			for (loop = 0; loop < libcount; loop++) {
371 				elf_object_t *depobj;
372 				const char *libname;
373 				libname = dynobj->dyn.strtab;
374 				libname +=
375 				    liblist[randomlist[loop]].dynp->d_un.d_val;
376 				DL_DEB(("loading: %s required by %s\n", libname,
377 				    dynobj->load_name));
378 				depobj = _dl_load_shlib(libname, dynobj,
379 				    OBJTYPE_LIB, depflags);
380 				if (depobj == 0) {
381 					if (booting) {
382 						_dl_die(
383 						    "can't load library '%s'",
384 						    libname);
385 					}
386 					DL_DEB(("dlopen: failed to open %s\n",
387 					    libname));
388 					_dl_free(liblist);
389 					_dl_free(randomlist);
390 					return (1);
391 				}
392 				liblist[randomlist[loop]].depobj = depobj;
393 			}
394 
395 			object_vec_grow(&dynobj->child_vec, libcount);
396 			for (loop = 0; loop < libcount; loop++) {
397 				_dl_add_object(liblist[loop].depobj);
398 				_dl_link_child(liblist[loop].depobj, dynobj);
399 			}
400 			_dl_free(liblist);
401 			_dl_free(randomlist);
402 		}
403 		dynobj = dynobj->next;
404 	}
405 
406 	_dl_cache_grpsym_list_setup(object);
407 
408 	return(0);
409 }
410 
411 
412 /* do any RWX -> RX fixups for executable PLTs and apply GNU_RELRO */
413 static inline void
414 _dl_self_relro(long loff)
415 {
416 	Elf_Ehdr *ehdp;
417 	Elf_Phdr *phdp;
418 	int i;
419 
420 	ehdp = (Elf_Ehdr *)loff;
421 	phdp = (Elf_Phdr *)(loff + ehdp->e_phoff);
422 	for (i = 0; i < ehdp->e_phnum; i++, phdp++) {
423 		switch (phdp->p_type) {
424 #if defined(__alpha__) || defined(__hppa__) || defined(__powerpc__) || \
425     defined(__sparc64__)
426 		case PT_LOAD:
427 			if ((phdp->p_flags & (PF_X | PF_W)) != (PF_X | PF_W))
428 				break;
429 			_dl_mprotect((void *)(phdp->p_vaddr + loff),
430 			    phdp->p_memsz, PROT_READ);
431 			break;
432 #endif
433 		case PT_GNU_RELRO:
434 			_dl_mprotect((void *)(phdp->p_vaddr + loff),
435 			    phdp->p_memsz, PROT_READ);
436 			break;
437 		}
438 	}
439 }
440 
441 
442 #define PFLAGS(X) ((((X) & PF_R) ? PROT_READ : 0) | \
443 		   (((X) & PF_W) ? PROT_WRITE : 0) | \
444 		   (((X) & PF_X) ? PROT_EXEC : 0))
445 
446 /*
447  * This is the dynamic loader entrypoint. When entering here, depending
448  * on architecture type, the stack and registers are set up according
449  * to the architectures ABI specification. The first thing required
450  * to do is to dig out all information we need to accomplish our task.
451  */
452 unsigned long
453 _dl_boot(const char **argv, char **envp, const long dyn_loff, long *dl_data)
454 {
455 	struct elf_object *exe_obj;	/* Pointer to executable object */
456 	struct elf_object *dyn_obj;	/* Pointer to ld.so object */
457 	struct r_debug **map_link;	/* Where to put pointer for gdb */
458 	struct r_debug *debug_map;
459 	struct load_list *next_load, *load_list = NULL;
460 	Elf_Dyn *dynp;
461 	Elf_Phdr *phdp;
462 	Elf_Ehdr *ehdr;
463 	char *us = NULL;
464 	unsigned int loop;
465 	int failed;
466 	struct dep_node *n;
467 	Elf_Addr minva, maxva, exe_loff, exec_end, cur_exec_end;
468 	Elf_Addr relro_addr = 0, relro_size = 0;
469 	Elf_Phdr *ptls = NULL;
470 	int align;
471 
472 	if (dl_data[AUX_pagesz] != 0)
473 		_dl_pagesz = dl_data[AUX_pagesz];
474 	_dl_malloc_init();
475 
476 	_dl_argv = argv;
477 	while (_dl_argv[_dl_argc] != NULL)
478 		_dl_argc++;
479 	_dl_setup_env(argv[0], envp);
480 
481 	/*
482 	 * Make read-only the GOT and PLT and variables initialized
483 	 * during the ld.so setup above.
484 	 */
485 	_dl_self_relro(dyn_loff);
486 
487 	align = _dl_pagesz - 1;
488 
489 #define ROUND_PG(x) (((x) + align) & ~(align))
490 #define TRUNC_PG(x) ((x) & ~(align))
491 
492 	if (_dl_bindnow) {
493 		/* Lazy binding disabled, so disable kbind */
494 		_dl___syscall(SYS_kbind, (void *)NULL, (size_t)0, (long long)0);
495 	}
496 
497 	DL_DEB(("ld.so loading: '%s'\n", __progname));
498 
499 	/* init this in runtime, not statically */
500 	TAILQ_INIT(&_dlopened_child_list);
501 
502 	exe_obj = NULL;
503 	_dl_loading_object = NULL;
504 
505 	minva = ELF_NO_ADDR;
506 	maxva = exe_loff = exec_end = 0;
507 
508 	/*
509 	 * Examine the user application and set up object information.
510 	 */
511 	phdp = (Elf_Phdr *)dl_data[AUX_phdr];
512 	for (loop = 0; loop < dl_data[AUX_phnum]; loop++) {
513 		switch (phdp->p_type) {
514 		case PT_PHDR:
515 			exe_loff = (Elf_Addr)dl_data[AUX_phdr] - phdp->p_vaddr;
516 			us += exe_loff;
517 			DL_DEB(("exe load offset:  0x%lx\n", exe_loff));
518 			break;
519 		case PT_DYNAMIC:
520 			minva = TRUNC_PG(minva);
521 			maxva = ROUND_PG(maxva);
522 			exe_obj = _dl_finalize_object(argv[0] ? argv[0] : "",
523 			    (Elf_Dyn *)(phdp->p_vaddr + exe_loff),
524 			    (Elf_Phdr *)dl_data[AUX_phdr],
525 			    dl_data[AUX_phnum], OBJTYPE_EXE, minva + exe_loff,
526 			    exe_loff);
527 			_dl_add_object(exe_obj);
528 			break;
529 		case PT_INTERP:
530 			us += phdp->p_vaddr;
531 			break;
532 		case PT_LOAD:
533 			if (phdp->p_vaddr < minva)
534 				minva = phdp->p_vaddr;
535 			if (phdp->p_vaddr > maxva)
536 				maxva = phdp->p_vaddr + phdp->p_memsz;
537 
538 			next_load = _dl_calloc(1, sizeof(struct load_list));
539 			if (next_load == NULL)
540 				_dl_oom();
541 			next_load->next = load_list;
542 			load_list = next_load;
543 			next_load->start = (char *)TRUNC_PG(phdp->p_vaddr) + exe_loff;
544 			next_load->size = (phdp->p_vaddr & align) + phdp->p_filesz;
545 			next_load->prot = PFLAGS(phdp->p_flags);
546 			cur_exec_end = (Elf_Addr)next_load->start + next_load->size;
547 			if ((next_load->prot & PROT_EXEC) != 0 &&
548 			    cur_exec_end > exec_end)
549 				exec_end = cur_exec_end;
550 			break;
551 		case PT_TLS:
552 			if (phdp->p_filesz > phdp->p_memsz)
553 				_dl_die("invalid tls data");
554 			ptls = phdp;
555 			break;
556 		case PT_GNU_RELRO:
557 			relro_addr = phdp->p_vaddr + exe_loff;
558 			relro_size = phdp->p_memsz;
559 			break;
560 		}
561 		phdp++;
562 	}
563 	exe_obj->load_list = load_list;
564 	exe_obj->obj_flags |= DF_1_GLOBAL;
565 	exe_obj->load_size = maxva - minva;
566 	exe_obj->relro_addr = relro_addr;
567 	exe_obj->relro_size = relro_size;
568 	_dl_set_sod(exe_obj->load_name, &exe_obj->sod);
569 
570 #ifdef __i386__
571 	if (exec_end > I386_MAX_EXE_ADDR)
572 		_dl_exec_hint = (void *)ROUND_PG(exec_end-I386_MAX_EXE_ADDR);
573 	DL_DEB(("_dl_exec_hint:  0x%lx\n", _dl_exec_hint));
574 #endif
575 
576 	/* TLS bits in the base executable */
577 	if (ptls != NULL && ptls->p_memsz)
578 		_dl_set_tls(exe_obj, ptls, exe_loff, NULL);
579 
580 	n = _dl_malloc(sizeof *n);
581 	if (n == NULL)
582 		_dl_oom();
583 	n->data = exe_obj;
584 	TAILQ_INSERT_TAIL(&_dlopened_child_list, n, next_sib);
585 	exe_obj->opencount++;
586 
587 	if (_dl_preload != NULL)
588 		_dl_dopreload(_dl_preload);
589 
590 	_dl_load_dep_libs(exe_obj, exe_obj->obj_flags, 1);
591 
592 	/*
593 	 * Now add the dynamic loader itself last in the object list
594 	 * so we can use the _dl_ code when serving dl.... calls.
595 	 * Intentionally left off the exe child_vec.
596 	 */
597 	dynp = (Elf_Dyn *)((void *)_DYNAMIC);
598 	ehdr = (Elf_Ehdr *)dl_data[AUX_base];
599 	dyn_obj = _dl_finalize_object(us, dynp,
600 	    (Elf_Phdr *)((char *)dl_data[AUX_base] + ehdr->e_phoff),
601 	    ehdr->e_phnum, OBJTYPE_LDR, dl_data[AUX_base], dyn_loff);
602 	_dl_add_object(dyn_obj);
603 
604 	dyn_obj->refcount++;
605 	_dl_link_grpsym(dyn_obj);
606 
607 	dyn_obj->status |= STAT_RELOC_DONE;
608 	_dl_set_sod(dyn_obj->load_name, &dyn_obj->sod);
609 
610 	/* calculate the offsets for static TLS allocations */
611 	_dl_allocate_tls_offsets();
612 
613 	/*
614 	 * Make something to help gdb when poking around in the code.
615 	 * Do this poking at the .dynamic section now, before relocation
616 	 * renders it read-only
617 	 */
618 	map_link = NULL;
619 #ifdef __mips__
620 	if (exe_obj->Dyn.info[DT_MIPS_RLD_MAP - DT_LOPROC + DT_NUM] != 0)
621 		map_link = (struct r_debug **)(exe_obj->Dyn.info[
622 		    DT_MIPS_RLD_MAP - DT_LOPROC + DT_NUM] + exe_loff);
623 #endif
624 	if (map_link == NULL) {
625 		for (dynp = exe_obj->load_dyn; dynp->d_tag; dynp++) {
626 			if (dynp->d_tag == DT_DEBUG) {
627 				map_link = (struct r_debug **)&dynp->d_un.d_ptr;
628 				break;
629 			}
630 		}
631 		if (dynp->d_tag != DT_DEBUG)
632 			DL_DEB(("failed to mark DTDEBUG\n"));
633 	}
634 	if (map_link) {
635 		debug_map = _dl_malloc(sizeof(*debug_map));
636 		if (debug_map == NULL)
637 			_dl_oom();
638 		debug_map->r_version = 1;
639 		debug_map->r_map = (struct link_map *)_dl_objects;
640 		debug_map->r_brk = (Elf_Addr)_dl_debug_state;
641 		debug_map->r_state = RT_CONSISTENT;
642 		debug_map->r_ldbase = dyn_loff;
643 		_dl_debug_map = debug_map;
644 #ifdef __mips__
645 		relro_addr = exe_obj->relro_addr;
646 		if (dynp->d_tag == DT_DEBUG &&
647 		    ((Elf_Addr)map_link + sizeof(*map_link) <= relro_addr ||
648 		     (Elf_Addr)map_link >= relro_addr + exe_obj->relro_size)) {
649 			_dl_mprotect(map_link, sizeof(*map_link),
650 			    PROT_READ|PROT_WRITE);
651 			*map_link = _dl_debug_map;
652 			_dl_mprotect(map_link, sizeof(*map_link),
653 			    PROT_READ|PROT_EXEC);
654 		} else
655 #endif
656 			*map_link = _dl_debug_map;
657 	}
658 
659 
660 	/*
661 	 * Everything should be in place now for doing the relocation
662 	 * and binding. Call _dl_rtld to do the job. Fingers crossed.
663 	 */
664 
665 	failed = 0;
666 	if (!_dl_traceld)
667 		failed = _dl_rtld(_dl_objects);
668 
669 	if (_dl_debug || _dl_traceld) {
670 		if (_dl_traceld)
671 			_dl_pledge("stdio rpath", NULL);
672 		_dl_show_objects();
673 	}
674 
675 	DL_DEB(("dynamic loading done, %s.\n",
676 	    (failed == 0) ? "success":"failed"));
677 
678 	if (failed != 0)
679 		_dl_die("relocation failed");
680 
681 	if (_dl_traceld)
682 		_dl_exit(0);
683 
684 	_dl_loading_object = NULL;
685 
686 	/* set up the TIB for the initial thread */
687 	_dl_allocate_first_tib();
688 
689 	_dl_fixup_user_env();
690 
691 	_dl_debug_state();
692 
693 	/*
694 	 * Do not run init code if run from ldd.
695 	 */
696 	if (_dl_objects->next != NULL) {
697 		_dl_call_preinit(_dl_objects);
698 		_dl_call_init(_dl_objects);
699 	}
700 
701 	DL_DEB(("entry point: 0x%lx\n", dl_data[AUX_entry]));
702 
703 	/*
704 	 * Return the entry point.
705 	 */
706 	return(dl_data[AUX_entry]);
707 }
708 
709 int
710 _dl_rtld(elf_object_t *object)
711 {
712 	struct load_list *llist;
713 	int fails = 0;
714 
715 	if (object->next)
716 		fails += _dl_rtld(object->next);
717 
718 	if (object->status & STAT_RELOC_DONE)
719 		return 0;
720 
721 	/*
722 	 * Do relocation information first, then GOT.
723 	 */
724 	unprotect_if_textrel(object);
725 	_dl_rreloc(object);
726 	fails =_dl_md_reloc(object, DT_REL, DT_RELSZ);
727 	fails += _dl_md_reloc(object, DT_RELA, DT_RELASZ);
728 	reprotect_if_textrel(object);
729 
730 	/*
731 	 * We do lazy resolution by default, doing eager resolution if
732 	 *  - the object requests it with -znow, OR
733 	 *  - LD_BIND_NOW is set and this object isn't being ltraced
734 	 *
735 	 * Note that -znow disables ltrace for the object: on at least
736 	 * amd64 'ld' doesn't generate the trampoline for lazy relocation
737 	 * when -znow is used.
738 	 */
739 	fails += _dl_md_reloc_got(object, !(object->obj_flags & DF_1_NOW) &&
740 	    !(_dl_bindnow && !object->traced));
741 
742 	/*
743 	 * Look for W&X segments and make them read-only.
744 	 */
745 	for (llist = object->load_list; llist != NULL; llist = llist->next) {
746 		if ((llist->prot & PROT_WRITE) && (llist->prot & PROT_EXEC)) {
747 			_dl_mprotect(llist->start, llist->size,
748 			    llist->prot & ~PROT_WRITE);
749 		}
750 	}
751 
752 	if (fails == 0)
753 		object->status |= STAT_RELOC_DONE;
754 
755 	return (fails);
756 }
757 
758 void
759 _dl_call_preinit(elf_object_t *object)
760 {
761 	if (object->dyn.preinit_array) {
762 		int num = object->dyn.preinit_arraysz / sizeof(Elf_Addr);
763 		int i;
764 
765 		DL_DEB(("doing preinitarray obj %p @%p: [%s]\n",
766 		    object, object->dyn.preinit_array, object->load_name));
767 		for (i = 0; i < num; i++)
768 			(*object->dyn.preinit_array[i])(_dl_argc, _dl_argv,
769 			    environ, &_dl_cb_cb);
770 	}
771 }
772 
773 void
774 _dl_call_init(elf_object_t *object)
775 {
776 	_dl_call_init_recurse(object, 1);
777 	_dl_call_init_recurse(object, 0);
778 }
779 
780 static void
781 _dl_relro(elf_object_t *object)
782 {
783 	/*
784 	 * Handle GNU_RELRO
785 	 */
786 	if (object->relro_addr != 0 && object->relro_size != 0) {
787 		Elf_Addr addr = object->relro_addr;
788 
789 		DL_DEB(("protect RELRO [0x%lx,0x%lx) in %s\n",
790 		    addr, addr + object->relro_size, object->load_name));
791 		_dl_mprotect((void *)addr, object->relro_size, PROT_READ);
792 	}
793 }
794 
795 void
796 _dl_call_init_recurse(elf_object_t *object, int initfirst)
797 {
798 	struct object_vector vec;
799 	int visited_flag = initfirst ? STAT_VISIT_INITFIRST : STAT_VISIT_INIT;
800 	int i;
801 
802 	object->status |= visited_flag;
803 
804 	for (vec = object->child_vec, i = 0; i < vec.len; i++) {
805 		if (vec.vec[i]->status & visited_flag)
806 			continue;
807 		_dl_call_init_recurse(vec.vec[i], initfirst);
808 	}
809 
810 	if (object->status & STAT_INIT_DONE)
811 		return;
812 
813 	if (initfirst && (object->obj_flags & DF_1_INITFIRST) == 0)
814 		return;
815 
816 	if (!initfirst)
817 		_dl_relro(object);
818 
819 	if (object->dyn.init) {
820 		DL_DEB(("doing ctors obj %p @%p: [%s]\n",
821 		    object, object->dyn.init, object->load_name));
822 		(*object->dyn.init)();
823 	}
824 
825 	if (object->dyn.init_array) {
826 		int num = object->dyn.init_arraysz / sizeof(Elf_Addr);
827 		int i;
828 
829 		DL_DEB(("doing initarray obj %p @%p: [%s]\n",
830 		    object, object->dyn.init_array, object->load_name));
831 		for (i = 0; i < num; i++)
832 			(*object->dyn.init_array[i])(_dl_argc, _dl_argv,
833 			    environ, &_dl_cb_cb);
834 	}
835 
836 	if (initfirst)
837 		_dl_relro(object);
838 
839 	object->status |= STAT_INIT_DONE;
840 }
841 
842 char *
843 _dl_getenv(const char *var, char **env)
844 {
845 	const char *ep;
846 
847 	while ((ep = *env++)) {
848 		const char *vp = var;
849 
850 		while (*vp && *vp == *ep) {
851 			vp++;
852 			ep++;
853 		}
854 		if (*vp == '\0' && *ep++ == '=')
855 			return((char *)ep);
856 	}
857 	return(NULL);
858 }
859 
860 void
861 _dl_unsetenv(const char *var, char **env)
862 {
863 	char *ep;
864 
865 	while ((ep = *env)) {
866 		const char *vp = var;
867 
868 		while (*vp && *vp == *ep) {
869 			vp++;
870 			ep++;
871 		}
872 		if (*vp == '\0' && *ep++ == '=') {
873 			char **P;
874 
875 			for (P = env;; ++P)
876 				if (!(*P = *(P + 1)))
877 					break;
878 		} else
879 			env++;
880 	}
881 }
882 
883 static inline void
884 fixup_sym(struct elf_object *dummy_obj, const char *name, void *addr)
885 {
886 	struct sym_res sr;
887 
888 	sr = _dl_find_symbol(name, SYM_SEARCH_ALL|SYM_NOWARNNOTFOUND|SYM_PLT,
889 	    NULL, dummy_obj);
890 	if (sr.sym != NULL) {
891 		void *p = (void *)(sr.sym->st_value + sr.obj->obj_base);
892 		if (p != addr) {
893 			DL_DEB(("setting %s %p@%s[%p] from %p\n", name,
894 			    p, sr.obj->load_name, (void *)sr.obj, addr));
895 			*(void **)p = *(void **)addr;
896 		}
897 	}
898 }
899 
900 /*
901  * _dl_fixup_user_env()
902  *
903  * Set the user environment so that programs can use the environment
904  * while running constructors. Specifically, MALLOC_OPTIONS= for malloc()
905  */
906 void
907 _dl_fixup_user_env(void)
908 {
909 	struct elf_object dummy_obj;
910 
911 	dummy_obj.dyn.symbolic = 0;
912 	dummy_obj.load_name = "ld.so";
913 	fixup_sym(&dummy_obj, "environ", &environ);
914 	fixup_sym(&dummy_obj, "__progname", &__progname);
915 }
916 
917 const void *
918 _dl_cb_cb(int version)
919 {
920 	DL_DEB(("version %d callbacks requested\n", version));
921 	if (version == 0)
922 		return &callbacks_0;
923 	return NULL;
924 }
925 
926 static inline void
927 unprotect_if_textrel(elf_object_t *object)
928 {
929 	struct load_list *ll;
930 
931 	if (__predict_false(object->dyn.textrel == 1)) {
932 		for (ll = object->load_list; ll != NULL; ll = ll->next) {
933 			if ((ll->prot & PROT_WRITE) == 0)
934 				_dl_mprotect(ll->start, ll->size,
935 				    PROT_READ | PROT_WRITE);
936 		}
937 	}
938 }
939 
940 static inline void
941 reprotect_if_textrel(elf_object_t *object)
942 {
943 	struct load_list *ll;
944 
945 	if (__predict_false(object->dyn.textrel == 1)) {
946 		for (ll = object->load_list; ll != NULL; ll = ll->next) {
947 			if ((ll->prot & PROT_WRITE) == 0)
948 				_dl_mprotect(ll->start, ll->size, ll->prot);
949 		}
950 	}
951 }
952 
953 static void
954 _dl_rreloc(elf_object_t *object)
955 {
956 	const Elf_Relr	*reloc, *rend;
957 	Elf_Addr	loff = object->obj_base;
958 
959 	reloc = object->dyn.relr;
960 	rend  = (const Elf_Relr *)((char *)reloc + object->dyn.relrsz);
961 
962 	while (reloc < rend) {
963 		Elf_Addr *where;
964 
965 		where = (Elf_Addr *)(*reloc + loff);
966 		*where++ += loff;
967 
968 		for (reloc++; reloc < rend && (*reloc & 1); reloc++) {
969 			Elf_Addr bits = *reloc >> 1;
970 
971 			Elf_Addr *here = where;
972 			while (bits != 0) {
973 				if (bits & 1) {
974 					*here += loff;
975 				}
976 				bits >>= 1;
977 				here++;
978 			}
979 			where += (8 * sizeof *reloc) - 1;
980 		}
981 	}
982 }
983 
984