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