1 /*- 2 * Copyright 1996, 1997, 1998, 1999 John D. Polstra. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * 25 * $FreeBSD$ 26 */ 27 28 /* 29 * Dynamic linker for ELF. 30 * 31 * John Polstra <jdp@polstra.com>. 32 */ 33 34 #ifndef __GNUC__ 35 #error "GCC is needed to compile this file" 36 #endif 37 38 #include <sys/param.h> 39 #include <sys/mman.h> 40 41 #include <dlfcn.h> 42 #include <err.h> 43 #include <errno.h> 44 #include <fcntl.h> 45 #include <stdarg.h> 46 #include <stdio.h> 47 #include <stdlib.h> 48 #include <string.h> 49 #include <unistd.h> 50 51 #include "debug.h" 52 #include "rtld.h" 53 54 /* 55 * Debugging support. 56 */ 57 58 #define assert(cond) ((cond) ? (void) 0 :\ 59 (msg("oops: " __XSTRING(__LINE__) "\n"), abort())) 60 #define msg(s) (write(1, s, strlen(s))) 61 #define trace() msg("trace: " __XSTRING(__LINE__) "\n"); 62 63 #define END_SYM "_end" 64 65 /* Types. */ 66 typedef void (*func_ptr_type)(); 67 68 /* 69 * Function declarations. 70 */ 71 static const char *basename(const char *); 72 static void call_fini_functions(Obj_Entry *); 73 static void call_init_functions(Obj_Entry *); 74 static void die(void); 75 static void digest_dynamic(Obj_Entry *); 76 static Obj_Entry *digest_phdr(const Elf_Phdr *, int, caddr_t, const char *); 77 static Obj_Entry *dlcheck(void *); 78 static char *find_library(const char *, const Obj_Entry *); 79 static const char *gethints(void); 80 static void init_rtld(caddr_t); 81 static bool is_exported(const Elf_Sym *); 82 static void linkmap_add(Obj_Entry *); 83 static void linkmap_delete(Obj_Entry *); 84 static int load_needed_objects(Obj_Entry *); 85 static int load_preload_objects(void); 86 static Obj_Entry *load_object(char *); 87 static Obj_Entry *obj_from_addr(const void *); 88 static int relocate_objects(Obj_Entry *, bool); 89 static void rtld_exit(void); 90 static char *search_library_path(const char *, const char *); 91 static void set_program_var(const char *, const void *); 92 static void trace_loaded_objects(Obj_Entry *obj); 93 static void unload_object(Obj_Entry *, bool do_fini_funcs); 94 static void unref_object_dag(Obj_Entry *); 95 96 void r_debug_state(void); 97 void xprintf(const char *, ...); 98 99 /* 100 * Data declarations. 101 */ 102 static char *error_message; /* Message for dlerror(), or NULL */ 103 struct r_debug r_debug; /* for GDB; */ 104 static bool trust; /* False for setuid and setgid programs */ 105 static char *ld_bind_now; /* Environment variable for immediate binding */ 106 static char *ld_debug; /* Environment variable for debugging */ 107 static char *ld_library_path; /* Environment variable for search path */ 108 static char *ld_preload; /* Environment variable for libraries to 109 load first */ 110 static char *ld_tracing; /* Called from ldd to print libs */ 111 static Obj_Entry **main_tail; /* Value of obj_tail after loading main and 112 its needed shared libraries */ 113 static Obj_Entry *obj_list; /* Head of linked list of shared objects */ 114 static Obj_Entry **obj_tail; /* Link field of last object in list */ 115 static Obj_Entry *obj_main; /* The main program shared object */ 116 static Obj_Entry obj_rtld; /* The dynamic linker shared object */ 117 118 static Elf_Sym sym_zero; /* For resolving undefined weak refs. */ 119 120 #define GDB_STATE(s) r_debug.r_state = s; r_debug_state(); 121 122 extern Elf_Dyn _DYNAMIC; 123 #pragma weak _DYNAMIC 124 125 /* 126 * These are the functions the dynamic linker exports to application 127 * programs. They are the only symbols the dynamic linker is willing 128 * to export from itself. 129 */ 130 static func_ptr_type exports[] = { 131 (func_ptr_type) &_rtld_error, 132 (func_ptr_type) &dlclose, 133 (func_ptr_type) &dlerror, 134 (func_ptr_type) &dlopen, 135 (func_ptr_type) &dlsym, 136 (func_ptr_type) &dladdr, 137 NULL 138 }; 139 140 /* 141 * Global declarations normally provided by crt1. The dynamic linker is 142 * not build with crt1, so we have to provide them ourselves. 143 */ 144 char *__progname; 145 char **environ; 146 147 /* 148 * Main entry point for dynamic linking. The first argument is the 149 * stack pointer. The stack is expected to be laid out as described 150 * in the SVR4 ABI specification, Intel 386 Processor Supplement. 151 * Specifically, the stack pointer points to a word containing 152 * ARGC. Following that in the stack is a null-terminated sequence 153 * of pointers to argument strings. Then comes a null-terminated 154 * sequence of pointers to environment strings. Finally, there is a 155 * sequence of "auxiliary vector" entries. 156 * 157 * The second argument points to a place to store the dynamic linker's 158 * exit procedure pointer and the third to a place to store the main 159 * program's object. 160 * 161 * The return value is the main program's entry point. 162 */ 163 func_ptr_type 164 _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp) 165 { 166 Elf_Auxinfo *aux_info[AT_COUNT]; 167 int i; 168 int argc; 169 char **argv; 170 char **env; 171 Elf_Auxinfo *aux; 172 Elf_Auxinfo *auxp; 173 const char *argv0; 174 175 /* 176 * On entry, the dynamic linker itself has not been relocated yet. 177 * Be very careful not to reference any global data until after 178 * init_rtld has returned. It is OK to reference file-scope statics 179 * and string constants, and to call static and global functions. 180 */ 181 182 /* Find the auxiliary vector on the stack. */ 183 argc = *sp++; 184 argv = (char **) sp; 185 sp += argc + 1; /* Skip over arguments and NULL terminator */ 186 env = (char **) sp; 187 while (*sp++ != 0) /* Skip over environment, and NULL terminator */ 188 ; 189 aux = (Elf_Auxinfo *) sp; 190 191 /* Digest the auxiliary vector. */ 192 for (i = 0; i < AT_COUNT; i++) 193 aux_info[i] = NULL; 194 for (auxp = aux; auxp->a_type != AT_NULL; auxp++) { 195 if (auxp->a_type < AT_COUNT) 196 aux_info[auxp->a_type] = auxp; 197 } 198 199 /* Initialize and relocate ourselves. */ 200 assert(aux_info[AT_BASE] != NULL); 201 init_rtld((caddr_t) aux_info[AT_BASE]->a_un.a_ptr); 202 203 __progname = obj_rtld.path; 204 argv0 = argv[0] != NULL ? argv[0] : "(null)"; 205 environ = env; 206 207 trust = geteuid() == getuid() && getegid() == getgid(); 208 209 ld_bind_now = getenv("LD_BIND_NOW"); 210 if (trust) { 211 ld_debug = getenv("LD_DEBUG"); 212 ld_library_path = getenv("LD_LIBRARY_PATH"); 213 ld_preload = getenv("LD_PRELOAD"); 214 } 215 ld_tracing = getenv("LD_TRACE_LOADED_OBJECTS"); 216 217 if (ld_debug != NULL && *ld_debug != '\0') 218 debug = 1; 219 dbg("%s is initialized, base address = %p", __progname, 220 (caddr_t) aux_info[AT_BASE]->a_un.a_ptr); 221 dbg("RTLD dynamic = %p", obj_rtld.dynamic); 222 dbg("RTLD pltgot = %p", obj_rtld.pltgot); 223 224 /* 225 * Load the main program, or process its program header if it is 226 * already loaded. 227 */ 228 if (aux_info[AT_EXECFD] != NULL) { /* Load the main program. */ 229 int fd = aux_info[AT_EXECFD]->a_un.a_val; 230 dbg("loading main program"); 231 obj_main = map_object(fd, argv0); 232 close(fd); 233 if (obj_main == NULL) 234 die(); 235 } else { /* Main program already loaded. */ 236 const Elf_Phdr *phdr; 237 int phnum; 238 caddr_t entry; 239 240 dbg("processing main program's program header"); 241 assert(aux_info[AT_PHDR] != NULL); 242 phdr = (const Elf_Phdr *) aux_info[AT_PHDR]->a_un.a_ptr; 243 assert(aux_info[AT_PHNUM] != NULL); 244 phnum = aux_info[AT_PHNUM]->a_un.a_val; 245 assert(aux_info[AT_PHENT] != NULL); 246 assert(aux_info[AT_PHENT]->a_un.a_val == sizeof(Elf_Phdr)); 247 assert(aux_info[AT_ENTRY] != NULL); 248 entry = (caddr_t) aux_info[AT_ENTRY]->a_un.a_ptr; 249 if ((obj_main = digest_phdr(phdr, phnum, entry, argv0)) == NULL) 250 die(); 251 } 252 253 obj_main->path = xstrdup(argv0); 254 obj_main->mainprog = true; 255 digest_dynamic(obj_main); 256 257 linkmap_add(obj_main); 258 linkmap_add(&obj_rtld); 259 260 /* Link the main program into the list of objects. */ 261 *obj_tail = obj_main; 262 obj_tail = &obj_main->next; 263 obj_main->refcount++; 264 265 /* Initialize a fake symbol for resolving undefined weak references. */ 266 sym_zero.st_info = ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE); 267 sym_zero.st_shndx = SHN_ABS; 268 269 dbg("loading LD_PRELOAD libraries"); 270 if (load_preload_objects() == -1) 271 die(); 272 273 dbg("loading needed objects"); 274 if (load_needed_objects(obj_main) == -1) 275 die(); 276 main_tail = obj_tail; 277 278 if (ld_tracing) { /* We're done */ 279 trace_loaded_objects(obj_main); 280 exit(0); 281 } 282 283 dbg("relocating objects"); 284 if (relocate_objects(obj_main, 285 ld_bind_now != NULL && *ld_bind_now != '\0') == -1) 286 die(); 287 288 dbg("doing copy relocations"); 289 if (do_copy_relocations(obj_main) == -1) 290 die(); 291 292 dbg("initializing key program variables"); 293 set_program_var("__progname", argv[0] != NULL ? basename(argv[0]) : ""); 294 set_program_var("environ", env); 295 296 r_debug_state(); /* say hello to gdb! */ 297 298 dbg("calling _init functions"); 299 call_init_functions(obj_main->next); 300 301 dbg("transferring control to program entry point = %p", obj_main->entry); 302 303 /* Return the exit procedure and the program entry point. */ 304 *exit_proc = rtld_exit; 305 *objp = obj_main; 306 return (func_ptr_type) obj_main->entry; 307 } 308 309 Elf_Addr 310 _rtld_bind(const Obj_Entry *obj, Elf_Word reloff) 311 { 312 const Elf_Rel *rel; 313 const Elf_Sym *def; 314 const Obj_Entry *defobj; 315 Elf_Addr *where; 316 Elf_Addr target; 317 318 if (obj->pltrel) 319 rel = (const Elf_Rel *) ((caddr_t) obj->pltrel + reloff); 320 else 321 rel = (const Elf_Rel *) ((caddr_t) obj->pltrela + reloff); 322 323 where = (Elf_Addr *) (obj->relocbase + rel->r_offset); 324 def = find_symdef(ELF_R_SYM(rel->r_info), obj, &defobj, true); 325 if (def == NULL) 326 die(); 327 328 target = (Elf_Addr)(defobj->relocbase + def->st_value); 329 330 dbg("\"%s\" in \"%s\" ==> %p in \"%s\"", 331 defobj->strtab + def->st_name, basename(obj->path), 332 (void *)target, basename(defobj->path)); 333 334 reloc_jmpslot(where, target); 335 return target; 336 } 337 338 /* 339 * Error reporting function. Use it like printf. If formats the message 340 * into a buffer, and sets things up so that the next call to dlerror() 341 * will return the message. 342 */ 343 void 344 _rtld_error(const char *fmt, ...) 345 { 346 static char buf[512]; 347 va_list ap; 348 349 va_start(ap, fmt); 350 vsnprintf(buf, sizeof buf, fmt, ap); 351 error_message = buf; 352 va_end(ap); 353 } 354 355 static const char * 356 basename(const char *name) 357 { 358 const char *p = strrchr(name, '/'); 359 return p != NULL ? p + 1 : name; 360 } 361 362 static void 363 call_fini_functions(Obj_Entry *first) 364 { 365 Obj_Entry *obj; 366 367 for (obj = first; obj != NULL; obj = obj->next) 368 if (obj->fini != NULL) 369 (*obj->fini)(); 370 } 371 372 static void 373 call_init_functions(Obj_Entry *first) 374 { 375 if (first != NULL) { 376 call_init_functions(first->next); 377 if (first->init != NULL) 378 (*first->init)(); 379 } 380 } 381 382 static void 383 die(void) 384 { 385 const char *msg = dlerror(); 386 387 if (msg == NULL) 388 msg = "Fatal error"; 389 errx(1, "%s", msg); 390 } 391 392 /* 393 * Process a shared object's DYNAMIC section, and save the important 394 * information in its Obj_Entry structure. 395 */ 396 static void 397 digest_dynamic(Obj_Entry *obj) 398 { 399 const Elf_Dyn *dynp; 400 Needed_Entry **needed_tail = &obj->needed; 401 const Elf_Dyn *dyn_rpath = NULL; 402 int plttype = DT_REL; 403 404 for (dynp = obj->dynamic; dynp->d_tag != DT_NULL; dynp++) { 405 switch (dynp->d_tag) { 406 407 case DT_REL: 408 obj->rel = (const Elf_Rel *) (obj->relocbase + dynp->d_un.d_ptr); 409 break; 410 411 case DT_RELSZ: 412 obj->relsize = dynp->d_un.d_val; 413 break; 414 415 case DT_RELENT: 416 assert(dynp->d_un.d_val == sizeof(Elf_Rel)); 417 break; 418 419 case DT_JMPREL: 420 obj->pltrel = (const Elf_Rel *) 421 (obj->relocbase + dynp->d_un.d_ptr); 422 break; 423 424 case DT_PLTRELSZ: 425 obj->pltrelsize = dynp->d_un.d_val; 426 break; 427 428 case DT_RELA: 429 obj->rela = (const Elf_Rela *) (obj->relocbase + dynp->d_un.d_ptr); 430 break; 431 432 case DT_RELASZ: 433 obj->relasize = dynp->d_un.d_val; 434 break; 435 436 case DT_RELAENT: 437 assert(dynp->d_un.d_val == sizeof(Elf_Rela)); 438 break; 439 440 case DT_PLTREL: 441 plttype = dynp->d_un.d_val; 442 assert(dynp->d_un.d_val == DT_REL || plttype == DT_RELA); 443 break; 444 445 case DT_SYMTAB: 446 obj->symtab = (const Elf_Sym *) 447 (obj->relocbase + dynp->d_un.d_ptr); 448 break; 449 450 case DT_SYMENT: 451 assert(dynp->d_un.d_val == sizeof(Elf_Sym)); 452 break; 453 454 case DT_STRTAB: 455 obj->strtab = (const char *) (obj->relocbase + dynp->d_un.d_ptr); 456 break; 457 458 case DT_STRSZ: 459 obj->strsize = dynp->d_un.d_val; 460 break; 461 462 case DT_HASH: 463 { 464 const Elf_Addr *hashtab = (const Elf_Addr *) 465 (obj->relocbase + dynp->d_un.d_ptr); 466 obj->nbuckets = hashtab[0]; 467 obj->nchains = hashtab[1]; 468 obj->buckets = hashtab + 2; 469 obj->chains = obj->buckets + obj->nbuckets; 470 } 471 break; 472 473 case DT_NEEDED: 474 if (!obj->rtld) { 475 Needed_Entry *nep = NEW(Needed_Entry); 476 nep->name = dynp->d_un.d_val; 477 nep->obj = NULL; 478 nep->next = NULL; 479 480 *needed_tail = nep; 481 needed_tail = &nep->next; 482 } 483 break; 484 485 case DT_PLTGOT: 486 obj->pltgot = (Elf_Addr *) (obj->relocbase + dynp->d_un.d_ptr); 487 break; 488 489 case DT_TEXTREL: 490 obj->textrel = true; 491 break; 492 493 case DT_SYMBOLIC: 494 obj->symbolic = true; 495 break; 496 497 case DT_RPATH: 498 /* 499 * We have to wait until later to process this, because we 500 * might not have gotten the address of the string table yet. 501 */ 502 dyn_rpath = dynp; 503 break; 504 505 case DT_SONAME: 506 /* Not used by the dynamic linker. */ 507 break; 508 509 case DT_INIT: 510 obj->init = (void (*)(void)) (obj->relocbase + dynp->d_un.d_ptr); 511 break; 512 513 case DT_FINI: 514 obj->fini = (void (*)(void)) (obj->relocbase + dynp->d_un.d_ptr); 515 break; 516 517 case DT_DEBUG: 518 /* XXX - not implemented yet */ 519 dbg("Filling in DT_DEBUG entry"); 520 ((Elf_Dyn*)dynp)->d_un.d_ptr = (Elf_Addr) &r_debug; 521 break; 522 523 default: 524 xprintf("Ignored d_tag %d\n",dynp->d_tag); 525 break; 526 } 527 } 528 529 obj->traced = false; 530 531 if (plttype == DT_RELA) { 532 obj->pltrela = (const Elf_Rela *) obj->pltrel; 533 obj->pltrel = NULL; 534 obj->pltrelasize = obj->pltrelsize; 535 obj->pltrelsize = 0; 536 } 537 538 if (dyn_rpath != NULL) 539 obj->rpath = obj->strtab + dyn_rpath->d_un.d_val; 540 } 541 542 /* 543 * Process a shared object's program header. This is used only for the 544 * main program, when the kernel has already loaded the main program 545 * into memory before calling the dynamic linker. It creates and 546 * returns an Obj_Entry structure. 547 */ 548 static Obj_Entry * 549 digest_phdr(const Elf_Phdr *phdr, int phnum, caddr_t entry, const char *path) 550 { 551 Obj_Entry *obj = CNEW(Obj_Entry); 552 const Elf_Phdr *phlimit = phdr + phnum; 553 const Elf_Phdr *ph; 554 int nsegs = 0; 555 556 for (ph = phdr; ph < phlimit; ph++) { 557 switch (ph->p_type) { 558 559 case PT_PHDR: 560 if ((const Elf_Phdr *)ph->p_vaddr != phdr) { 561 _rtld_error("%s: invalid PT_PHDR", path); 562 return NULL; 563 } 564 obj->phdr = (const Elf_Phdr *) ph->p_vaddr; 565 obj->phsize = ph->p_memsz; 566 break; 567 568 case PT_LOAD: 569 if (nsegs >= 2) { 570 _rtld_error("%s: too many PT_LOAD segments", path); 571 return NULL; 572 } 573 if (nsegs == 0) { /* First load segment */ 574 obj->vaddrbase = trunc_page(ph->p_vaddr); 575 obj->mapbase = (caddr_t) obj->vaddrbase; 576 obj->relocbase = obj->mapbase - obj->vaddrbase; 577 obj->textsize = round_page(ph->p_vaddr + ph->p_memsz) - 578 obj->vaddrbase; 579 } else { /* Last load segment */ 580 obj->mapsize = round_page(ph->p_vaddr + ph->p_memsz) - 581 obj->vaddrbase; 582 } 583 nsegs++; 584 break; 585 586 case PT_DYNAMIC: 587 obj->dynamic = (const Elf_Dyn *) ph->p_vaddr; 588 break; 589 } 590 } 591 if (nsegs < 2) { 592 _rtld_error("%s: too few PT_LOAD segments", path); 593 return NULL; 594 } 595 596 obj->entry = entry; 597 return obj; 598 } 599 600 static Obj_Entry * 601 dlcheck(void *handle) 602 { 603 Obj_Entry *obj; 604 605 for (obj = obj_list; obj != NULL; obj = obj->next) 606 if (obj == (Obj_Entry *) handle) 607 break; 608 609 if (obj == NULL || obj->dl_refcount == 0) { 610 _rtld_error("Invalid shared object handle %p", handle); 611 return NULL; 612 } 613 return obj; 614 } 615 616 /* 617 * Hash function for symbol table lookup. Don't even think about changing 618 * this. It is specified by the System V ABI. 619 */ 620 unsigned long 621 elf_hash(const char *name) 622 { 623 const unsigned char *p = (const unsigned char *) name; 624 unsigned long h = 0; 625 unsigned long g; 626 627 while (*p != '\0') { 628 h = (h << 4) + *p++; 629 if ((g = h & 0xf0000000) != 0) 630 h ^= g >> 24; 631 h &= ~g; 632 } 633 return h; 634 } 635 636 /* 637 * Find the library with the given name, and return its full pathname. 638 * The returned string is dynamically allocated. Generates an error 639 * message and returns NULL if the library cannot be found. 640 * 641 * If the second argument is non-NULL, then it refers to an already- 642 * loaded shared object, whose library search path will be searched. 643 * 644 * The search order is: 645 * LD_LIBRARY_PATH 646 * ldconfig hints 647 * rpath in the referencing file 648 * /usr/lib 649 */ 650 static char * 651 find_library(const char *name, const Obj_Entry *refobj) 652 { 653 char *pathname; 654 655 if (strchr(name, '/') != NULL) { /* Hard coded pathname */ 656 if (name[0] != '/' && !trust) { 657 _rtld_error("Absolute pathname required for shared object \"%s\"", 658 name); 659 return NULL; 660 } 661 return xstrdup(name); 662 } 663 664 dbg(" Searching for \"%s\"", name); 665 666 if ((refobj != NULL && 667 (pathname = search_library_path(name, refobj->rpath)) != NULL) || 668 (pathname = search_library_path(name, ld_library_path)) != NULL || 669 (pathname = search_library_path(name, gethints())) != NULL || 670 (pathname = search_library_path(name, STANDARD_LIBRARY_PATH)) != NULL) 671 return pathname; 672 673 _rtld_error("Shared object \"%s\" not found", name); 674 return NULL; 675 } 676 677 /* 678 * Given a symbol number in a referencing object, find the corresponding 679 * definition of the symbol. Returns a pointer to the symbol, or NULL if 680 * no definition was found. Returns a pointer to the Obj_Entry of the 681 * defining object via the reference parameter DEFOBJ_OUT. 682 */ 683 const Elf_Sym * 684 find_symdef(unsigned long symnum, const Obj_Entry *refobj, 685 const Obj_Entry **defobj_out, bool in_plt) 686 { 687 const Elf_Sym *ref; 688 const Elf_Sym *strongdef; 689 const Elf_Sym *weakdef; 690 const Obj_Entry *obj; 691 const Obj_Entry *strongobj; 692 const Obj_Entry *weakobj; 693 const char *name; 694 unsigned long hash; 695 696 ref = refobj->symtab + symnum; 697 name = refobj->strtab + ref->st_name; 698 hash = elf_hash(name); 699 700 if (refobj->symbolic) { /* Look first in the referencing object */ 701 const Elf_Sym *def = symlook_obj(name, hash, refobj, in_plt); 702 if (def != NULL) { 703 *defobj_out = refobj; 704 return def; 705 } 706 } 707 708 /* 709 * Look in all loaded objects. Skip the referencing object, if 710 * we have already searched it. We keep track of the first weak 711 * definition and the first strong definition we encounter. If 712 * we find a strong definition we stop searching, because there 713 * won't be anything better than that. 714 */ 715 strongdef = weakdef = NULL; 716 strongobj = weakobj = NULL; 717 for (obj = obj_list; obj != NULL; obj = obj->next) { 718 if (obj != refobj || !refobj->symbolic) { 719 const Elf_Sym *def = symlook_obj(name, hash, obj, in_plt); 720 if (def != NULL) { 721 if (ELF_ST_BIND(def->st_info) == STB_WEAK) { 722 if (weakdef == NULL) { 723 weakdef = def; 724 weakobj = obj; 725 } 726 } else { 727 strongdef = def; 728 strongobj = obj; 729 break; /* We are done. */ 730 } 731 } 732 } 733 } 734 735 /* 736 * If we still don't have a strong definition, search the dynamic 737 * linker itself, and possibly resolve the symbol from there. 738 * This is how the application links to dynamic linker services 739 * such as dlopen. Only the values listed in the "exports" array 740 * can be resolved from the dynamic linker. 741 */ 742 if (strongdef == NULL) { 743 const Elf_Sym *def = symlook_obj(name, hash, &obj_rtld, in_plt); 744 if (def != NULL && is_exported(def)) { 745 if (ELF_ST_BIND(def->st_info) == STB_WEAK) { 746 if (weakdef == NULL) { 747 weakdef = def; 748 weakobj = &obj_rtld; 749 } 750 } else { 751 strongdef = def; 752 strongobj = &obj_rtld; 753 } 754 } 755 } 756 757 if (strongdef != NULL) { 758 *defobj_out = strongobj; 759 return strongdef; 760 } 761 if (weakdef != NULL) { 762 *defobj_out = weakobj; 763 return weakdef; 764 } 765 766 if (ELF_ST_BIND(ref->st_info) == STB_WEAK) { 767 *defobj_out = obj_main; 768 return &sym_zero; 769 } 770 771 _rtld_error("%s: Undefined symbol \"%s\"", refobj->path, name); 772 return NULL; 773 } 774 775 /* 776 * Return the search path from the ldconfig hints file, reading it if 777 * necessary. Returns NULL if there are problems with the hints file, 778 * or if the search path there is empty. 779 */ 780 static const char * 781 gethints(void) 782 { 783 static char *hints; 784 785 if (hints == NULL) { 786 int fd; 787 struct elfhints_hdr hdr; 788 char *p; 789 790 /* Keep from trying again in case the hints file is bad. */ 791 hints = ""; 792 793 if ((fd = open(_PATH_ELF_HINTS, O_RDONLY)) == -1) 794 return NULL; 795 if (read(fd, &hdr, sizeof hdr) != sizeof hdr || 796 hdr.magic != ELFHINTS_MAGIC || 797 hdr.version != 1) { 798 close(fd); 799 return NULL; 800 } 801 p = xmalloc(hdr.dirlistlen + 1); 802 if (lseek(fd, hdr.strtab + hdr.dirlist, SEEK_SET) == -1 || 803 read(fd, p, hdr.dirlistlen + 1) != hdr.dirlistlen + 1) { 804 free(p); 805 close(fd); 806 return NULL; 807 } 808 hints = p; 809 close(fd); 810 } 811 return hints[0] != '\0' ? hints : NULL; 812 } 813 814 /* 815 * Initialize the dynamic linker. The argument is the address at which 816 * the dynamic linker has been mapped into memory. The primary task of 817 * this function is to relocate the dynamic linker. 818 */ 819 static void 820 init_rtld(caddr_t mapbase) 821 { 822 /* 823 * Conjure up an Obj_Entry structure for the dynamic linker. 824 * 825 * The "path" member is supposed to be dynamically-allocated, but we 826 * aren't yet initialized sufficiently to do that. Below we will 827 * replace the static version with a dynamically-allocated copy. 828 */ 829 obj_rtld.path = "/usr/libexec/ld-elf.so.1"; 830 obj_rtld.rtld = true; 831 obj_rtld.mapbase = mapbase; 832 #ifdef PIC 833 obj_rtld.relocbase = mapbase; 834 #endif 835 if (&_DYNAMIC != 0) { 836 obj_rtld.dynamic = rtld_dynamic(&obj_rtld); 837 digest_dynamic(&obj_rtld); 838 assert(obj_rtld.needed == NULL); 839 assert(!obj_rtld.textrel); 840 841 /* 842 * Temporarily put the dynamic linker entry into the object list, so 843 * that symbols can be found. 844 */ 845 obj_list = &obj_rtld; 846 obj_tail = &obj_rtld.next; 847 848 relocate_objects(&obj_rtld, true); 849 } 850 851 /* Make the object list empty again. */ 852 obj_list = NULL; 853 obj_tail = &obj_list; 854 855 /* Replace the path with a dynamically allocated copy. */ 856 obj_rtld.path = xstrdup(obj_rtld.path); 857 858 r_debug.r_brk = r_debug_state; 859 r_debug.r_state = RT_CONSISTENT; 860 } 861 862 static bool 863 is_exported(const Elf_Sym *def) 864 { 865 func_ptr_type value; 866 const func_ptr_type *p; 867 868 value = (func_ptr_type)(obj_rtld.relocbase + def->st_value); 869 for (p = exports; *p != NULL; p++) 870 if (*p == value) 871 return true; 872 return false; 873 } 874 875 /* 876 * Given a shared object, traverse its list of needed objects, and load 877 * each of them. Returns 0 on success. Generates an error message and 878 * returns -1 on failure. 879 */ 880 static int 881 load_needed_objects(Obj_Entry *first) 882 { 883 Obj_Entry *obj; 884 885 for (obj = first; obj != NULL; obj = obj->next) { 886 Needed_Entry *needed; 887 888 for (needed = obj->needed; needed != NULL; needed = needed->next) { 889 const char *name = obj->strtab + needed->name; 890 char *path = find_library(name, obj); 891 892 needed->obj = NULL; 893 if (path == NULL && !ld_tracing) 894 return -1; 895 896 if (path) { 897 needed->obj = load_object(path); 898 if (needed->obj == NULL && !ld_tracing) 899 return -1; /* XXX - cleanup */ 900 } 901 } 902 } 903 904 return 0; 905 } 906 907 static int 908 load_preload_objects(void) 909 { 910 char *p = ld_preload; 911 912 if (p == NULL) 913 return NULL; 914 915 p += strspn(p, ":;"); 916 while (*p != '\0') { 917 size_t len = strcspn(p, ":;"); 918 char *path; 919 char savech; 920 921 savech = p[len]; 922 p[len] = '\0'; 923 if ((path = find_library(p, NULL)) == NULL) 924 return -1; 925 if (load_object(path) == NULL) 926 return -1; /* XXX - cleanup */ 927 p[len] = savech; 928 p += len; 929 p += strspn(p, ":;"); 930 } 931 return 0; 932 } 933 934 /* 935 * Load a shared object into memory, if it is not already loaded. The 936 * argument must be a string allocated on the heap. This function assumes 937 * responsibility for freeing it when necessary. 938 * 939 * Returns a pointer to the Obj_Entry for the object. Returns NULL 940 * on failure. 941 */ 942 static Obj_Entry * 943 load_object(char *path) 944 { 945 Obj_Entry *obj; 946 947 for (obj = obj_list->next; obj != NULL; obj = obj->next) 948 if (strcmp(obj->path, path) == 0) 949 break; 950 951 if (obj == NULL) { /* First use of this object, so we must map it in */ 952 int fd; 953 954 if ((fd = open(path, O_RDONLY)) == -1) { 955 _rtld_error("Cannot open \"%s\"", path); 956 return NULL; 957 } 958 dbg("loading \"%s\"", path); 959 obj = map_object(fd, path); 960 close(fd); 961 if (obj == NULL) { 962 free(path); 963 return NULL; 964 } 965 966 obj->path = path; 967 digest_dynamic(obj); 968 969 *obj_tail = obj; 970 obj_tail = &obj->next; 971 linkmap_add(obj); /* for GDB */ 972 973 dbg(" %p .. %p: %s", obj->mapbase, 974 obj->mapbase + obj->mapsize - 1, obj->path); 975 if (obj->textrel) 976 dbg(" WARNING: %s has impure text", obj->path); 977 } else 978 free(path); 979 980 obj->refcount++; 981 return obj; 982 } 983 984 static Obj_Entry * 985 obj_from_addr(const void *addr) 986 { 987 unsigned long endhash; 988 Obj_Entry *obj; 989 990 endhash = elf_hash(END_SYM); 991 for (obj = obj_list; obj != NULL; obj = obj->next) { 992 const Elf_Sym *endsym; 993 994 if (addr < (void *) obj->mapbase) 995 continue; 996 if ((endsym = symlook_obj(END_SYM, endhash, obj, true)) == NULL) 997 continue; /* No "end" symbol?! */ 998 if (addr < (void *) (obj->relocbase + endsym->st_value)) 999 return obj; 1000 } 1001 return NULL; 1002 } 1003 1004 /* 1005 * Relocate newly-loaded shared objects. The argument is a pointer to 1006 * the Obj_Entry for the first such object. All objects from the first 1007 * to the end of the list of objects are relocated. Returns 0 on success, 1008 * or -1 on failure. 1009 */ 1010 static int 1011 relocate_objects(Obj_Entry *first, bool bind_now) 1012 { 1013 Obj_Entry *obj; 1014 1015 for (obj = first; obj != NULL; obj = obj->next) { 1016 if (obj != &obj_rtld) 1017 dbg("relocating \"%s\"", obj->path); 1018 if (obj->nbuckets == 0 || obj->nchains == 0 || obj->buckets == NULL || 1019 obj->symtab == NULL || obj->strtab == NULL) { 1020 _rtld_error("%s: Shared object has no run-time symbol table", 1021 obj->path); 1022 return -1; 1023 } 1024 1025 if (obj->textrel) { 1026 /* There are relocations to the write-protected text segment. */ 1027 if (mprotect(obj->mapbase, obj->textsize, 1028 PROT_READ|PROT_WRITE|PROT_EXEC) == -1) { 1029 _rtld_error("%s: Cannot write-enable text segment: %s", 1030 obj->path, strerror(errno)); 1031 return -1; 1032 } 1033 } 1034 1035 /* Process the non-PLT relocations. */ 1036 if (reloc_non_plt(obj, &obj_rtld)) 1037 return -1; 1038 1039 if (obj->textrel) { /* Re-protected the text segment. */ 1040 if (mprotect(obj->mapbase, obj->textsize, 1041 PROT_READ|PROT_EXEC) == -1) { 1042 _rtld_error("%s: Cannot write-protect text segment: %s", 1043 obj->path, strerror(errno)); 1044 return -1; 1045 } 1046 } 1047 1048 /* Process the PLT relocations. */ 1049 if (reloc_plt(obj, bind_now)) 1050 return -1; 1051 1052 /* 1053 * Set up the magic number and version in the Obj_Entry. These 1054 * were checked in the crt1.o from the original ElfKit, so we 1055 * set them for backward compatibility. 1056 */ 1057 obj->magic = RTLD_MAGIC; 1058 obj->version = RTLD_VERSION; 1059 1060 /* Set the special PLT or GOT entries. */ 1061 init_pltgot(obj); 1062 } 1063 1064 return 0; 1065 } 1066 1067 /* 1068 * Cleanup procedure. It will be called (by the atexit mechanism) just 1069 * before the process exits. 1070 */ 1071 static void 1072 rtld_exit(void) 1073 { 1074 dbg("rtld_exit()"); 1075 call_fini_functions(obj_list->next); 1076 } 1077 1078 static char * 1079 search_library_path(const char *name, const char *path) 1080 { 1081 size_t namelen = strlen(name); 1082 const char *p = path; 1083 1084 if (p == NULL) 1085 return NULL; 1086 1087 p += strspn(p, ":;"); 1088 while (*p != '\0') { 1089 size_t len = strcspn(p, ":;"); 1090 1091 if (*p == '/' || trust) { 1092 char *pathname; 1093 const char *dir = p; 1094 size_t dirlen = len; 1095 1096 pathname = xmalloc(dirlen + 1 + namelen + 1); 1097 strncpy(pathname, dir, dirlen); 1098 pathname[dirlen] = '/'; 1099 strcpy(pathname + dirlen + 1, name); 1100 1101 dbg(" Trying \"%s\"", pathname); 1102 if (access(pathname, F_OK) == 0) /* We found it */ 1103 return pathname; 1104 1105 free(pathname); 1106 } 1107 p += len; 1108 p += strspn(p, ":;"); 1109 } 1110 1111 return NULL; 1112 } 1113 1114 int 1115 dlclose(void *handle) 1116 { 1117 Obj_Entry *root = dlcheck(handle); 1118 1119 if (root == NULL) 1120 return -1; 1121 1122 GDB_STATE(RT_DELETE); 1123 unload_object(root, true); 1124 root->dl_refcount--; 1125 GDB_STATE(RT_CONSISTENT); 1126 1127 return 0; 1128 } 1129 1130 const char * 1131 dlerror(void) 1132 { 1133 char *msg = error_message; 1134 error_message = NULL; 1135 return msg; 1136 } 1137 1138 void * 1139 dlopen(const char *name, int mode) 1140 { 1141 Obj_Entry **old_obj_tail = obj_tail; 1142 Obj_Entry *obj = NULL; 1143 1144 GDB_STATE(RT_ADD); 1145 1146 if (name == NULL) { 1147 obj = obj_main; 1148 obj->refcount++; 1149 } else { 1150 char *path = find_library(name, obj_main); 1151 if (path != NULL) 1152 obj = load_object(path); 1153 } 1154 1155 if (obj) { 1156 obj->dl_refcount++; 1157 if (*old_obj_tail != NULL) { /* We loaded something new. */ 1158 assert(*old_obj_tail == obj); 1159 1160 if (load_needed_objects(obj) == -1 || 1161 relocate_objects(obj, mode == RTLD_NOW) == -1) { 1162 unload_object(obj, false); 1163 obj->dl_refcount--; 1164 obj = NULL; 1165 } else 1166 call_init_functions(obj); 1167 } 1168 } 1169 1170 GDB_STATE(RT_CONSISTENT); 1171 1172 return obj; 1173 } 1174 1175 void * 1176 dlsym(void *handle, const char *name) 1177 { 1178 const Obj_Entry *obj; 1179 unsigned long hash; 1180 const Elf_Sym *def; 1181 1182 hash = elf_hash(name); 1183 def = NULL; 1184 1185 if (handle == NULL || handle == RTLD_NEXT) { 1186 void *retaddr; 1187 1188 retaddr = __builtin_return_address(0); /* __GNUC__ only */ 1189 if ((obj = obj_from_addr(retaddr)) == NULL) { 1190 _rtld_error("Cannot determine caller's shared object"); 1191 return NULL; 1192 } 1193 if (handle == NULL) /* Just the caller's shared object. */ 1194 def = symlook_obj(name, hash, obj, true); 1195 else { /* All the shared objects after the caller's */ 1196 while ((obj = obj->next) != NULL) 1197 if ((def = symlook_obj(name, hash, obj, true)) != NULL) 1198 break; 1199 } 1200 } else { 1201 if ((obj = dlcheck(handle)) == NULL) 1202 return NULL; 1203 1204 if (obj->mainprog) { 1205 /* Search main program and all libraries loaded by it. */ 1206 for ( ; obj != *main_tail; obj = obj->next) 1207 if ((def = symlook_obj(name, hash, obj, true)) != NULL) 1208 break; 1209 } else { 1210 /* 1211 * XXX - This isn't correct. The search should include the whole 1212 * DAG rooted at the given object. 1213 */ 1214 def = symlook_obj(name, hash, obj, true); 1215 } 1216 } 1217 1218 if (def != NULL) 1219 return obj->relocbase + def->st_value; 1220 1221 _rtld_error("Undefined symbol \"%s\"", name); 1222 return NULL; 1223 } 1224 1225 int 1226 dladdr(const void *addr, Dl_info *info) 1227 { 1228 const Obj_Entry *obj; 1229 const Elf_Sym *def; 1230 void *symbol_addr; 1231 unsigned long symoffset; 1232 1233 obj = obj_from_addr(addr); 1234 if (obj == NULL) { 1235 _rtld_error("No shared object contains address"); 1236 return 0; 1237 } 1238 info->dli_fname = obj->path; 1239 info->dli_fbase = obj->mapbase; 1240 info->dli_saddr = (void *)0; 1241 info->dli_sname = NULL; 1242 1243 /* 1244 * Walk the symbol list looking for the symbol whose address is 1245 * closest to the address sent in. 1246 */ 1247 for (symoffset = 0; symoffset < obj->nchains; symoffset++) { 1248 def = obj->symtab + symoffset; 1249 1250 /* 1251 * For skip the symbol if st_shndx is either SHN_UNDEF or 1252 * SHN_COMMON. 1253 */ 1254 if (def->st_shndx == SHN_UNDEF || def->st_shndx == SHN_COMMON) 1255 continue; 1256 1257 /* 1258 * If the symbol is greater than the specified address, or if it 1259 * is further away from addr than the current nearest symbol, 1260 * then reject it. 1261 */ 1262 symbol_addr = obj->relocbase + def->st_value; 1263 if (symbol_addr > addr || symbol_addr < info->dli_saddr) 1264 continue; 1265 1266 /* Update our idea of the nearest symbol. */ 1267 info->dli_sname = obj->strtab + def->st_name; 1268 info->dli_saddr = symbol_addr; 1269 1270 /* Exact match? */ 1271 if (info->dli_saddr == addr) 1272 break; 1273 } 1274 return 1; 1275 } 1276 1277 static void 1278 linkmap_add(Obj_Entry *obj) 1279 { 1280 struct link_map *l = &obj->linkmap; 1281 struct link_map *prev; 1282 1283 obj->linkmap.l_name = obj->path; 1284 obj->linkmap.l_addr = obj->mapbase; 1285 obj->linkmap.l_ld = obj->dynamic; 1286 #ifdef __mips__ 1287 /* GDB needs load offset on MIPS to use the symbols */ 1288 obj->linkmap.l_offs = obj->relocbase; 1289 #endif 1290 1291 if (r_debug.r_map == NULL) { 1292 r_debug.r_map = l; 1293 return; 1294 } 1295 1296 /* 1297 * Scan to the end of the list, but not past the entry for the 1298 * dynamic linker, which we want to keep at the very end. 1299 */ 1300 for (prev = r_debug.r_map; 1301 prev->l_next != NULL && prev->l_next != &obj_rtld.linkmap; 1302 prev = prev->l_next) 1303 ; 1304 1305 /* Link in the new entry. */ 1306 l->l_prev = prev; 1307 l->l_next = prev->l_next; 1308 if (l->l_next != NULL) 1309 l->l_next->l_prev = l; 1310 prev->l_next = l; 1311 } 1312 1313 static void 1314 linkmap_delete(Obj_Entry *obj) 1315 { 1316 struct link_map *l = &obj->linkmap; 1317 1318 if (l->l_prev == NULL) { 1319 if ((r_debug.r_map = l->l_next) != NULL) 1320 l->l_next->l_prev = NULL; 1321 return; 1322 } 1323 1324 if ((l->l_prev->l_next = l->l_next) != NULL) 1325 l->l_next->l_prev = l->l_prev; 1326 } 1327 1328 /* 1329 * Function for the debugger to set a breakpoint on to gain control. 1330 */ 1331 void 1332 r_debug_state(void) 1333 { 1334 } 1335 1336 /* 1337 * Set a pointer variable in the main program to the given value. This 1338 * is used to set key variables such as "environ" before any of the 1339 * init functions are called. 1340 */ 1341 static void 1342 set_program_var(const char *name, const void *value) 1343 { 1344 const Obj_Entry *obj; 1345 unsigned long hash; 1346 1347 hash = elf_hash(name); 1348 for (obj = obj_main; obj != NULL; obj = obj->next) { 1349 const Elf_Sym *def; 1350 1351 if ((def = symlook_obj(name, hash, obj, false)) != NULL) { 1352 const void **addr; 1353 1354 addr = (const void **)(obj->relocbase + def->st_value); 1355 dbg("\"%s\": *%p <-- %p", name, addr, value); 1356 *addr = value; 1357 break; 1358 } 1359 } 1360 } 1361 1362 /* 1363 * Search the symbol table of a single shared object for a symbol of 1364 * the given name. Returns a pointer to the symbol, or NULL if no 1365 * definition was found. 1366 * 1367 * The symbol's hash value is passed in for efficiency reasons; that 1368 * eliminates many recomputations of the hash value. 1369 */ 1370 const Elf_Sym * 1371 symlook_obj(const char *name, unsigned long hash, const Obj_Entry *obj, 1372 bool in_plt) 1373 { 1374 if (obj->buckets != NULL) { 1375 unsigned long symnum = obj->buckets[hash % obj->nbuckets]; 1376 1377 while (symnum != STN_UNDEF) { 1378 const Elf_Sym *symp; 1379 const char *strp; 1380 1381 if (symnum >= obj->nchains) 1382 return NULL; /* Bad object */ 1383 symp = obj->symtab + symnum; 1384 strp = obj->strtab + symp->st_name; 1385 1386 if (strcmp(name, strp) == 0) 1387 return symp->st_shndx != SHN_UNDEF || 1388 (!in_plt && symp->st_value != 0 && 1389 ELF_ST_TYPE(symp->st_info) == STT_FUNC) ? symp : NULL; 1390 1391 symnum = obj->chains[symnum]; 1392 } 1393 } 1394 return NULL; 1395 } 1396 1397 static void 1398 trace_loaded_objects(Obj_Entry *obj) 1399 { 1400 char *fmt1, *fmt2, *fmt, *main_local; 1401 int c; 1402 1403 if ((main_local = getenv("LD_TRACE_LOADED_OBJECTS_PROGNAME")) == NULL) 1404 main_local = ""; 1405 1406 if ((fmt1 = getenv("LD_TRACE_LOADED_OBJECTS_FMT1")) == NULL) 1407 fmt1 = "\t%o => %p (%x)\n"; 1408 1409 if ((fmt2 = getenv("LD_TRACE_LOADED_OBJECTS_FMT2")) == NULL) 1410 fmt2 = "\t%o (%x)\n"; 1411 1412 for (; obj; obj = obj->next) { 1413 Needed_Entry *needed; 1414 char *name, *path; 1415 bool is_lib; 1416 1417 for (needed = obj->needed; needed; needed = needed->next) { 1418 if (needed->obj != NULL) { 1419 if (needed->obj->traced) 1420 continue; 1421 needed->obj->traced = true; 1422 path = needed->obj->path; 1423 } else 1424 path = "not found"; 1425 1426 name = (char *)obj->strtab + needed->name; 1427 is_lib = strncmp(name, "lib", 3) == 0; /* XXX - bogus */ 1428 1429 fmt = is_lib ? fmt1 : fmt2; 1430 while ((c = *fmt++) != '\0') { 1431 switch (c) { 1432 default: 1433 putchar(c); 1434 continue; 1435 case '\\': 1436 switch (c = *fmt) { 1437 case '\0': 1438 continue; 1439 case 'n': 1440 putchar('\n'); 1441 break; 1442 case 't': 1443 putchar('\t'); 1444 break; 1445 } 1446 break; 1447 case '%': 1448 switch (c = *fmt) { 1449 case '\0': 1450 continue; 1451 case '%': 1452 default: 1453 putchar(c); 1454 break; 1455 case 'A': 1456 printf("%s", main_local); 1457 break; 1458 case 'a': 1459 printf("%s", obj_main->path); 1460 break; 1461 case 'o': 1462 printf("%s", name); 1463 break; 1464 #if 0 1465 case 'm': 1466 printf("%d", sodp->sod_major); 1467 break; 1468 case 'n': 1469 printf("%d", sodp->sod_minor); 1470 break; 1471 #endif 1472 case 'p': 1473 printf("%s", path); 1474 break; 1475 case 'x': 1476 printf("%p", needed->obj ? needed->obj->mapbase : 0); 1477 break; 1478 } 1479 break; 1480 } 1481 ++fmt; 1482 } 1483 } 1484 } 1485 } 1486 1487 static void 1488 unload_object(Obj_Entry *root, bool do_fini_funcs) 1489 { 1490 unref_object_dag(root); 1491 if (root->refcount == 0) { /* We are finished with some objects. */ 1492 Obj_Entry *obj; 1493 Obj_Entry **linkp; 1494 1495 /* Finalize objects that are about to be unmapped. */ 1496 if (do_fini_funcs) 1497 for (obj = obj_list->next; obj != NULL; obj = obj->next) 1498 if (obj->refcount == 0 && obj->fini != NULL) 1499 (*obj->fini)(); 1500 1501 /* Unmap all objects that are no longer referenced. */ 1502 linkp = &obj_list->next; 1503 while ((obj = *linkp) != NULL) { 1504 if (obj->refcount == 0) { 1505 dbg("unloading \"%s\"", obj->path); 1506 munmap(obj->mapbase, obj->mapsize); 1507 free(obj->path); 1508 while (obj->needed != NULL) { 1509 Needed_Entry *needed = obj->needed; 1510 obj->needed = needed->next; 1511 free(needed); 1512 } 1513 linkmap_delete(obj); 1514 *linkp = obj->next; 1515 free(obj); 1516 } else 1517 linkp = &obj->next; 1518 } 1519 obj_tail = linkp; 1520 } 1521 } 1522 1523 static void 1524 unref_object_dag(Obj_Entry *root) 1525 { 1526 const Needed_Entry *needed; 1527 1528 assert(root->refcount != 0); 1529 root->refcount--; 1530 if (root->refcount == 0) 1531 for (needed = root->needed; needed != NULL; needed = needed->next) 1532 if (needed->obj != NULL) 1533 unref_object_dag(needed->obj); 1534 } 1535 1536 /* 1537 * Non-mallocing printf, for use by malloc itself. 1538 * XXX - This doesn't belong in this module. 1539 */ 1540 void 1541 xprintf(const char *fmt, ...) 1542 { 1543 char buf[256]; 1544 va_list ap; 1545 1546 va_start(ap, fmt); 1547 vsprintf(buf, fmt, ap); 1548 (void)write(1, buf, strlen(buf)); 1549 va_end(ap); 1550 } 1551