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