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