1 /* $NetBSD: rtld.c,v 1.137 2010/12/24 12:41:43 skrll 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.137 2010/12/24 12:41:43 skrll 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 u_int _rtld_objcount; /* Number of objects in _rtld_objlist */ 89 u_int _rtld_objloads; /* Number of objects loaded in _rtld_objlist */ 90 const char _rtld_path[] = _PATH_RTLD; 91 92 /* Initialize a fake symbol for resolving undefined weak references. */ 93 Elf_Sym _rtld_sym_zero = { 94 .st_info = ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE), 95 .st_shndx = SHN_ABS, 96 }; 97 size_t _rtld_pagesz; /* Page size, as provided by kernel */ 98 99 Search_Path *_rtld_default_paths; 100 Search_Path *_rtld_paths; 101 102 Library_Xform *_rtld_xforms; 103 104 /* 105 * Global declarations normally provided by crt0. 106 */ 107 char *__progname; 108 char **environ; 109 110 #if defined(RTLD_DEBUG) 111 #ifndef __sh__ 112 extern Elf_Addr _GLOBAL_OFFSET_TABLE_[]; 113 #else /* 32-bit SuperH */ 114 register Elf_Addr *_GLOBAL_OFFSET_TABLE_ asm("r12"); 115 #endif 116 #endif /* RTLD_DEBUG */ 117 extern Elf_Dyn _DYNAMIC; 118 119 static void _rtld_call_fini_functions(int); 120 static void _rtld_call_init_functions(void); 121 static void _rtld_initlist_visit(Objlist *, Obj_Entry *, int); 122 static void _rtld_initlist_tsort(Objlist *, int); 123 static Obj_Entry *_rtld_dlcheck(void *); 124 static void _rtld_init_dag(Obj_Entry *); 125 static void _rtld_init_dag1(Obj_Entry *, Obj_Entry *); 126 static void _rtld_objlist_remove(Objlist *, Obj_Entry *); 127 static void _rtld_objlist_clear(Objlist *); 128 static void _rtld_unload_object(Obj_Entry *, bool); 129 static void _rtld_unref_dag(Obj_Entry *); 130 static Obj_Entry *_rtld_obj_from_addr(const void *); 131 132 static void 133 _rtld_call_fini_functions(int force) 134 { 135 Objlist_Entry *elm; 136 Objlist finilist; 137 Obj_Entry *obj; 138 139 dbg(("_rtld_call_fini_functions(%d)", force)); 140 141 SIMPLEQ_INIT(&finilist); 142 _rtld_initlist_tsort(&finilist, 1); 143 144 /* First pass: objects _not_ marked with DF_1_INITFIRST. */ 145 SIMPLEQ_FOREACH(elm, &finilist, link) { 146 obj = elm->obj; 147 if (obj->refcount > 0 && !force) { 148 continue; 149 } 150 if (obj->fini == NULL || obj->fini_called || obj->z_initfirst) { 151 continue; 152 } 153 dbg (("calling fini function %s at %p", obj->path, 154 (void *)obj->fini)); 155 obj->fini_called = 1; 156 (*obj->fini)(); 157 } 158 159 /* Second pass: objects marked with DF_1_INITFIRST. */ 160 SIMPLEQ_FOREACH(elm, &finilist, link) { 161 obj = elm->obj; 162 if (obj->refcount > 0 && !force) { 163 continue; 164 } 165 if (obj->fini == NULL || obj->fini_called) { 166 continue; 167 } 168 dbg (("calling fini function %s at %p (DF_1_INITFIRST)", 169 obj->path, (void *)obj->fini)); 170 obj->fini_called = 1; 171 (*obj->fini)(); 172 } 173 174 _rtld_objlist_clear(&finilist); 175 } 176 177 static void 178 _rtld_call_init_functions() 179 { 180 Objlist_Entry *elm; 181 Objlist initlist; 182 Obj_Entry *obj; 183 184 dbg(("_rtld_call_init_functions()")); 185 SIMPLEQ_INIT(&initlist); 186 _rtld_initlist_tsort(&initlist, 0); 187 188 /* First pass: objects marked with DF_1_INITFIRST. */ 189 SIMPLEQ_FOREACH(elm, &initlist, link) { 190 obj = elm->obj; 191 if (obj->init == NULL || obj->init_called || !obj->z_initfirst) { 192 continue; 193 } 194 dbg (("calling init function %s at %p (DF_1_INITFIRST)", 195 obj->path, (void *)obj->init)); 196 obj->init_called = 1; 197 (*obj->init)(); 198 } 199 200 /* Second pass: all other objects. */ 201 SIMPLEQ_FOREACH(elm, &initlist, link) { 202 obj = elm->obj; 203 if (obj->init == NULL || obj->init_called) { 204 continue; 205 } 206 dbg (("calling init function %s at %p", obj->path, 207 (void *)obj->init)); 208 obj->init_called = 1; 209 (*obj->init)(); 210 } 211 212 _rtld_objlist_clear(&initlist); 213 } 214 215 /* 216 * Initialize the dynamic linker. The argument is the address at which 217 * the dynamic linker has been mapped into memory. The primary task of 218 * this function is to create an Obj_Entry for the dynamic linker and 219 * to resolve the PLT relocation for platforms that need it (those that 220 * define __HAVE_FUNCTION_DESCRIPTORS 221 */ 222 static void 223 _rtld_init(caddr_t mapbase, caddr_t relocbase, const char *execname) 224 { 225 226 /* Conjure up an Obj_Entry structure for the dynamic linker. */ 227 _rtld_objself.path = __UNCONST(_rtld_path); 228 _rtld_objself.pathlen = sizeof(_rtld_path)-1; 229 _rtld_objself.rtld = true; 230 _rtld_objself.mapbase = mapbase; 231 _rtld_objself.relocbase = relocbase; 232 _rtld_objself.dynamic = (Elf_Dyn *) &_DYNAMIC; 233 _rtld_objself.strtab = "_rtld_sym_zero"; 234 235 /* 236 * Set value to -relocbase so that 237 * 238 * _rtld_objself.relocbase + _rtld_sym_zero.st_value == 0 239 * 240 * This allows unresolved references to weak symbols to be computed 241 * to a value of 0. 242 */ 243 _rtld_sym_zero.st_value = -(uintptr_t)relocbase; 244 245 _rtld_digest_dynamic(_rtld_path, &_rtld_objself); 246 assert(!_rtld_objself.needed); 247 #if !defined(__hppa__) 248 assert(!_rtld_objself.pltrel && !_rtld_objself.pltrela); 249 #else 250 _rtld_relocate_plt_objects(&_rtld_objself); 251 #endif 252 #if !defined(__mips__) && !defined(__hppa__) 253 assert(!_rtld_objself.pltgot); 254 #endif 255 #if !defined(__arm__) && !defined(__mips__) && !defined(__sh__) 256 /* ARM, MIPS and SH{3,5} have a bogus DT_TEXTREL. */ 257 assert(!_rtld_objself.textrel); 258 #endif 259 260 _rtld_add_paths(execname, &_rtld_default_paths, 261 RTLD_DEFAULT_LIBRARY_PATH); 262 263 #ifdef RTLD_ARCH_SUBDIR 264 _rtld_add_paths(execname, &_rtld_default_paths, 265 RTLD_DEFAULT_LIBRARY_PATH "/" RTLD_ARCH_SUBDIR); 266 #endif 267 268 /* 269 * Set up the _rtld_objlist pointer, so that rtld symbols can be found. 270 */ 271 _rtld_objlist = &_rtld_objself; 272 273 /* Make the object list empty again. */ 274 _rtld_objlist = NULL; 275 _rtld_objtail = &_rtld_objlist; 276 _rtld_objcount = 0; 277 278 _rtld_debug.r_brk = _rtld_debug_state; 279 _rtld_debug.r_state = RT_CONSISTENT; 280 } 281 282 /* 283 * Cleanup procedure. It will be called (by the atexit() mechanism) just 284 * before the process exits. 285 */ 286 static void 287 _rtld_exit(void) 288 { 289 dbg(("rtld_exit()")); 290 291 _rtld_call_fini_functions(1); 292 } 293 294 /* 295 * Main entry point for dynamic linking. The argument is the stack 296 * pointer. The stack is expected to be laid out as described in the 297 * SVR4 ABI specification, Intel 386 Processor Supplement. Specifically, 298 * the stack pointer points to a word containing ARGC. Following that 299 * in the stack is a null-terminated sequence of pointers to argument 300 * strings. Then comes a null-terminated sequence of pointers to 301 * environment strings. Finally, there is a sequence of "auxiliary 302 * vector" entries. 303 * 304 * This function returns the entry point for the main program, the dynamic 305 * linker's exit procedure in sp[0], and a pointer to the main object in 306 * sp[1]. 307 */ 308 Elf_Addr 309 _rtld(Elf_Addr *sp, Elf_Addr relocbase) 310 { 311 const AuxInfo *pAUX_base, *pAUX_entry, *pAUX_execfd, *pAUX_phdr, 312 *pAUX_phent, *pAUX_phnum, *pAUX_euid, *pAUX_egid, 313 *pAUX_ruid, *pAUX_rgid; 314 const AuxInfo *pAUX_pagesz; 315 char **env, **oenvp; 316 const AuxInfo *aux; 317 const AuxInfo *auxp; 318 Elf_Addr *const osp = sp; 319 bool bind_now = 0; 320 const char *ld_bind_now, *ld_preload, *ld_library_path; 321 const char **argv; 322 const char *execname; 323 long argc; 324 const char **real___progname; 325 const Obj_Entry **real___mainprog_obj; 326 char ***real_environ; 327 #ifdef DEBUG 328 int i = 0; 329 const char *ld_debug; 330 #endif 331 332 /* 333 * On entry, the dynamic linker itself has not been relocated yet. 334 * Be very careful not to reference any global data until after 335 * _rtld_init has returned. It is OK to reference file-scope statics 336 * and string constants, and to call static and global functions. 337 */ 338 /* Find the auxiliary vector on the stack. */ 339 /* first Elf_Word reserved to address of exit routine */ 340 #if defined(RTLD_DEBUG) 341 debug = 1; 342 dbg(("sp = %p, argc = %ld, argv = %p <%s> relocbase %p", sp, 343 (long)sp[2], &sp[3], (char *) sp[3], (void *)relocbase)); 344 dbg(("got is at %p, dynamic is at %p", _GLOBAL_OFFSET_TABLE_, 345 &_DYNAMIC)); 346 dbg(("_ctype_ is %p", _ctype_)); 347 #endif 348 349 sp += 2; /* skip over return argument space */ 350 argv = (const char **) &sp[1]; 351 argc = *(long *)sp; 352 sp += 2 + argc; /* Skip over argc, arguments, and NULL 353 * terminator */ 354 env = (char **) sp; 355 while (*sp++ != 0) { /* Skip over environment, and NULL terminator */ 356 #if defined(RTLD_DEBUG) 357 dbg(("env[%d] = %p %s", i++, (void *)sp[-1], (char *)sp[-1])); 358 #endif 359 } 360 aux = (const AuxInfo *) sp; 361 362 pAUX_base = pAUX_entry = pAUX_execfd = NULL; 363 pAUX_phdr = pAUX_phent = pAUX_phnum = NULL; 364 pAUX_euid = pAUX_ruid = pAUX_egid = pAUX_rgid = NULL; 365 pAUX_pagesz = NULL; 366 367 execname = NULL; 368 369 /* Digest the auxiliary vector. */ 370 for (auxp = aux; auxp->a_type != AT_NULL; ++auxp) { 371 switch (auxp->a_type) { 372 case AT_BASE: 373 pAUX_base = auxp; 374 break; 375 case AT_ENTRY: 376 pAUX_entry = auxp; 377 break; 378 case AT_EXECFD: 379 pAUX_execfd = auxp; 380 break; 381 case AT_PHDR: 382 pAUX_phdr = auxp; 383 break; 384 case AT_PHENT: 385 pAUX_phent = auxp; 386 break; 387 case AT_PHNUM: 388 pAUX_phnum = auxp; 389 break; 390 #ifdef AT_EUID 391 case AT_EUID: 392 pAUX_euid = auxp; 393 break; 394 case AT_RUID: 395 pAUX_ruid = auxp; 396 break; 397 case AT_EGID: 398 pAUX_egid = auxp; 399 break; 400 case AT_RGID: 401 pAUX_rgid = auxp; 402 break; 403 #endif 404 #ifdef AT_SUN_EXECNAME 405 case AT_SUN_EXECNAME: 406 execname = (const char *)(const void *)auxp->a_v; 407 break; 408 #endif 409 case AT_PAGESZ: 410 pAUX_pagesz = auxp; 411 break; 412 } 413 } 414 415 /* Initialize and relocate ourselves. */ 416 if (pAUX_base == NULL) { 417 _rtld_error("Bad pAUX_base"); 418 _rtld_die(); 419 } 420 assert(pAUX_pagesz != NULL); 421 _rtld_pagesz = (int)pAUX_pagesz->a_v; 422 _rtld_init((caddr_t)pAUX_base->a_v, (caddr_t)relocbase, execname); 423 424 __progname = _rtld_objself.path; 425 environ = env; 426 427 _rtld_trust = ((pAUX_euid ? (uid_t)pAUX_euid->a_v : geteuid()) == 428 (pAUX_ruid ? (uid_t)pAUX_ruid->a_v : getuid())) && 429 ((pAUX_egid ? (gid_t)pAUX_egid->a_v : getegid()) == 430 (pAUX_rgid ? (gid_t)pAUX_rgid->a_v : getgid())); 431 432 #ifdef DEBUG 433 ld_debug = NULL; 434 #endif 435 ld_bind_now = NULL; 436 ld_library_path = NULL; 437 ld_preload = NULL; 438 /* 439 * Inline avoid using normal getenv/unsetenv here as the libc 440 * code is quite a bit more complicated. 441 */ 442 for (oenvp = env; *env != NULL; ++env) { 443 static const char bind_var[] = "LD_BIND_NOW="; 444 static const char debug_var[] = "LD_DEBUG="; 445 static const char path_var[] = "LD_LIBRARY_PATH="; 446 static const char preload_var[] = "LD_PRELOAD="; 447 #define LEN(x) (sizeof(x) - 1) 448 449 if ((*env)[0] != 'L' || (*env)[1] != 'D') { 450 /* 451 * Special case to skip most entries without 452 * the more expensive calls to strncmp. 453 */ 454 *oenvp++ = *env; 455 } else if (strncmp(*env, debug_var, LEN(debug_var)) == 0) { 456 if (_rtld_trust) { 457 #ifdef DEBUG 458 ld_debug = *env + LEN(debug_var); 459 #endif 460 *oenvp++ = *env; 461 } 462 } else if (strncmp(*env, bind_var, LEN(bind_var)) == 0) { 463 ld_bind_now = *env + LEN(bind_var); 464 } else if (strncmp(*env, path_var, LEN(path_var)) == 0) { 465 if (_rtld_trust) { 466 ld_library_path = *env + LEN(path_var); 467 *oenvp++ = *env; 468 } 469 } else if (strncmp(*env, preload_var, LEN(preload_var)) == 0) { 470 if (_rtld_trust) { 471 ld_preload = *env + LEN(preload_var); 472 *oenvp++ = *env; 473 } 474 } else { 475 *oenvp++ = *env; 476 } 477 #undef LEN 478 } 479 *oenvp++ = NULL; 480 481 if (ld_bind_now != NULL && *ld_bind_now != '\0') 482 bind_now = true; 483 if (_rtld_trust) { 484 #ifdef DEBUG 485 #ifdef RTLD_DEBUG 486 debug = 0; 487 #endif 488 if (ld_debug != NULL && *ld_debug != '\0') 489 debug = 1; 490 #endif 491 _rtld_add_paths(execname, &_rtld_paths, ld_library_path); 492 } else { 493 execname = NULL; 494 } 495 _rtld_process_hints(execname, &_rtld_paths, &_rtld_xforms, 496 _PATH_LD_HINTS); 497 dbg(("dynamic linker is initialized, mapbase=%p, relocbase=%p", 498 _rtld_objself.mapbase, _rtld_objself.relocbase)); 499 500 /* 501 * Load the main program, or process its program header if it is 502 * already loaded. 503 */ 504 if (pAUX_execfd != NULL) { /* Load the main program. */ 505 int fd = pAUX_execfd->a_v; 506 const char *obj_name = argv[0] ? argv[0] : "main program"; 507 dbg(("loading main program")); 508 _rtld_objmain = _rtld_map_object(obj_name, fd, NULL); 509 close(fd); 510 if (_rtld_objmain == NULL) 511 _rtld_die(); 512 } else { /* Main program already loaded. */ 513 const Elf_Phdr *phdr; 514 int phnum; 515 caddr_t entry; 516 517 dbg(("processing main program's program header")); 518 assert(pAUX_phdr != NULL); 519 phdr = (const Elf_Phdr *) pAUX_phdr->a_v; 520 assert(pAUX_phnum != NULL); 521 phnum = pAUX_phnum->a_v; 522 assert(pAUX_phent != NULL); 523 assert(pAUX_phent->a_v == sizeof(Elf_Phdr)); 524 assert(pAUX_entry != NULL); 525 entry = (caddr_t) pAUX_entry->a_v; 526 _rtld_objmain = _rtld_digest_phdr(phdr, phnum, entry); 527 _rtld_objmain->path = xstrdup(argv[0] ? argv[0] : 528 "main program"); 529 _rtld_objmain->pathlen = strlen(_rtld_objmain->path); 530 } 531 532 _rtld_objmain->mainprog = true; 533 534 /* 535 * Get the actual dynamic linker pathname from the executable if 536 * possible. (It should always be possible.) That ensures that 537 * gdb will find the right dynamic linker even if a non-standard 538 * one is being used. 539 */ 540 if (_rtld_objmain->interp != NULL && 541 strcmp(_rtld_objmain->interp, _rtld_objself.path) != 0) 542 _rtld_objself.path = xstrdup(_rtld_objmain->interp); 543 dbg(("actual dynamic linker is %s", _rtld_objself.path)); 544 545 _rtld_digest_dynamic(execname, _rtld_objmain); 546 547 /* Link the main program into the list of objects. */ 548 *_rtld_objtail = _rtld_objmain; 549 _rtld_objtail = &_rtld_objmain->next; 550 _rtld_objcount++; 551 _rtld_objloads++; 552 553 _rtld_linkmap_add(_rtld_objmain); 554 _rtld_linkmap_add(&_rtld_objself); 555 556 ++_rtld_objmain->refcount; 557 _rtld_objmain->mainref = 1; 558 _rtld_objlist_push_tail(&_rtld_list_main, _rtld_objmain); 559 560 if (ld_preload) { 561 /* 562 * Pre-load user-specified objects after the main program 563 * but before any shared object dependencies. 564 */ 565 dbg(("preloading objects")); 566 if (_rtld_preload(ld_preload) == -1) 567 _rtld_die(); 568 } 569 570 dbg(("loading needed objects")); 571 if (_rtld_load_needed_objects(_rtld_objmain, _RTLD_MAIN) == -1) 572 _rtld_die(); 573 574 dbg(("relocating objects")); 575 if (_rtld_relocate_objects(_rtld_objmain, bind_now) == -1) 576 _rtld_die(); 577 578 dbg(("doing copy relocations")); 579 if (_rtld_do_copy_relocations(_rtld_objmain) == -1) 580 _rtld_die(); 581 582 /* 583 * Set the __progname, environ and, __mainprog_obj before 584 * calling anything that might use them. 585 */ 586 real___progname = _rtld_objmain_sym("__progname"); 587 if (real___progname) { 588 if (argv[0] != NULL) { 589 if ((*real___progname = strrchr(argv[0], '/')) == NULL) 590 (*real___progname) = argv[0]; 591 else 592 (*real___progname)++; 593 } else { 594 (*real___progname) = NULL; 595 } 596 } 597 real_environ = _rtld_objmain_sym("environ"); 598 if (real_environ) 599 *real_environ = environ; 600 /* 601 * Set __mainprog_obj for old binaries. 602 */ 603 real___mainprog_obj = _rtld_objmain_sym("__mainprog_obj"); 604 if (real___mainprog_obj) 605 *real___mainprog_obj = _rtld_objmain; 606 607 dbg(("calling _init functions")); 608 _rtld_call_init_functions(); 609 610 dbg(("control at program entry point = %p, obj = %p, exit = %p", 611 _rtld_objmain->entry, _rtld_objmain, _rtld_exit)); 612 613 /* 614 * Return with the entry point and the exit procedure in at the top 615 * of stack. 616 */ 617 618 _rtld_debug_state(); /* say hello to gdb! */ 619 620 ((void **) osp)[0] = _rtld_exit; 621 ((void **) osp)[1] = _rtld_objmain; 622 return (Elf_Addr) _rtld_objmain->entry; 623 } 624 625 void 626 _rtld_die(void) 627 { 628 const char *msg = dlerror(); 629 630 if (msg == NULL) 631 msg = "Fatal error"; 632 xerrx(1, "%s", msg); 633 } 634 635 static Obj_Entry * 636 _rtld_dlcheck(void *handle) 637 { 638 Obj_Entry *obj; 639 640 for (obj = _rtld_objlist; obj != NULL; obj = obj->next) 641 if (obj == (Obj_Entry *) handle) 642 break; 643 644 if (obj == NULL || obj->dl_refcount == 0) { 645 xwarnx("Invalid shared object handle %p", handle); 646 return NULL; 647 } 648 return obj; 649 } 650 651 static void 652 _rtld_initlist_visit(Objlist* list, Obj_Entry *obj, int rev) 653 { 654 Needed_Entry* elm; 655 656 /* dbg(("_rtld_initlist_visit(%s)", obj->path)); */ 657 658 if (obj->init_done) 659 return; 660 obj->init_done = 1; 661 662 for (elm = obj->needed; elm != NULL; elm = elm->next) { 663 if (elm->obj != NULL) { 664 _rtld_initlist_visit(list, elm->obj, rev); 665 } 666 } 667 668 if (rev) { 669 _rtld_objlist_push_head(list, obj); 670 } else { 671 _rtld_objlist_push_tail(list, obj); 672 } 673 } 674 675 static void 676 _rtld_initlist_tsort(Objlist* list, int rev) 677 { 678 dbg(("_rtld_initlist_tsort")); 679 680 Obj_Entry* obj; 681 682 for (obj = _rtld_objlist->next; obj; obj = obj->next) { 683 obj->init_done = 0; 684 } 685 686 for (obj = _rtld_objlist->next; obj; obj = obj->next) { 687 _rtld_initlist_visit(list, obj, rev); 688 } 689 } 690 691 static void 692 _rtld_init_dag(Obj_Entry *root) 693 { 694 695 _rtld_init_dag1(root, root); 696 } 697 698 static void 699 _rtld_init_dag1(Obj_Entry *root, Obj_Entry *obj) 700 { 701 const Needed_Entry *needed; 702 703 if (!obj->mainref) { 704 if (_rtld_objlist_find(&obj->dldags, root)) 705 return; 706 dbg(("add %p (%s) to %p (%s) DAG", obj, obj->path, root, 707 root->path)); 708 _rtld_objlist_push_tail(&obj->dldags, root); 709 _rtld_objlist_push_tail(&root->dagmembers, obj); 710 } 711 for (needed = obj->needed; needed != NULL; needed = needed->next) 712 if (needed->obj != NULL) 713 _rtld_init_dag1(root, needed->obj); 714 } 715 716 /* 717 * Note, this is called only for objects loaded by dlopen(). 718 */ 719 static void 720 _rtld_unload_object(Obj_Entry *root, bool do_fini_funcs) 721 { 722 723 _rtld_unref_dag(root); 724 if (root->refcount == 0) { /* We are finished with some objects. */ 725 Obj_Entry *obj; 726 Obj_Entry **linkp; 727 Objlist_Entry *elm; 728 729 /* Finalize objects that are about to be unmapped. */ 730 if (do_fini_funcs) 731 _rtld_call_fini_functions(0); 732 733 /* Remove the DAG from all objects' DAG lists. */ 734 SIMPLEQ_FOREACH(elm, &root->dagmembers, link) 735 _rtld_objlist_remove(&elm->obj->dldags, root); 736 737 /* Remove the DAG from the RTLD_GLOBAL list. */ 738 if (root->globalref) { 739 root->globalref = 0; 740 _rtld_objlist_remove(&_rtld_list_global, root); 741 } 742 743 /* Unmap all objects that are no longer referenced. */ 744 linkp = &_rtld_objlist->next; 745 while ((obj = *linkp) != NULL) { 746 if (obj->refcount == 0) { 747 dbg(("unloading \"%s\"", obj->path)); 748 if (obj->ehdr != MAP_FAILED) 749 munmap(obj->ehdr, _rtld_pagesz); 750 munmap(obj->mapbase, obj->mapsize); 751 _rtld_objlist_remove(&_rtld_list_global, obj); 752 _rtld_linkmap_delete(obj); 753 *linkp = obj->next; 754 _rtld_objcount--; 755 _rtld_obj_free(obj); 756 } else 757 linkp = &obj->next; 758 } 759 _rtld_objtail = linkp; 760 } 761 } 762 763 void 764 _rtld_ref_dag(Obj_Entry *root) 765 { 766 const Needed_Entry *needed; 767 768 assert(root); 769 770 ++root->refcount; 771 772 dbg(("incremented reference on \"%s\" (%d)", root->path, 773 root->refcount)); 774 for (needed = root->needed; needed != NULL; 775 needed = needed->next) { 776 if (needed->obj != NULL) 777 _rtld_ref_dag(needed->obj); 778 } 779 } 780 781 static void 782 _rtld_unref_dag(Obj_Entry *root) 783 { 784 785 assert(root); 786 assert(root->refcount != 0); 787 788 --root->refcount; 789 dbg(("decremented reference on \"%s\" (%d)", root->path, 790 root->refcount)); 791 792 if (root->refcount == 0) { 793 const Needed_Entry *needed; 794 795 for (needed = root->needed; needed != NULL; 796 needed = needed->next) { 797 if (needed->obj != NULL) 798 _rtld_unref_dag(needed->obj); 799 } 800 } 801 } 802 803 __strong_alias(__dlclose,dlclose) 804 int 805 dlclose(void *handle) 806 { 807 Obj_Entry *root = _rtld_dlcheck(handle); 808 809 if (root == NULL) 810 return -1; 811 812 _rtld_debug.r_state = RT_DELETE; 813 _rtld_debug_state(); 814 815 --root->dl_refcount; 816 _rtld_unload_object(root, true); 817 818 _rtld_debug.r_state = RT_CONSISTENT; 819 _rtld_debug_state(); 820 821 return 0; 822 } 823 824 __strong_alias(__dlerror,dlerror) 825 char * 826 dlerror(void) 827 { 828 char *msg = error_message; 829 830 error_message = NULL; 831 return msg; 832 } 833 834 __strong_alias(__dlopen,dlopen) 835 void * 836 dlopen(const char *name, int mode) 837 { 838 Obj_Entry **old_obj_tail = _rtld_objtail; 839 Obj_Entry *obj = NULL; 840 int flags = _RTLD_DLOPEN; 841 bool nodelete; 842 bool now; 843 844 flags |= (mode & RTLD_GLOBAL) ? _RTLD_GLOBAL : 0; 845 flags |= (mode & RTLD_NOLOAD) ? _RTLD_NOLOAD : 0; 846 847 nodelete = (mode & RTLD_NODELETE) ? true : false; 848 now = ((mode & RTLD_MODEMASK) == RTLD_NOW) ? true : false; 849 850 _rtld_debug.r_state = RT_ADD; 851 _rtld_debug_state(); 852 853 if (name == NULL) { 854 obj = _rtld_objmain; 855 obj->refcount++; 856 } else 857 obj = _rtld_load_library(name, _rtld_objmain, flags); 858 859 860 if (obj != NULL) { 861 ++obj->dl_refcount; 862 if (*old_obj_tail != NULL) { /* We loaded something new. */ 863 assert(*old_obj_tail == obj); 864 865 if (_rtld_load_needed_objects(obj, flags) == -1 || 866 (_rtld_init_dag(obj), 867 _rtld_relocate_objects(obj, 868 (now || obj->z_now))) == -1) { 869 _rtld_unload_object(obj, false); 870 obj->dl_refcount--; 871 obj = NULL; 872 } else { 873 _rtld_call_init_functions(); 874 } 875 } 876 if (obj != NULL) { 877 if ((nodelete || obj->z_nodelete) && !obj->ref_nodel) { 878 dbg(("dlopen obj %s nodelete", obj->path)); 879 _rtld_ref_dag(obj); 880 obj->z_nodelete = obj->ref_nodel = true; 881 } 882 } 883 } 884 _rtld_debug.r_state = RT_CONSISTENT; 885 _rtld_debug_state(); 886 887 return obj; 888 } 889 890 /* 891 * Find a symbol in the main program. 892 */ 893 void * 894 _rtld_objmain_sym(const char *name) 895 { 896 unsigned long hash; 897 const Elf_Sym *def; 898 const Obj_Entry *obj; 899 DoneList donelist; 900 901 hash = _rtld_elf_hash(name); 902 obj = _rtld_objmain; 903 _rtld_donelist_init(&donelist); 904 905 def = _rtld_symlook_list(name, hash, &_rtld_list_main, &obj, false, 906 &donelist); 907 908 if (def != NULL) 909 return obj->relocbase + def->st_value; 910 return NULL; 911 } 912 913 #ifdef __powerpc__ 914 static void * 915 hackish_return_address(void) 916 { 917 return __builtin_return_address(1); 918 } 919 #endif 920 921 __strong_alias(__dlsym,dlsym) 922 void * 923 dlsym(void *handle, const char *name) 924 { 925 const Obj_Entry *obj; 926 unsigned long hash; 927 const Elf_Sym *def; 928 const Obj_Entry *defobj; 929 void *retaddr; 930 DoneList donelist; 931 932 hash = _rtld_elf_hash(name); 933 def = NULL; 934 defobj = NULL; 935 936 switch ((intptr_t)handle) { 937 case (intptr_t)NULL: 938 case (intptr_t)RTLD_NEXT: 939 case (intptr_t)RTLD_DEFAULT: 940 case (intptr_t)RTLD_SELF: 941 #ifdef __powerpc__ 942 retaddr = hackish_return_address(); 943 #else 944 retaddr = __builtin_return_address(0); 945 #endif 946 if ((obj = _rtld_obj_from_addr(retaddr)) == NULL) { 947 _rtld_error("Cannot determine caller's shared object"); 948 return NULL; 949 } 950 951 switch ((intptr_t)handle) { 952 case (intptr_t)NULL: /* Just the caller's shared object. */ 953 def = _rtld_symlook_obj(name, hash, obj, false); 954 defobj = obj; 955 break; 956 957 case (intptr_t)RTLD_NEXT: /* Objects after callers */ 958 obj = obj->next; 959 /*FALLTHROUGH*/ 960 961 case (intptr_t)RTLD_SELF: /* Caller included */ 962 for (; obj; obj = obj->next) { 963 if ((def = _rtld_symlook_obj(name, hash, obj, 964 false)) != NULL) { 965 defobj = obj; 966 break; 967 } 968 } 969 break; 970 971 case (intptr_t)RTLD_DEFAULT: 972 def = _rtld_symlook_default(name, hash, obj, &defobj, 973 false); 974 break; 975 976 default: 977 abort(); 978 } 979 break; 980 981 default: 982 if ((obj = _rtld_dlcheck(handle)) == NULL) 983 return NULL; 984 985 _rtld_donelist_init(&donelist); 986 987 if (obj->mainprog) { 988 /* Search main program and all libraries loaded by it */ 989 def = _rtld_symlook_list(name, hash, &_rtld_list_main, 990 &defobj, false, &donelist); 991 } else { 992 Needed_Entry fake; 993 DoneList depth; 994 995 /* Search the object and all the libraries loaded by it. */ 996 fake.next = NULL; 997 fake.obj = __UNCONST(obj); 998 fake.name = 0; 999 1000 _rtld_donelist_init(&depth); 1001 def = _rtld_symlook_needed(name, hash, &fake, &defobj, 1002 false, &donelist, &depth); 1003 } 1004 1005 break; 1006 } 1007 1008 if (def != NULL) { 1009 #ifdef __HAVE_FUNCTION_DESCRIPTORS 1010 if (ELF_ST_TYPE(def->st_info) == STT_FUNC) 1011 return (void *)_rtld_function_descriptor_alloc(defobj, 1012 def, 0); 1013 #endif /* __HAVE_FUNCTION_DESCRIPTORS */ 1014 return defobj->relocbase + def->st_value; 1015 } 1016 1017 _rtld_error("Undefined symbol \"%s\"", name); 1018 return NULL; 1019 } 1020 1021 __strong_alias(__dladdr,dladdr) 1022 int 1023 dladdr(const void *addr, Dl_info *info) 1024 { 1025 const Obj_Entry *obj; 1026 const Elf_Sym *def, *best_def; 1027 void *symbol_addr; 1028 unsigned long symoffset; 1029 1030 #ifdef __HAVE_FUNCTION_DESCRIPTORS 1031 addr = _rtld_function_descriptor_function(addr); 1032 #endif /* __HAVE_FUNCTION_DESCRIPTORS */ 1033 1034 obj = _rtld_obj_from_addr(addr); 1035 if (obj == NULL) { 1036 _rtld_error("No shared object contains address"); 1037 return 0; 1038 } 1039 info->dli_fname = obj->path; 1040 info->dli_fbase = obj->mapbase; 1041 info->dli_saddr = (void *)0; 1042 info->dli_sname = NULL; 1043 1044 /* 1045 * Walk the symbol list looking for the symbol whose address is 1046 * closest to the address sent in. 1047 */ 1048 best_def = NULL; 1049 for (symoffset = 0; symoffset < obj->nchains; symoffset++) { 1050 def = obj->symtab + symoffset; 1051 1052 /* 1053 * For skip the symbol if st_shndx is either SHN_UNDEF or 1054 * SHN_COMMON. 1055 */ 1056 if (def->st_shndx == SHN_UNDEF || def->st_shndx == SHN_COMMON) 1057 continue; 1058 1059 /* 1060 * If the symbol is greater than the specified address, or if it 1061 * is further away from addr than the current nearest symbol, 1062 * then reject it. 1063 */ 1064 symbol_addr = obj->relocbase + def->st_value; 1065 if (symbol_addr > addr || symbol_addr < info->dli_saddr) 1066 continue; 1067 1068 /* Update our idea of the nearest symbol. */ 1069 info->dli_sname = obj->strtab + def->st_name; 1070 info->dli_saddr = symbol_addr; 1071 best_def = def; 1072 1073 /* Exact match? */ 1074 if (info->dli_saddr == addr) 1075 break; 1076 } 1077 1078 #ifdef __HAVE_FUNCTION_DESCRIPTORS 1079 if (best_def != NULL && ELF_ST_TYPE(best_def->st_info) == STT_FUNC) 1080 info->dli_saddr = (void *)_rtld_function_descriptor_alloc(obj, 1081 best_def, 0); 1082 #endif /* __HAVE_FUNCTION_DESCRIPTORS */ 1083 1084 return 1; 1085 } 1086 1087 __strong_alias(__dlinfo,dlinfo) 1088 int 1089 dlinfo(void *handle, int req, void *v) 1090 { 1091 const Obj_Entry *obj; 1092 void *retaddr; 1093 1094 if (handle == RTLD_SELF) { 1095 #ifdef __powerpc__ 1096 retaddr = hackish_return_address(); 1097 #else 1098 retaddr = __builtin_return_address(0); 1099 #endif 1100 if ((obj = _rtld_obj_from_addr(retaddr)) == NULL) { 1101 _rtld_error("Cannot determine caller's shared object"); 1102 return -1; 1103 } 1104 } else { 1105 if ((obj = _rtld_dlcheck(handle)) == NULL) { 1106 _rtld_error("Invalid handle"); 1107 return -1; 1108 } 1109 } 1110 1111 switch (req) { 1112 case RTLD_DI_LINKMAP: 1113 { 1114 const struct link_map **map = v; 1115 1116 *map = &obj->linkmap; 1117 break; 1118 } 1119 1120 default: 1121 _rtld_error("Invalid request"); 1122 return -1; 1123 } 1124 1125 return 0; 1126 } 1127 1128 __strong_alias(__dl_iterate_phdr,dl_iterate_phdr); 1129 int 1130 dl_iterate_phdr(int (*callback)(struct dl_phdr_info *, size_t, void *), void *param) 1131 { 1132 struct dl_phdr_info phdr_info; 1133 const Obj_Entry *obj; 1134 int error = 0; 1135 1136 for (obj = _rtld_objlist; obj != NULL; obj = obj->next) { 1137 phdr_info.dlpi_addr = (Elf_Addr)obj->relocbase; 1138 phdr_info.dlpi_name = STAILQ_FIRST(&obj->names) ? 1139 STAILQ_FIRST(&obj->names)->name : obj->path; 1140 phdr_info.dlpi_phdr = obj->phdr; 1141 phdr_info.dlpi_phnum = obj->phsize / sizeof(obj->phdr[0]); 1142 #if 1 1143 phdr_info.dlpi_tls_modid = 0; 1144 phdr_info.dlpi_tls_data = 0; 1145 #else 1146 phdr_info.dlpi_tls_modid = obj->tlsindex; 1147 phdr_info.dlpi_tls_data = obj->tlsinit; 1148 #endif 1149 phdr_info.dlpi_adds = _rtld_objloads; 1150 phdr_info.dlpi_subs = _rtld_objloads - _rtld_objcount; 1151 1152 error = callback(&phdr_info, sizeof(phdr_info), param); 1153 if (error) 1154 break; 1155 } 1156 1157 return error; 1158 } 1159 1160 /* 1161 * Error reporting function. Use it like printf. If formats the message 1162 * into a buffer, and sets things up so that the next call to dlerror() 1163 * will return the message. 1164 */ 1165 void 1166 _rtld_error(const char *fmt,...) 1167 { 1168 static char buf[512]; 1169 va_list ap; 1170 1171 va_start(ap, fmt); 1172 xvsnprintf(buf, sizeof buf, fmt, ap); 1173 error_message = buf; 1174 va_end(ap); 1175 } 1176 1177 void 1178 _rtld_debug_state(void) 1179 { 1180 1181 /* do nothing */ 1182 } 1183 1184 void 1185 _rtld_linkmap_add(Obj_Entry *obj) 1186 { 1187 struct link_map *l = &obj->linkmap; 1188 struct link_map *prev; 1189 1190 obj->linkmap.l_name = obj->path; 1191 obj->linkmap.l_addr = obj->relocbase; 1192 obj->linkmap.l_ld = obj->dynamic; 1193 #ifdef __mips__ 1194 /* XXX This field is not standard and will be removed eventually. */ 1195 obj->linkmap.l_offs = obj->relocbase; 1196 #endif 1197 1198 if (_rtld_debug.r_map == NULL) { 1199 _rtld_debug.r_map = l; 1200 return; 1201 } 1202 1203 /* 1204 * Scan to the end of the list, but not past the entry for the 1205 * dynamic linker, which we want to keep at the very end. 1206 */ 1207 for (prev = _rtld_debug.r_map; 1208 prev->l_next != NULL && prev->l_next != &_rtld_objself.linkmap; 1209 prev = prev->l_next); 1210 1211 l->l_prev = prev; 1212 l->l_next = prev->l_next; 1213 if (l->l_next != NULL) 1214 l->l_next->l_prev = l; 1215 prev->l_next = l; 1216 } 1217 1218 void 1219 _rtld_linkmap_delete(Obj_Entry *obj) 1220 { 1221 struct link_map *l = &obj->linkmap; 1222 1223 if (l->l_prev == NULL) { 1224 if ((_rtld_debug.r_map = l->l_next) != NULL) 1225 l->l_next->l_prev = NULL; 1226 return; 1227 } 1228 if ((l->l_prev->l_next = l->l_next) != NULL) 1229 l->l_next->l_prev = l->l_prev; 1230 } 1231 1232 static Obj_Entry * 1233 _rtld_obj_from_addr(const void *addr) 1234 { 1235 Obj_Entry *obj; 1236 1237 for (obj = _rtld_objlist; obj != NULL; obj = obj->next) { 1238 if (addr < (void *) obj->mapbase) 1239 continue; 1240 if (addr < (void *) (obj->mapbase + obj->mapsize)) 1241 return obj; 1242 } 1243 return NULL; 1244 } 1245 1246 static void 1247 _rtld_objlist_clear(Objlist *list) 1248 { 1249 while (!SIMPLEQ_EMPTY(list)) { 1250 Objlist_Entry* elm = SIMPLEQ_FIRST(list); 1251 SIMPLEQ_REMOVE_HEAD(list, link); 1252 xfree(elm); 1253 } 1254 } 1255 1256 static void 1257 _rtld_objlist_remove(Objlist *list, Obj_Entry *obj) 1258 { 1259 Objlist_Entry *elm; 1260 1261 if ((elm = _rtld_objlist_find(list, obj)) != NULL) { 1262 SIMPLEQ_REMOVE(list, elm, Struct_Objlist_Entry, link); 1263 xfree(elm); 1264 } 1265 } 1266