1 /* $NetBSD: rtld.c,v 1.117 2007/12/07 20:34:05 ad Exp $ */ 2 3 /* 4 * Copyright 1996 John D. Polstra. 5 * Copyright 1996 Matt Thomas <matt@3am-software.com> 6 * Copyright 2002 Charles M. Hannum <root@ihack.net> 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed by John Polstra. 20 * 4. The name of the author may not be used to endorse or promote products 21 * derived from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 /* 36 * Dynamic linker for ELF. 37 * 38 * John Polstra <jdp@polstra.com>. 39 */ 40 41 #include <sys/cdefs.h> 42 #ifndef lint 43 __RCSID("$NetBSD: rtld.c,v 1.117 2007/12/07 20:34:05 ad Exp $"); 44 #endif /* not lint */ 45 46 #include <err.h> 47 #include <errno.h> 48 #include <fcntl.h> 49 #include <stdarg.h> 50 #include <stdio.h> 51 #include <stdlib.h> 52 #include <string.h> 53 #include <unistd.h> 54 #include <sys/param.h> 55 #include <sys/mman.h> 56 #include <dirent.h> 57 58 #include <ctype.h> 59 60 #include <dlfcn.h> 61 #include "debug.h" 62 #include "rtld.h" 63 64 #if !defined(lint) 65 #include "sysident.h" 66 #endif 67 68 /* 69 * Function declarations. 70 */ 71 static void _rtld_init(caddr_t, caddr_t, const char *); 72 static void _rtld_exit(void); 73 74 Elf_Addr _rtld(Elf_Addr *, Elf_Addr); 75 76 77 /* 78 * Data declarations. 79 */ 80 static char *error_message; /* Message for dlopen(), or NULL */ 81 82 struct r_debug _rtld_debug; /* for GDB; */ 83 bool _rtld_trust; /* False for setuid and setgid programs */ 84 Obj_Entry *_rtld_objlist; /* Head of linked list of shared objects */ 85 Obj_Entry **_rtld_objtail; /* Link field of last object in list */ 86 Obj_Entry *_rtld_objmain; /* The main program shared object */ 87 Obj_Entry _rtld_objself; /* The dynamic linker shared object */ 88 char *_rtld_path = _PATH_RTLD; 89 Elf_Sym _rtld_sym_zero; /* For resolving undefined weak refs. */ 90 int _rtld_pagesz; /* Page size, as provided by kernel */ 91 92 Search_Path *_rtld_default_paths; 93 Search_Path *_rtld_paths; 94 95 Library_Xform *_rtld_xforms; 96 97 /* 98 * Global declarations normally provided by crt0. 99 */ 100 char *__progname; 101 char **environ; 102 103 #if defined(RTLD_DEBUG) 104 #ifndef __sh__ 105 extern Elf_Addr _GLOBAL_OFFSET_TABLE_[]; 106 #else /* 32-bit SuperH */ 107 register Elf_Addr *_GLOBAL_OFFSET_TABLE_ asm("r12"); 108 #endif 109 #endif /* RTLD_DEBUG */ 110 extern Elf_Dyn _DYNAMIC; 111 112 static void _rtld_call_fini_functions(int); 113 static void _rtld_call_init_functions(void); 114 static void _rtld_initlist_visit(Objlist *, Obj_Entry *, int); 115 static void _rtld_initlist_tsort(Objlist *, int); 116 static Obj_Entry *_rtld_dlcheck(void *); 117 static void _rtld_init_dag(Obj_Entry *); 118 static void _rtld_init_dag1(Obj_Entry *, Obj_Entry *); 119 static void _rtld_objlist_remove(Objlist *, Obj_Entry *); 120 static void _rtld_objlist_clear(Objlist *); 121 static void _rtld_unload_object(Obj_Entry *, bool); 122 static void _rtld_unref_dag(Obj_Entry *); 123 static Obj_Entry *_rtld_obj_from_addr(const void *); 124 125 static void 126 _rtld_call_fini_functions(int force) 127 { 128 Objlist_Entry *elm; 129 Objlist finilist; 130 Obj_Entry *obj; 131 132 dbg(("_rtld_call_fini_functions(%d)", force)); 133 134 SIMPLEQ_INIT(&finilist); 135 _rtld_initlist_tsort(&finilist, 1); 136 137 /* First pass: objects _not_ marked with DF_1_INITFIRST. */ 138 SIMPLEQ_FOREACH(elm, &finilist, link) { 139 obj = elm->obj; 140 if (obj->refcount > 0 && !force) { 141 continue; 142 } 143 if (obj->fini == NULL || obj->fini_called || obj->initfirst) { 144 continue; 145 } 146 dbg (("calling fini function %s at %p", obj->path, 147 (void *)obj->fini)); 148 obj->fini_called = 1; 149 (*obj->fini)(); 150 } 151 152 /* Second pass: objects marked with DF_1_INITFIRST. */ 153 SIMPLEQ_FOREACH(elm, &finilist, link) { 154 obj = elm->obj; 155 if (obj->refcount > 0 && !force) { 156 continue; 157 } 158 if (obj->fini == NULL || obj->fini_called) { 159 continue; 160 } 161 dbg (("calling fini function %s at %p (DF_1_INITFIRST)", 162 obj->path, (void *)obj->fini)); 163 obj->fini_called = 1; 164 (*obj->fini)(); 165 } 166 167 _rtld_objlist_clear(&finilist); 168 } 169 170 static void 171 _rtld_call_init_functions() 172 { 173 Objlist_Entry *elm; 174 Objlist initlist; 175 Obj_Entry *obj; 176 177 dbg(("_rtld_call_init_functions()")); 178 SIMPLEQ_INIT(&initlist); 179 _rtld_initlist_tsort(&initlist, 0); 180 181 /* First pass: objects marked with DF_1_INITFIRST. */ 182 SIMPLEQ_FOREACH(elm, &initlist, link) { 183 obj = elm->obj; 184 if (obj->init == NULL || obj->init_called || !obj->initfirst) { 185 continue; 186 } 187 dbg (("calling init function %s at %p (DF_1_INITFIRST)", 188 obj->path, (void *)obj->init)); 189 obj->init_called = 1; 190 (*obj->init)(); 191 } 192 193 /* Second pass: all other objects. */ 194 SIMPLEQ_FOREACH(elm, &initlist, link) { 195 obj = elm->obj; 196 if (obj->init == NULL || obj->init_called) { 197 continue; 198 } 199 dbg (("calling init function %s at %p", obj->path, 200 (void *)obj->init)); 201 obj->init_called = 1; 202 (*obj->init)(); 203 } 204 205 _rtld_objlist_clear(&initlist); 206 } 207 208 /* 209 * Initialize the dynamic linker. The argument is the address at which 210 * the dynamic linker has been mapped into memory. The primary task of 211 * this function is to create an Obj_Entry for the dynamic linker and 212 * to resolve the PLT relocation for platforms that need it (those that 213 * define __HAVE_FUNCTION_DESCRIPTORS 214 */ 215 static void 216 _rtld_init(caddr_t mapbase, caddr_t relocbase, const char *execname) 217 { 218 219 /* Conjure up an Obj_Entry structure for the dynamic linker. */ 220 _rtld_objself.path = _rtld_path; 221 _rtld_objself.pathlen = strlen(_rtld_path); 222 _rtld_objself.rtld = true; 223 _rtld_objself.mapbase = mapbase; 224 _rtld_objself.relocbase = relocbase; 225 _rtld_objself.dynamic = (Elf_Dyn *) &_DYNAMIC; 226 227 _rtld_digest_dynamic(_rtld_path, &_rtld_objself); 228 assert(!_rtld_objself.needed); 229 #if !defined(__hppa__) 230 assert(!_rtld_objself.pltrel && !_rtld_objself.pltrela); 231 #else 232 _rtld_relocate_plt_objects(&_rtld_objself); 233 #endif 234 #if !defined(__mips__) && !defined(__hppa__) 235 assert(!_rtld_objself.pltgot); 236 #endif 237 #if !defined(__arm__) && !defined(__mips__) && !defined(__sh__) 238 /* ARM, MIPS and SH{3,5} have a bogus DT_TEXTREL. */ 239 assert(!_rtld_objself.textrel); 240 #endif 241 242 _rtld_add_paths(execname, &_rtld_default_paths, 243 RTLD_DEFAULT_LIBRARY_PATH); 244 245 /* 246 * Set up the _rtld_objlist pointer, so that rtld symbols can be found. 247 */ 248 _rtld_objlist = &_rtld_objself; 249 250 /* Make the object list empty again. */ 251 _rtld_objlist = NULL; 252 _rtld_objtail = &_rtld_objlist; 253 254 _rtld_debug.r_brk = _rtld_debug_state; 255 _rtld_debug.r_state = RT_CONSISTENT; 256 } 257 258 /* 259 * Cleanup procedure. It will be called (by the atexit() mechanism) just 260 * before the process exits. 261 */ 262 static void 263 _rtld_exit(void) 264 { 265 dbg(("rtld_exit()")); 266 267 _rtld_call_fini_functions(1); 268 } 269 270 /* 271 * Main entry point for dynamic linking. The argument is the stack 272 * pointer. The stack is expected to be laid out as described in the 273 * SVR4 ABI specification, Intel 386 Processor Supplement. Specifically, 274 * the stack pointer points to a word containing ARGC. Following that 275 * in the stack is a null-terminated sequence of pointers to argument 276 * strings. Then comes a null-terminated sequence of pointers to 277 * environment strings. Finally, there is a sequence of "auxiliary 278 * vector" entries. 279 * 280 * This function returns the entry point for the main program, the dynamic 281 * linker's exit procedure in sp[0], and a pointer to the main object in 282 * sp[1]. 283 */ 284 Elf_Addr 285 _rtld(Elf_Addr *sp, Elf_Addr relocbase) 286 { 287 const AuxInfo *pAUX_base, *pAUX_entry, *pAUX_execfd, *pAUX_phdr, 288 *pAUX_phent, *pAUX_phnum, *pAUX_euid, *pAUX_egid, 289 *pAUX_ruid, *pAUX_rgid; 290 const AuxInfo *pAUX_pagesz; 291 char **env; 292 const AuxInfo *aux; 293 const AuxInfo *auxp; 294 Elf_Addr *const osp = sp; 295 bool bind_now = 0; 296 const char *ld_bind_now; 297 const char **argv; 298 const char *execname; 299 long argc; 300 const char **real___progname; 301 const Obj_Entry **real___mainprog_obj; 302 char ***real_environ; 303 #if defined(RTLD_DEBUG) 304 int i = 0; 305 #endif 306 307 /* 308 * On entry, the dynamic linker itself has not been relocated yet. 309 * Be very careful not to reference any global data until after 310 * _rtld_init has returned. It is OK to reference file-scope statics 311 * and string constants, and to call static and global functions. 312 */ 313 /* Find the auxiliary vector on the stack. */ 314 /* first Elf_Word reserved to address of exit routine */ 315 #if defined(RTLD_DEBUG) 316 debug = 1; 317 dbg(("sp = %p, argc = %ld, argv = %p <%s> relocbase %p", sp, 318 (long)sp[2], &sp[3], (char *) sp[3], (void *)relocbase)); 319 dbg(("got is at %p, dynamic is at %p", _GLOBAL_OFFSET_TABLE_, 320 &_DYNAMIC)); 321 dbg(("_ctype_ is %p", _ctype_)); 322 #endif 323 324 sp += 2; /* skip over return argument space */ 325 argv = (const char **) &sp[1]; 326 argc = *(long *)sp; 327 sp += 2 + argc; /* Skip over argc, arguments, and NULL 328 * terminator */ 329 env = (char **) sp; 330 while (*sp++ != 0) { /* Skip over environment, and NULL terminator */ 331 #if defined(RTLD_DEBUG) 332 dbg(("env[%d] = %p %s", i++, (void *)sp[-1], (char *)sp[-1])); 333 #endif 334 } 335 aux = (const AuxInfo *) sp; 336 337 pAUX_base = pAUX_entry = pAUX_execfd = NULL; 338 pAUX_phdr = pAUX_phent = pAUX_phnum = NULL; 339 pAUX_euid = pAUX_ruid = pAUX_egid = pAUX_rgid = NULL; 340 pAUX_pagesz = NULL; 341 342 execname = NULL; 343 344 /* Digest the auxiliary vector. */ 345 for (auxp = aux; auxp->a_type != AT_NULL; ++auxp) { 346 switch (auxp->a_type) { 347 case AT_BASE: 348 pAUX_base = auxp; 349 break; 350 case AT_ENTRY: 351 pAUX_entry = auxp; 352 break; 353 case AT_EXECFD: 354 pAUX_execfd = auxp; 355 break; 356 case AT_PHDR: 357 pAUX_phdr = auxp; 358 break; 359 case AT_PHENT: 360 pAUX_phent = auxp; 361 break; 362 case AT_PHNUM: 363 pAUX_phnum = auxp; 364 break; 365 #ifdef AT_EUID 366 case AT_EUID: 367 pAUX_euid = auxp; 368 break; 369 case AT_RUID: 370 pAUX_ruid = auxp; 371 break; 372 case AT_EGID: 373 pAUX_egid = auxp; 374 break; 375 case AT_RGID: 376 pAUX_rgid = auxp; 377 break; 378 #endif 379 #ifdef AT_SUN_EXECNAME 380 case AT_SUN_EXECNAME: 381 execname = (const char *)(const void *)auxp->a_v; 382 break; 383 #endif 384 case AT_PAGESZ: 385 pAUX_pagesz = auxp; 386 break; 387 } 388 } 389 390 /* Initialize and relocate ourselves. */ 391 if (pAUX_base == NULL) { 392 _rtld_error("Bad pAUX_base"); 393 _rtld_die(); 394 } 395 assert(pAUX_pagesz != NULL); 396 _rtld_pagesz = (int)pAUX_pagesz->a_v; 397 _rtld_init((caddr_t)pAUX_base->a_v, (caddr_t)relocbase, execname); 398 399 __progname = _rtld_objself.path; 400 environ = env; 401 402 _rtld_trust = ((pAUX_euid ? (uid_t)pAUX_euid->a_v : geteuid()) == 403 (pAUX_ruid ? (uid_t)pAUX_ruid->a_v : getuid())) && 404 ((pAUX_egid ? (gid_t)pAUX_egid->a_v : getegid()) == 405 (pAUX_rgid ? (gid_t)pAUX_rgid->a_v : getgid())); 406 407 ld_bind_now = getenv("LD_BIND_NOW"); 408 if (ld_bind_now != NULL && *ld_bind_now != '\0') 409 bind_now = true; 410 if (_rtld_trust) { 411 #ifdef DEBUG 412 const char *ld_debug = getenv("LD_DEBUG"); 413 #ifdef RTLD_DEBUG 414 debug = 0; 415 #endif 416 if (ld_debug != NULL && *ld_debug != '\0') 417 debug = 1; 418 #endif 419 _rtld_add_paths(execname, &_rtld_paths, 420 getenv("LD_LIBRARY_PATH")); 421 } else { 422 execname = NULL; 423 unsetenv("LD_DEBUG"); 424 unsetenv("LD_LIBRARY_PATH"); 425 } 426 _rtld_process_hints(execname, &_rtld_paths, &_rtld_xforms, 427 _PATH_LD_HINTS); 428 dbg(("dynamic linker is initialized, mapbase=%p, relocbase=%p", 429 _rtld_objself.mapbase, _rtld_objself.relocbase)); 430 431 /* 432 * Load the main program, or process its program header if it is 433 * already loaded. 434 */ 435 if (pAUX_execfd != NULL) { /* Load the main program. */ 436 int fd = pAUX_execfd->a_v; 437 const char *obj_name = argv[0] ? argv[0] : "main program"; 438 dbg(("loading main program")); 439 _rtld_objmain = _rtld_map_object(obj_name, fd, NULL); 440 close(fd); 441 if (_rtld_objmain == NULL) 442 _rtld_die(); 443 } else { /* Main program already loaded. */ 444 const Elf_Phdr *phdr; 445 int phnum; 446 caddr_t entry; 447 448 dbg(("processing main program's program header")); 449 assert(pAUX_phdr != NULL); 450 phdr = (const Elf_Phdr *) pAUX_phdr->a_v; 451 assert(pAUX_phnum != NULL); 452 phnum = pAUX_phnum->a_v; 453 assert(pAUX_phent != NULL); 454 assert(pAUX_phent->a_v == sizeof(Elf_Phdr)); 455 assert(pAUX_entry != NULL); 456 entry = (caddr_t) pAUX_entry->a_v; 457 _rtld_objmain = _rtld_digest_phdr(phdr, phnum, entry); 458 _rtld_objmain->path = xstrdup(argv[0] ? argv[0] : 459 "main program"); 460 _rtld_objmain->pathlen = strlen(_rtld_objmain->path); 461 } 462 463 _rtld_objmain->mainprog = true; 464 465 /* 466 * Get the actual dynamic linker pathname from the executable if 467 * possible. (It should always be possible.) That ensures that 468 * gdb will find the right dynamic linker even if a non-standard 469 * one is being used. 470 */ 471 if (_rtld_objmain->interp != NULL && 472 strcmp(_rtld_objmain->interp, _rtld_objself.path) != 0) 473 _rtld_objself.path = xstrdup(_rtld_objmain->interp); 474 dbg(("actual dynamic linker is %s", _rtld_objself.path)); 475 476 _rtld_digest_dynamic(execname, _rtld_objmain); 477 478 /* Link the main program into the list of objects. */ 479 *_rtld_objtail = _rtld_objmain; 480 _rtld_objtail = &_rtld_objmain->next; 481 482 _rtld_linkmap_add(_rtld_objmain); 483 _rtld_linkmap_add(&_rtld_objself); 484 485 ++_rtld_objmain->refcount; 486 _rtld_objmain->mainref = 1; 487 _rtld_objlist_push_tail(&_rtld_list_main, _rtld_objmain); 488 489 /* Initialize a fake symbol for resolving undefined weak references. */ 490 _rtld_sym_zero.st_info = ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE); 491 _rtld_sym_zero.st_shndx = SHN_ABS; 492 493 if (_rtld_trust) { 494 /* 495 * Pre-load user-specified objects after the main program 496 * but before any shared object dependencies. 497 */ 498 dbg(("preloading objects")); 499 if (_rtld_preload(getenv("LD_PRELOAD")) == -1) 500 _rtld_die(); 501 } else 502 unsetenv("LD_PRELOAD"); 503 504 dbg(("loading needed objects")); 505 if (_rtld_load_needed_objects(_rtld_objmain, RTLD_MAIN) == -1) 506 _rtld_die(); 507 508 dbg(("relocating objects")); 509 if (_rtld_relocate_objects(_rtld_objmain, bind_now) == -1) 510 _rtld_die(); 511 512 dbg(("doing copy relocations")); 513 if (_rtld_do_copy_relocations(_rtld_objmain) == -1) 514 _rtld_die(); 515 516 /* 517 * Set the __progname, environ and, __mainprog_obj before 518 * calling anything that might use them. 519 */ 520 real___progname = _rtld_objmain_sym("__progname"); 521 if (real___progname) { 522 if (argv[0] != NULL) { 523 if ((*real___progname = strrchr(argv[0], '/')) == NULL) 524 (*real___progname) = argv[0]; 525 else 526 (*real___progname)++; 527 } else { 528 (*real___progname) = NULL; 529 } 530 } 531 real_environ = _rtld_objmain_sym("environ"); 532 if (real_environ) 533 *real_environ = environ; 534 /* 535 * Set __mainprog_obj for old binaries. 536 */ 537 real___mainprog_obj = _rtld_objmain_sym("__mainprog_obj"); 538 if (real___mainprog_obj) 539 *real___mainprog_obj = _rtld_objmain; 540 541 dbg(("calling _init functions")); 542 _rtld_call_init_functions(); 543 544 dbg(("control at program entry point = %p, obj = %p, exit = %p", 545 _rtld_objmain->entry, _rtld_objmain, _rtld_exit)); 546 547 /* 548 * Return with the entry point and the exit procedure in at the top 549 * of stack. 550 */ 551 552 _rtld_debug_state(); /* say hello to gdb! */ 553 554 ((void **) osp)[0] = _rtld_exit; 555 ((void **) osp)[1] = _rtld_objmain; 556 return (Elf_Addr) _rtld_objmain->entry; 557 } 558 559 void 560 _rtld_die(void) 561 { 562 const char *msg = dlerror(); 563 564 if (msg == NULL) 565 msg = "Fatal error"; 566 xerrx(1, "%s", msg); 567 } 568 569 static Obj_Entry * 570 _rtld_dlcheck(void *handle) 571 { 572 Obj_Entry *obj; 573 574 for (obj = _rtld_objlist; obj != NULL; obj = obj->next) 575 if (obj == (Obj_Entry *) handle) 576 break; 577 578 if (obj == NULL || obj->dl_refcount == 0) { 579 xwarnx("Invalid shared object handle %p", handle); 580 return NULL; 581 } 582 return obj; 583 } 584 585 static void 586 _rtld_initlist_visit(Objlist* list, Obj_Entry *obj, int rev) 587 { 588 Needed_Entry* elm; 589 590 /* dbg(("_rtld_initlist_visit(%s)", obj->path)); */ 591 592 if (obj->init_done) 593 return; 594 obj->init_done = 1; 595 596 for (elm = obj->needed; elm != NULL; elm = elm->next) { 597 if (elm->obj != NULL) { 598 _rtld_initlist_visit(list, elm->obj, rev); 599 } 600 } 601 602 if (rev) { 603 _rtld_objlist_push_head(list, obj); 604 } else { 605 _rtld_objlist_push_tail(list, obj); 606 } 607 } 608 609 static void 610 _rtld_initlist_tsort(Objlist* list, int rev) 611 { 612 dbg(("_rtld_initlist_tsort")); 613 614 Obj_Entry* obj; 615 616 for (obj = _rtld_objlist->next; obj; obj = obj->next) { 617 obj->init_done = 0; 618 } 619 620 for (obj = _rtld_objlist->next; obj; obj = obj->next) { 621 _rtld_initlist_visit(list, obj, rev); 622 } 623 } 624 625 static void 626 _rtld_init_dag(Obj_Entry *root) 627 { 628 629 _rtld_init_dag1(root, root); 630 } 631 632 static void 633 _rtld_init_dag1(Obj_Entry *root, Obj_Entry *obj) 634 { 635 const Needed_Entry *needed; 636 637 if (!obj->mainref) { 638 if (_rtld_objlist_find(&obj->dldags, root)) 639 return; 640 rdbg(("add %p (%s) to %p (%s) DAG", obj, obj->path, root, 641 root->path)); 642 _rtld_objlist_push_tail(&obj->dldags, root); 643 _rtld_objlist_push_tail(&root->dagmembers, obj); 644 } 645 for (needed = obj->needed; needed != NULL; needed = needed->next) 646 if (needed->obj != NULL) 647 _rtld_init_dag1(root, needed->obj); 648 } 649 650 /* 651 * Note, this is called only for objects loaded by dlopen(). 652 */ 653 static void 654 _rtld_unload_object(Obj_Entry *root, bool do_fini_funcs) 655 { 656 657 _rtld_unref_dag(root); 658 if (root->refcount == 0) { /* We are finished with some objects. */ 659 Obj_Entry *obj; 660 Obj_Entry **linkp; 661 Objlist_Entry *elm; 662 663 /* Finalize objects that are about to be unmapped. */ 664 if (do_fini_funcs) 665 _rtld_call_fini_functions(0); 666 667 /* Remove the DAG from all objects' DAG lists. */ 668 SIMPLEQ_FOREACH(elm, &root->dagmembers, link) 669 _rtld_objlist_remove(&elm->obj->dldags, root); 670 671 /* Remove the DAG from the RTLD_GLOBAL list. */ 672 if (root->globalref) { 673 root->globalref = 0; 674 _rtld_objlist_remove(&_rtld_list_global, root); 675 } 676 677 /* Unmap all objects that are no longer referenced. */ 678 linkp = &_rtld_objlist->next; 679 while ((obj = *linkp) != NULL) { 680 if (obj->refcount == 0) { 681 #ifdef RTLD_DEBUG 682 dbg(("unloading \"%s\"", obj->path)); 683 #endif 684 munmap(obj->mapbase, obj->mapsize); 685 _rtld_objlist_remove(&_rtld_list_global, obj); 686 _rtld_linkmap_delete(obj); 687 *linkp = obj->next; 688 _rtld_obj_free(obj); 689 } else 690 linkp = &obj->next; 691 } 692 _rtld_objtail = linkp; 693 } 694 } 695 696 static void 697 _rtld_unref_dag(Obj_Entry *root) 698 { 699 700 assert(root); 701 assert(root->refcount != 0); 702 --root->refcount; 703 if (root->refcount == 0) { 704 const Needed_Entry *needed; 705 706 for (needed = root->needed; needed != NULL; 707 needed = needed->next) { 708 if (needed->obj != NULL) 709 _rtld_unref_dag(needed->obj); 710 } 711 } 712 } 713 714 __strong_alias(__dlclose,dlclose) 715 int 716 dlclose(void *handle) 717 { 718 Obj_Entry *root = _rtld_dlcheck(handle); 719 720 if (root == NULL) 721 return -1; 722 723 _rtld_debug.r_state = RT_DELETE; 724 _rtld_debug_state(); 725 726 --root->dl_refcount; 727 _rtld_unload_object(root, true); 728 729 _rtld_debug.r_state = RT_CONSISTENT; 730 _rtld_debug_state(); 731 732 return 0; 733 } 734 735 __strong_alias(__dlerror,dlerror) 736 char * 737 dlerror(void) 738 { 739 char *msg = error_message; 740 741 error_message = NULL; 742 return msg; 743 } 744 745 __strong_alias(__dlopen,dlopen) 746 void * 747 dlopen(const char *name, int mode) 748 { 749 Obj_Entry **old_obj_tail = _rtld_objtail; 750 Obj_Entry *obj = NULL; 751 752 _rtld_debug.r_state = RT_ADD; 753 _rtld_debug_state(); 754 755 if (name == NULL) { 756 obj = _rtld_objmain; 757 obj->refcount++; 758 } else 759 obj = _rtld_load_library(name, _rtld_objmain, mode); 760 761 if (obj != NULL) { 762 ++obj->dl_refcount; 763 if (*old_obj_tail != NULL) { /* We loaded something new. */ 764 assert(*old_obj_tail == obj); 765 766 if (_rtld_load_needed_objects(obj, mode) == -1 || 767 (_rtld_init_dag(obj), 768 _rtld_relocate_objects(obj, 769 ((mode & 3) == RTLD_NOW))) == -1) { 770 _rtld_unload_object(obj, false); 771 obj->dl_refcount--; 772 obj = NULL; 773 } else { 774 _rtld_call_init_functions(); 775 } 776 } 777 } 778 _rtld_debug.r_state = RT_CONSISTENT; 779 _rtld_debug_state(); 780 781 return obj; 782 } 783 784 /* 785 * Find a symbol in the main program. 786 */ 787 void * 788 _rtld_objmain_sym(const char *name) 789 { 790 unsigned long hash; 791 const Elf_Sym *def; 792 const Obj_Entry *obj; 793 794 hash = _rtld_elf_hash(name); 795 obj = _rtld_objmain; 796 797 def = _rtld_symlook_list(name, hash, &_rtld_list_main, &obj, false); 798 799 if (def != NULL) 800 return obj->relocbase + def->st_value; 801 return(NULL); 802 } 803 804 __strong_alias(__dlsym,dlsym) 805 void * 806 dlsym(void *handle, const char *name) 807 { 808 const Obj_Entry *obj; 809 unsigned long hash; 810 const Elf_Sym *def; 811 const Obj_Entry *defobj; 812 void *retaddr; 813 814 hash = _rtld_elf_hash(name); 815 def = NULL; 816 defobj = NULL; 817 818 switch ((intptr_t)handle) { 819 case (intptr_t)NULL: 820 case (intptr_t)RTLD_NEXT: 821 case (intptr_t)RTLD_DEFAULT: 822 case (intptr_t)RTLD_SELF: 823 retaddr = __builtin_return_address(0); /* __GNUC__ only */ 824 if ((obj = _rtld_obj_from_addr(retaddr)) == NULL) { 825 _rtld_error("Cannot determine caller's shared object"); 826 return NULL; 827 } 828 829 switch ((intptr_t)handle) { 830 case (intptr_t)NULL: /* Just the caller's shared object. */ 831 def = _rtld_symlook_obj(name, hash, obj, false); 832 defobj = obj; 833 break; 834 835 case (intptr_t)RTLD_NEXT: /* Objects after callers */ 836 obj = obj->next; 837 /*FALLTHROUGH*/ 838 839 case (intptr_t)RTLD_SELF: /* Caller included */ 840 for (; obj; obj = obj->next) { 841 if ((def = _rtld_symlook_obj(name, hash, obj, 842 false)) != NULL) { 843 defobj = obj; 844 break; 845 } 846 } 847 break; 848 849 case (intptr_t)RTLD_DEFAULT: 850 def = _rtld_symlook_default(name, hash, obj, &defobj, 851 false); 852 break; 853 854 default: 855 abort(); 856 } 857 break; 858 859 default: 860 if ((obj = _rtld_dlcheck(handle)) == NULL) 861 return NULL; 862 863 if (obj->mainprog) { 864 /* Search main program and all libraries loaded by it */ 865 def = _rtld_symlook_list(name, hash, &_rtld_list_main, 866 &defobj, false); 867 } else { 868 /* 869 * XXX - This isn't correct. The search should include 870 * the whole DAG rooted at the given object. 871 */ 872 def = _rtld_symlook_obj(name, hash, obj, false); 873 defobj = obj; 874 } 875 break; 876 } 877 878 if (def != NULL) { 879 #ifdef __HAVE_FUNCTION_DESCRIPTORS 880 if (ELF_ST_TYPE(def->st_info) == STT_FUNC) 881 return (void *)_rtld_function_descriptor_alloc(defobj, 882 def, 0); 883 #endif /* __HAVE_FUNCTION_DESCRIPTORS */ 884 return defobj->relocbase + def->st_value; 885 } 886 887 _rtld_error("Undefined symbol \"%s\"", name); 888 return NULL; 889 } 890 891 __strong_alias(__dladdr,dladdr) 892 int 893 dladdr(const void *addr, Dl_info *info) 894 { 895 const Obj_Entry *obj; 896 const Elf_Sym *def, *best_def; 897 void *symbol_addr; 898 unsigned long symoffset; 899 900 #ifdef __HAVE_FUNCTION_DESCRIPTORS 901 addr = _rtld_function_descriptor_function(addr); 902 #endif /* __HAVE_FUNCTION_DESCRIPTORS */ 903 904 obj = _rtld_obj_from_addr(addr); 905 if (obj == NULL) { 906 _rtld_error("No shared object contains address"); 907 return 0; 908 } 909 info->dli_fname = obj->path; 910 info->dli_fbase = obj->mapbase; 911 info->dli_saddr = (void *)0; 912 info->dli_sname = NULL; 913 914 /* 915 * Walk the symbol list looking for the symbol whose address is 916 * closest to the address sent in. 917 */ 918 best_def = NULL; 919 for (symoffset = 0; symoffset < obj->nchains; symoffset++) { 920 def = obj->symtab + symoffset; 921 922 /* 923 * For skip the symbol if st_shndx is either SHN_UNDEF or 924 * SHN_COMMON. 925 */ 926 if (def->st_shndx == SHN_UNDEF || def->st_shndx == SHN_COMMON) 927 continue; 928 929 /* 930 * If the symbol is greater than the specified address, or if it 931 * is further away from addr than the current nearest symbol, 932 * then reject it. 933 */ 934 symbol_addr = obj->relocbase + def->st_value; 935 if (symbol_addr > addr || symbol_addr < info->dli_saddr) 936 continue; 937 938 /* Update our idea of the nearest symbol. */ 939 info->dli_sname = obj->strtab + def->st_name; 940 info->dli_saddr = symbol_addr; 941 best_def = def; 942 943 /* Exact match? */ 944 if (info->dli_saddr == addr) 945 break; 946 } 947 948 #ifdef __HAVE_FUNCTION_DESCRIPTORS 949 if (best_def != NULL && ELF_ST_TYPE(best_def->st_info) == STT_FUNC) 950 info->dli_saddr = (void *)_rtld_function_descriptor_alloc(obj, 951 best_def, 0); 952 #endif /* __HAVE_FUNCTION_DESCRIPTORS */ 953 954 return 1; 955 } 956 957 /* 958 * Error reporting function. Use it like printf. If formats the message 959 * into a buffer, and sets things up so that the next call to dlerror() 960 * will return the message. 961 */ 962 void 963 _rtld_error(const char *fmt,...) 964 { 965 static char buf[512]; 966 va_list ap; 967 968 va_start(ap, fmt); 969 xvsnprintf(buf, sizeof buf, fmt, ap); 970 error_message = buf; 971 va_end(ap); 972 } 973 974 void 975 _rtld_debug_state(void) 976 { 977 978 /* do nothing */ 979 } 980 981 void 982 _rtld_linkmap_add(Obj_Entry *obj) 983 { 984 struct link_map *l = &obj->linkmap; 985 struct link_map *prev; 986 987 obj->linkmap.l_name = obj->path; 988 obj->linkmap.l_addr = obj->relocbase; 989 obj->linkmap.l_ld = obj->dynamic; 990 #ifdef __mips__ 991 /* XXX This field is not standard and will be removed eventually. */ 992 obj->linkmap.l_offs = obj->relocbase; 993 #endif 994 995 if (_rtld_debug.r_map == NULL) { 996 _rtld_debug.r_map = l; 997 return; 998 } 999 1000 /* 1001 * Scan to the end of the list, but not past the entry for the 1002 * dynamic linker, which we want to keep at the very end. 1003 */ 1004 for (prev = _rtld_debug.r_map; 1005 prev->l_next != NULL && prev->l_next != &_rtld_objself.linkmap; 1006 prev = prev->l_next); 1007 1008 l->l_prev = prev; 1009 l->l_next = prev->l_next; 1010 if (l->l_next != NULL) 1011 l->l_next->l_prev = l; 1012 prev->l_next = l; 1013 } 1014 1015 void 1016 _rtld_linkmap_delete(Obj_Entry *obj) 1017 { 1018 struct link_map *l = &obj->linkmap; 1019 1020 if (l->l_prev == NULL) { 1021 if ((_rtld_debug.r_map = l->l_next) != NULL) 1022 l->l_next->l_prev = NULL; 1023 return; 1024 } 1025 if ((l->l_prev->l_next = l->l_next) != NULL) 1026 l->l_next->l_prev = l->l_prev; 1027 } 1028 1029 static Obj_Entry * 1030 _rtld_obj_from_addr(const void *addr) 1031 { 1032 Obj_Entry *obj; 1033 1034 for (obj = _rtld_objlist; obj != NULL; obj = obj->next) { 1035 if (addr < (void *) obj->mapbase) 1036 continue; 1037 if (addr < (void *) (obj->mapbase + obj->mapsize)) 1038 return obj; 1039 } 1040 return NULL; 1041 } 1042 1043 static void 1044 _rtld_objlist_clear(Objlist *list) 1045 { 1046 while (!SIMPLEQ_EMPTY(list)) { 1047 Objlist_Entry* elm = SIMPLEQ_FIRST(list); 1048 SIMPLEQ_REMOVE_HEAD(list, link); 1049 xfree(elm); 1050 } 1051 } 1052 1053 static void 1054 _rtld_objlist_remove(Objlist *list, Obj_Entry *obj) 1055 { 1056 Objlist_Entry *elm; 1057 1058 if ((elm = _rtld_objlist_find(list, obj)) != NULL) { 1059 SIMPLEQ_REMOVE(list, elm, Struct_Objlist_Entry, link); 1060 xfree(elm); 1061 } 1062 } 1063