1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 1988 AT&T 24 * All Rights Reserved 25 * 26 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 27 * Use is subject to license terms. 28 */ 29 #pragma ident "%Z%%M% %I% %E% SMI" 30 31 /* 32 * Utility routines for run-time linker. some are duplicated here from libc 33 * (with different names) to avoid name space collisions. 34 */ 35 #include "_synonyms.h" 36 #include <stdio.h> 37 #include <sys/types.h> 38 #include <sys/mman.h> 39 #include <sys/lwp.h> 40 #include <sys/debug.h> 41 #include <stdarg.h> 42 #include <fcntl.h> 43 #include <string.h> 44 #include <ctype.h> 45 #include <dlfcn.h> 46 #include <unistd.h> 47 #include <stdlib.h> 48 #include <sys/auxv.h> 49 #include <debug.h> 50 #include <conv.h> 51 #include "_rtld.h" 52 #include "_audit.h" 53 #include "_elf.h" 54 #include "msg.h" 55 56 static int ld_flags_env(const char *, Word *, Word *, uint_t, int); 57 58 /* 59 * All error messages go through eprintf(). During process initialization these 60 * messages should be directed to the standard error, however once control has 61 * been passed to the applications code these messages should be stored in an 62 * internal buffer for use with dlerror(). Note, fatal error conditions that 63 * may occur while running the application will still cause a standard error 64 * message, see rtldexit() in this file for details. 65 * The `application' flag serves to indicate the transition between process 66 * initialization and when the applications code is running. 67 */ 68 69 /* 70 * Null function used as place where a debugger can set a breakpoint. 71 */ 72 void 73 rtld_db_dlactivity(Lm_list *lml) 74 { 75 DBG_CALL(Dbg_util_dbnotify(lml, r_debug.rtd_rdebug.r_rdevent, 76 r_debug.rtd_rdebug.r_state)); 77 } 78 79 /* 80 * Null function used as place where debugger can set a pre .init 81 * processing breakpoint. 82 */ 83 void 84 rtld_db_preinit(Lm_list *lml) 85 { 86 DBG_CALL(Dbg_util_dbnotify(lml, r_debug.rtd_rdebug.r_rdevent, 87 r_debug.rtd_rdebug.r_state)); 88 } 89 90 /* 91 * Null function used as place where debugger can set a post .init 92 * processing breakpoint. 93 */ 94 void 95 rtld_db_postinit(Lm_list *lml) 96 { 97 DBG_CALL(Dbg_util_dbnotify(lml, r_debug.rtd_rdebug.r_rdevent, 98 r_debug.rtd_rdebug.r_state)); 99 } 100 101 /* 102 * Debugger Event Notification 103 * 104 * This function centralizes all debugger event notification (ala rtld_db). 105 * 106 * There's a simple intent, focused on insuring the primary link-map control 107 * list (or each link-map list) is consistent, and the indication that objects 108 * have been added or deleted from this list. Although an RD_ADD and RD_DELETE 109 * event are posted for each of these, most debuggers don't care, as their 110 * view is that these events simply convey an "inconsistent" state. 111 * 112 * We also don't want to trigger multiple RD_ADD/RD_DELETE events any time we 113 * enter ld.so.1. 114 * 115 * With auditors, we may be in the process of relocating a collection of 116 * objects, and will leave() ld.so.1 to call the auditor. At this point we 117 * must indicate an RD_CONSISTENT event, but librtld_db will not report an 118 * object to the debuggers until relocation processing has been completed on it. 119 * To allow for the collection of these objects that are pending relocation, an 120 * RD_ADD event is set after completing a series of relocations on the primary 121 * link-map control list. 122 * 123 * Set an RD_ADD/RD_DELETE event and indicate that an RD_CONSISTENT event is 124 * required later (LML_FLG_DBNOTIF): 125 * 126 * i the first time we add or delete an object to the primary link-map 127 * control list. 128 * ii the first time we move a secondary link-map control list to the primary 129 * link-map control list (effectively, this is like adding a group of 130 * objects to the primary link-map control list). 131 * iii the first time we relocate a series of objects on the primary link-map 132 * control list. 133 * 134 * Set an RD_CONSISTENT event when it is required (LML_FLG_DBNOTIF is set) and 135 * 136 * i each time we leave the runtime linker. 137 */ 138 void 139 rd_event(Lm_list *lml, rd_event_e event, r_state_e state) 140 { 141 void (*fptr)(Lm_list *); 142 143 switch (event) { 144 case RD_PREINIT: 145 fptr = rtld_db_preinit; 146 break; 147 case RD_POSTINIT: 148 fptr = rtld_db_postinit; 149 break; 150 case RD_DLACTIVITY: 151 switch (state) { 152 case RT_CONSISTENT: 153 lml->lm_flags &= ~LML_FLG_DBNOTIF; 154 155 /* 156 * Do we need to send a notification? 157 */ 158 if ((rtld_flags & RT_FL_DBNOTIF) == 0) 159 return; 160 rtld_flags &= ~RT_FL_DBNOTIF; 161 break; 162 case RT_ADD: 163 case RT_DELETE: 164 lml->lm_flags |= LML_FLG_DBNOTIF; 165 166 /* 167 * If we are already in an inconsistent state, no 168 * notification is required. 169 */ 170 if (rtld_flags & RT_FL_DBNOTIF) 171 return; 172 rtld_flags |= RT_FL_DBNOTIF; 173 break; 174 }; 175 fptr = rtld_db_dlactivity; 176 break; 177 default: 178 /* 179 * RD_NONE - do nothing 180 */ 181 break; 182 }; 183 184 /* 185 * Set event state and call 'notification' function. 186 * 187 * The debugging clients have previously been told about these 188 * notification functions and have set breakpoints on them if they 189 * are interested in the notification. 190 */ 191 r_debug.rtd_rdebug.r_state = state; 192 r_debug.rtd_rdebug.r_rdevent = event; 193 fptr(lml); 194 r_debug.rtd_rdebug.r_rdevent = RD_NONE; 195 } 196 197 #if defined(sparc) || defined(i386) || defined(__amd64) 198 /* 199 * Stack Cleanup. 200 * 201 * This function is invoked to 'remove' arguments that were passed in on the 202 * stack. This is most likely if ld.so.1 was invoked directly. In that case 203 * we want to remove ld.so.1 as well as it's arguments from the argv[] array. 204 * Which means we then need to slide everything above it on the stack down 205 * accordingly. 206 * 207 * While the stack layout is platform specific - it just so happens that x86, 208 * sparc, sparcv9, and amd64 all share the following initial stack layout. 209 * 210 * !_______________________! high addresses 211 * ! ! 212 * ! Information ! 213 * ! Block ! 214 * ! (size varies) ! 215 * !_______________________! 216 * ! 0 word ! 217 * !_______________________! 218 * ! Auxiliary ! 219 * ! vector ! 220 * ! 2 word entries ! 221 * ! ! 222 * !_______________________! 223 * ! 0 word ! 224 * !_______________________! 225 * ! Environment ! 226 * ! pointers ! 227 * ! ... ! 228 * ! (one word each) ! 229 * !_______________________! 230 * ! 0 word ! 231 * !_______________________! 232 * ! Argument ! low addresses 233 * ! pointers ! 234 * ! Argc words ! 235 * !_______________________! 236 * ! ! 237 * ! Argc ! 238 * !_______________________! 239 * ! ... ! 240 * 241 */ 242 static void 243 stack_cleanup(char **argv, char ***envp, auxv_t **auxv, int rmcnt) 244 { 245 int ndx; 246 long *argc; 247 char **oargv, **nargv; 248 char **oenvp, **nenvp; 249 auxv_t *oauxv, *nauxv; 250 251 /* 252 * Slide ARGV[] and update argc. The argv pointer remains the same, 253 * however slide the applications arguments over the arguments to 254 * ld.so.1. 255 */ 256 nargv = &argv[0]; 257 oargv = &argv[rmcnt]; 258 259 for (ndx = 0; oargv[ndx]; ndx++) 260 nargv[ndx] = oargv[ndx]; 261 nargv[ndx] = oargv[ndx]; 262 263 argc = (long *)((uintptr_t)argv - sizeof (long *)); 264 *argc -= rmcnt; 265 266 /* 267 * Slide ENVP[], and update the environment array pointer. 268 */ 269 ndx++; 270 nenvp = &nargv[ndx]; 271 oenvp = &oargv[ndx]; 272 *envp = nenvp; 273 274 for (ndx = 0; oenvp[ndx]; ndx++) 275 nenvp[ndx] = oenvp[ndx]; 276 nenvp[ndx] = oenvp[ndx]; 277 278 /* 279 * Slide AUXV[], and update the aux vector pointer. 280 */ 281 ndx++; 282 nauxv = (auxv_t *)&nenvp[ndx]; 283 oauxv = (auxv_t *)&oenvp[ndx]; 284 *auxv = nauxv; 285 286 for (ndx = 0; (oauxv[ndx].a_type != AT_NULL); ndx++) 287 nauxv[ndx] = oauxv[ndx]; 288 nauxv[ndx] = oauxv[ndx]; 289 } 290 #else 291 /* 292 * Verify that the above routine is appropriate for any new platforms. 293 */ 294 #error unsupported architecture! 295 #endif 296 297 /* 298 * The only command line argument recognized is -e, followed by a runtime 299 * linker environment variable. 300 */ 301 int 302 rtld_getopt(char **argv, char ***envp, auxv_t **auxv, Word *lmflags, 303 Word *lmtflags, int aout) 304 { 305 int ndx; 306 307 for (ndx = 1; argv[ndx]; ndx++) { 308 char *str; 309 310 if (argv[ndx][0] != '-') 311 break; 312 313 if (argv[ndx][1] == '\0') { 314 ndx++; 315 break; 316 } 317 318 if (argv[ndx][1] != 'e') 319 return (1); 320 321 if (argv[ndx][2] == '\0') { 322 ndx++; 323 if (argv[ndx] == NULL) 324 return (1); 325 str = argv[ndx]; 326 } else 327 str = &argv[ndx][2]; 328 329 /* 330 * If the environment variable starts with LD_, strip the LD_. 331 * Otherwise, take things as is. 332 */ 333 if ((str[0] == 'L') && (str[1] == 'D') && (str[2] == '_') && 334 (str[3] != '\0')) 335 str += 3; 336 if (ld_flags_env(str, lmflags, lmtflags, 0, aout) == 1) 337 return (1); 338 } 339 340 /* 341 * Make sure an object file has been specified. 342 */ 343 if (argv[ndx] == 0) 344 return (1); 345 346 /* 347 * Having gotten the arguments, clean ourselves off of the stack. 348 */ 349 stack_cleanup(argv, envp, auxv, ndx); 350 return (0); 351 } 352 353 /* 354 * Compare function for FullpathNode AVL tree. 355 */ 356 static int 357 fpavl_compare(const void * n1, const void * n2) 358 { 359 uint_t hash1, hash2; 360 const char *st1, *st2; 361 int rc; 362 363 hash1 = ((FullpathNode *)n1)->fpn_hash; 364 hash2 = ((FullpathNode *)n2)->fpn_hash; 365 366 if (hash1 > hash2) 367 return (1); 368 if (hash1 < hash2) 369 return (-1); 370 371 st1 = ((FullpathNode *)n1)->fpn_name; 372 st2 = ((FullpathNode *)n2)->fpn_name; 373 374 rc = strcmp(st1, st2); 375 if (rc > 0) 376 return (1); 377 if (rc < 0) 378 return (-1); 379 return (0); 380 } 381 382 383 /* 384 * Determine if a given pathname has already been loaded in the AVL tree. 385 * If the pathname does not exist in the AVL tree, the next insertion point 386 * is deposited in "where". This value can be used by fpavl_insert() to 387 * expedite the insertion. 388 */ 389 Rt_map * 390 fpavl_loaded(Lm_list *lml, const char *name, avl_index_t *where) 391 { 392 FullpathNode fpn, *fpnp; 393 avl_tree_t *avlt; 394 395 /* 396 * Create the avl tree if required. 397 */ 398 if ((avlt = lml->lm_fpavl) == NULL) { 399 if ((avlt = calloc(sizeof (avl_tree_t), 1)) == 0) 400 return (0); 401 avl_create(avlt, fpavl_compare, sizeof (FullpathNode), 402 SGSOFFSETOF(FullpathNode, fpn_avl)); 403 lml->lm_fpavl = avlt; 404 } 405 406 fpn.fpn_name = name; 407 fpn.fpn_hash = sgs_str_hash(name); 408 409 if ((fpnp = avl_find(lml->lm_fpavl, &fpn, where)) == NULL) 410 return (NULL); 411 412 return (fpnp->fpn_lmp); 413 } 414 415 416 /* 417 * Insert a name into the FullpathNode AVL tree for the link-map list. The 418 * objects NAME() is the path that would have originally been searched for, and 419 * is therefore the name to associate with any "where" value. If the object has 420 * a different PATHNAME(), perhaps because it has resolved to a different file 421 * (see fullpath), then this name is recorded also. See load_file(). 422 */ 423 int 424 fpavl_insert(Lm_list *lml, Rt_map *lmp, const char *name, avl_index_t where) 425 { 426 FullpathNode *fpnp; 427 428 if (where == 0) { 429 /* LINTED */ 430 Rt_map *_lmp = fpavl_loaded(lml, name, &where); 431 432 /* 433 * We better not get a hit now, we do not want duplicates in 434 * the tree. 435 */ 436 ASSERT(_lmp == 0); 437 } 438 439 /* 440 * Insert new node in tree 441 */ 442 if ((fpnp = calloc(sizeof (FullpathNode), 1)) == 0) 443 return (0); 444 445 fpnp->fpn_name = name; 446 fpnp->fpn_hash = sgs_str_hash(name); 447 fpnp->fpn_lmp = lmp; 448 449 if (alist_append(&FPNODE(lmp), &fpnp, sizeof (FullpathNode *), 450 AL_CNT_FPNODE) == 0) { 451 free(fpnp); 452 return (0); 453 } 454 455 ASSERT(lml->lm_fpavl != NULL); 456 avl_insert(lml->lm_fpavl, fpnp, where); 457 return (1); 458 } 459 460 /* 461 * Remove an object from the Fullpath AVL tree. Note, this is called *before* 462 * the objects link-map is torn down (remove_so), which is where any NAME() and 463 * PATHNAME() strings will be deallocated. 464 */ 465 void 466 fpavl_remove(Rt_map *lmp) 467 { 468 FullpathNode **fpnpp; 469 Aliste off; 470 471 for (ALIST_TRAVERSE(FPNODE(lmp), off, fpnpp)) { 472 FullpathNode *fpnp = *fpnpp; 473 474 avl_remove(LIST(lmp)->lm_fpavl, fpnp); 475 free(fpnp); 476 } 477 free(FPNODE(lmp)); 478 FPNODE(lmp) = 0; 479 } 480 481 482 /* 483 * Prior to calling an object, either via a .plt or through dlsym(), make sure 484 * its .init has fired. Through topological sorting, ld.so.1 attempts to fire 485 * init's in the correct order, however, this order is typically based on needed 486 * dependencies and non-lazy relocation bindings. Lazy relocations (.plts) can 487 * still occur and result in bindings that were not captured during topological 488 * sorting. This routine compensates for this lack of binding information, and 489 * provides for dynamic .init firing. 490 */ 491 void 492 is_dep_init(Rt_map * dlmp, Rt_map * clmp) 493 { 494 Rt_map ** tobj; 495 496 /* 497 * If the caller is an auditor, and the destination isn't, then don't 498 * run any .inits (see comments in load_completion()). 499 */ 500 if ((LIST(clmp)->lm_flags & LML_FLG_NOAUDIT) && 501 (LIST(clmp) != LIST(dlmp))) 502 return; 503 504 if ((dlmp == clmp) || (rtld_flags & (RT_FL_BREADTH | RT_FL_INITFIRST))) 505 return; 506 507 if ((FLAGS(dlmp) & (FLG_RT_RELOCED | FLG_RT_INITDONE)) == 508 (FLG_RT_RELOCED | FLG_RT_INITDONE)) 509 return; 510 511 if ((FLAGS(dlmp) & (FLG_RT_RELOCED | FLG_RT_INITCALL)) == 512 (FLG_RT_RELOCED | FLG_RT_INITCALL)) { 513 DBG_CALL(Dbg_util_no_init(dlmp)); 514 return; 515 } 516 517 if ((tobj = calloc(2, sizeof (Rt_map *))) != NULL) { 518 tobj[0] = dlmp; 519 call_init(tobj, DBG_INIT_DYN); 520 } 521 } 522 523 /* 524 * In a threaded environment insure the thread responsible for loading an object 525 * has completed .init processing for that object before any new thread is 526 * allowed to access the object. This check is only valid with libthread 527 * TI_VERSION 2, where ld.so.1 implements locking through low level mutexes. 528 * 529 * When a new link-map is created, the thread that causes it to be loaded is 530 * identified by THREADID(dlmp). Compare this with the current thread to 531 * determine if it must be blocked. 532 * 533 * NOTE, there are a number of instances (typically only for .plt processing) 534 * where we must skip this test: 535 * 536 * . any thread id of 0 - threads that call thr_exit() may be in this state 537 * thus we can't deduce what tid they used to be. Also some of the 538 * lib/libthread worker threads have this id and must bind (to themselves 539 * or libc) for libthread to function. 540 * 541 * . libthread itself binds to libc, and as libthread is INITFIRST 542 * libc's .init can't have fired yet. Luckly libc's .init is not required 543 * by libthreads binding. 544 * 545 * . if the caller is an auditor, and the destination isn't, then don't 546 * block (see comments in load_completion()). 547 */ 548 void 549 is_dep_ready(Rt_map * dlmp, Rt_map * clmp, int what) 550 { 551 thread_t tid; 552 553 if ((LIST(clmp)->lm_flags & LML_FLG_NOAUDIT) && 554 (LIST(clmp) != LIST(dlmp))) 555 return; 556 557 if ((rtld_flags & RT_FL_CONCUR) && 558 ((FLAGS(dlmp) & FLG_RT_INITDONE) == 0) && 559 ((FLAGS(clmp) & FLG_RT_INITFRST) == 0) && 560 ((tid = rt_thr_self()) != 0) && (THREADID(dlmp) != tid)) { 561 while ((FLAGS(dlmp) & FLG_RT_INITDONE) == 0) { 562 FLAGS1(dlmp) |= FL1_RT_INITWAIT; 563 DBG_CALL(Dbg_util_wait(clmp, dlmp, what)); 564 (void) rt_cond_wait(CONDVAR(dlmp), &rtldlock); 565 } 566 } 567 } 568 569 /* 570 * Execute .{preinit|init|fini}array sections 571 */ 572 void 573 call_array(Addr *array, uint_t arraysz, Rt_map *lmp, Word shtype) 574 { 575 int start, stop, incr, ndx; 576 uint_t arraycnt = (uint_t)(arraysz / sizeof (Addr)); 577 578 if (array == NULL) 579 return; 580 581 /* 582 * initarray & preinitarray are walked from beginning to end - while 583 * finiarray is walked from end to beginning. 584 */ 585 if (shtype == SHT_FINI_ARRAY) { 586 start = arraycnt - 1; 587 stop = incr = -1; 588 } else { 589 start = 0; 590 stop = arraycnt; 591 incr = 1; 592 } 593 594 /* 595 * Call the .*array[] entries 596 */ 597 for (ndx = start; ndx != stop; ndx += incr) { 598 void (*fptr)(void) = (void(*)())array[ndx]; 599 600 DBG_CALL(Dbg_util_call_array(lmp, (void *)fptr, ndx, shtype)); 601 602 leave(LIST(lmp)); 603 (*fptr)(); 604 (void) enter(); 605 } 606 } 607 608 609 /* 610 * Execute any .init sections. These are passed to us in an lmp array which 611 * (by default) will have been sorted. 612 */ 613 void 614 call_init(Rt_map ** tobj, int flag) 615 { 616 Rt_map ** _tobj, ** _nobj; 617 static List pending = { NULL, NULL }; 618 619 /* 620 * If we're in the middle of an INITFIRST, this must complete before 621 * any new init's are fired. In this case add the object list to the 622 * pending queue and return. We'll pick up the queue after any 623 * INITFIRST objects have their init's fired. 624 */ 625 if (rtld_flags & RT_FL_INITFIRST) { 626 (void) list_append(&pending, tobj); 627 return; 628 } 629 630 /* 631 * Traverse the tobj array firing each objects init. 632 */ 633 for (_tobj = _nobj = tobj, _nobj++; *_tobj != NULL; _tobj++, _nobj++) { 634 Rt_map * lmp = *_tobj; 635 void (* iptr)() = INIT(lmp); 636 637 if (FLAGS(lmp) & FLG_RT_INITCALL) 638 continue; 639 640 FLAGS(lmp) |= FLG_RT_INITCALL; 641 642 /* 643 * Establish an initfirst state if necessary - no other inits 644 * will be fired (because of additional relocation bindings) 645 * when in this state. 646 */ 647 if (FLAGS(lmp) & FLG_RT_INITFRST) 648 rtld_flags |= RT_FL_INITFIRST; 649 650 if (INITARRAY(lmp) || iptr) { 651 Aliste off; 652 Bnd_desc ** bdpp; 653 654 /* 655 * Make sure that all dependencies that have been 656 * relocated to are initialized before this objects 657 * .init is executed. This insures that a dependency 658 * on an external item that must first be initialized 659 * by its associated object is satisfied. 660 */ 661 for (ALIST_TRAVERSE(DEPENDS(lmp), off, bdpp)) { 662 Bnd_desc * bdp = *bdpp; 663 664 if ((bdp->b_flags & BND_REFER) == 0) 665 continue; 666 is_dep_ready(bdp->b_depend, lmp, DBG_WAIT_INIT); 667 } 668 DBG_CALL(Dbg_util_call_init(lmp, flag)); 669 } 670 671 if (iptr) { 672 leave(LIST(lmp)); 673 (*iptr)(); 674 (void) enter(); 675 } 676 677 call_array(INITARRAY(lmp), INITARRAYSZ(lmp), lmp, 678 SHT_INIT_ARRAY); 679 680 if (INITARRAY(lmp) || iptr) 681 DBG_CALL(Dbg_util_call_init(lmp, DBG_INIT_DONE)); 682 683 /* 684 * Set the initdone flag regardless of whether this object 685 * actually contains an .init section. This flag prevents us 686 * from processing this section again for an .init and also 687 * signifies that a .fini must be called should it exist. 688 * Clear the sort field for use in later .fini processing. 689 */ 690 FLAGS(lmp) |= FLG_RT_INITDONE; 691 SORTVAL(lmp) = -1; 692 693 /* 694 * Wake anyone up who might be waiting on this .init. 695 */ 696 if (FLAGS1(lmp) & FL1_RT_INITWAIT) { 697 DBG_CALL(Dbg_util_broadcast(lmp)); 698 (void) rt_cond_broadcast(CONDVAR(lmp)); 699 FLAGS1(lmp) &= ~FL1_RT_INITWAIT; 700 } 701 702 /* 703 * If we're firing an INITFIRST object, and other objects must 704 * be fired which are not INITFIRST, make sure we grab any 705 * pending objects that might have been delayed as this 706 * INITFIRST was processed. 707 */ 708 if ((rtld_flags & RT_FL_INITFIRST) && 709 ((*_nobj == NULL) || !(FLAGS(*_nobj) & FLG_RT_INITFRST))) { 710 Listnode * lnp; 711 Rt_map ** pobj; 712 713 rtld_flags &= ~RT_FL_INITFIRST; 714 715 while ((lnp = pending.head) != NULL) { 716 if ((pending.head = lnp->next) == NULL) 717 pending.tail = NULL; 718 pobj = lnp->data; 719 free(lnp); 720 721 call_init(pobj, DBG_INIT_PEND); 722 } 723 } 724 } 725 free(tobj); 726 } 727 728 /* 729 * Function called by atexit(3C). Calls all .fini sections related with the 730 * mains dependent shared libraries in the order in which the shared libraries 731 * have been loaded. Skip any .fini defined in the main executable, as this 732 * will be called by crt0 (main was never marked as initdone). 733 */ 734 void 735 call_fini(Lm_list * lml, Rt_map ** tobj) 736 { 737 Rt_map **_tobj; 738 739 for (_tobj = tobj; *_tobj != NULL; _tobj++) { 740 Rt_map * clmp, * lmp = *_tobj; 741 Aliste off; 742 Bnd_desc ** bdpp; 743 744 /* 745 * If concurrency checking isn't enabled only fire .fini if 746 * .init has completed. We collect all .fini sections of 747 * objects that had their .init collected, but that doesn't 748 * mean at the time that the .init had completed. 749 */ 750 if ((rtld_flags & RT_FL_CONCUR) || 751 (FLAGS(lmp) & FLG_RT_INITDONE)) { 752 void (*fptr)(void) = FINI(lmp); 753 754 if (FINIARRAY(lmp) || fptr) { 755 /* 756 * If concurrency checking is enabled make sure 757 * this object's .init is completed before 758 * calling any .fini. 759 */ 760 is_dep_ready(lmp, lmp, DBG_WAIT_FINI); 761 DBG_CALL(Dbg_util_call_fini(lmp)); 762 } 763 764 call_array(FINIARRAY(lmp), FINIARRAYSZ(lmp), lmp, 765 SHT_FINI_ARRAY); 766 767 if (fptr) { 768 leave(LIST(lmp)); 769 (*fptr)(); 770 (void) enter(); 771 } 772 } 773 774 /* 775 * Skip main, this is explicitly called last in atexit_fini(). 776 */ 777 if (FLAGS(lmp) & FLG_RT_ISMAIN) 778 continue; 779 780 /* 781 * Audit `close' operations at this point. The library has 782 * exercised its last instructions (regardless of whether it 783 * will be unmapped or not). 784 * 785 * First call any global auditing. 786 */ 787 if (lml->lm_tflags & LML_TFLG_AUD_OBJCLOSE) 788 _audit_objclose(&(auditors->ad_list), lmp); 789 790 /* 791 * Finally determine whether this object has local auditing 792 * requirements by inspecting itself and then its dependencies. 793 */ 794 if ((lml->lm_flags & LML_FLG_LOCAUDIT) == 0) 795 continue; 796 797 if (FLAGS1(lmp) & LML_TFLG_AUD_OBJCLOSE) 798 _audit_objclose(&(AUDITORS(lmp)->ad_list), lmp); 799 800 for (ALIST_TRAVERSE(CALLERS(lmp), off, bdpp)) { 801 Bnd_desc * bdp = *bdpp; 802 803 clmp = bdp->b_caller; 804 805 if (FLAGS1(clmp) & LML_TFLG_AUD_OBJCLOSE) { 806 _audit_objclose(&(AUDITORS(clmp)->ad_list), lmp); 807 break; 808 } 809 } 810 } 811 DBG_CALL(Dbg_bind_plt_summary(lml, M_MACH, pltcnt21d, pltcnt24d, 812 pltcntu32, pltcntu44, pltcntfull, pltcntfar)); 813 814 free(tobj); 815 } 816 817 void 818 atexit_fini() 819 { 820 Rt_map ** tobj, * lmp; 821 Lm_list * lml; 822 Listnode * lnp; 823 824 (void) enter(); 825 826 rtld_flags |= RT_FL_ATEXIT; 827 828 lml = &lml_main; 829 lml->lm_flags |= LML_FLG_ATEXIT; 830 lmp = (Rt_map *)lml->lm_head; 831 832 /* 833 * Display any objects that haven't been referenced so far. 834 */ 835 unused(lml); 836 837 /* 838 * Reverse topologically sort the main link-map for .fini execution. 839 */ 840 if (((tobj = tsort(lmp, lml->lm_obj, RT_SORT_FWD)) != 0) && 841 (tobj != (Rt_map **)S_ERROR)) 842 call_fini(lml, tobj); 843 844 /* 845 * Add an explicit close to main and ld.so.1. Although main's .fini is 846 * collected in call_fini() to provide for FINITARRAY processing, its 847 * audit_objclose is explicitly skipped. This provides for it to be 848 * called last, here. This is the reverse of the explicit calls to 849 * audit_objopen() made in setup(). 850 */ 851 if ((lml->lm_tflags | FLAGS1(lmp)) & LML_TFLG_AUD_MASK) { 852 audit_objclose(lmp, (Rt_map *)lml_rtld.lm_head); 853 audit_objclose(lmp, lmp); 854 } 855 856 /* 857 * Now that all .fini code has been run, see what unreferenced objects 858 * remain. Any difference between this and the above unused() would 859 * indicate an object is only being used for .fini processing, which 860 * might be fine, but might also indicate an overhead whose removal 861 * would be worth considering. 862 */ 863 unused(lml); 864 865 /* 866 * Traverse any alternative link-map lists. 867 */ 868 for (LIST_TRAVERSE(&dynlm_list, lnp, lml)) { 869 /* 870 * Ignore the base-link-map list, which has already been 871 * processed, and the runtime linkers link-map list, which is 872 * typically processed last. 873 */ 874 if (lml->lm_flags & (LML_FLG_BASELM | LML_FLG_RTLDLM)) 875 continue; 876 877 if ((lmp = (Rt_map *)lml->lm_head) == 0) 878 continue; 879 880 lml->lm_flags |= LML_FLG_ATEXIT; 881 882 /* 883 * Reverse topologically sort the link-map for .fini execution. 884 */ 885 if (((tobj = tsort(lmp, lml->lm_obj, RT_SORT_FWD)) != 0) && 886 (tobj != (Rt_map **)S_ERROR)) 887 call_fini(lml, tobj); 888 889 unused(lml); 890 } 891 892 /* 893 * Finally reverse topologically sort the runtime linkers link-map for 894 * .fini execution. 895 */ 896 lml = &lml_rtld; 897 lml->lm_flags |= LML_FLG_ATEXIT; 898 lmp = (Rt_map *)lml->lm_head; 899 900 if (((tobj = tsort(lmp, lml->lm_obj, RT_SORT_FWD)) != 0) && 901 (tobj != (Rt_map **)S_ERROR)) 902 call_fini(lml, tobj); 903 904 leave(&lml_main); 905 } 906 907 908 /* 909 * This routine is called to complete any runtime linker activity which may have 910 * resulted in objects being loaded. This is called from all user entry points 911 * and from any internal dl*() requests. 912 */ 913 void 914 load_completion(Rt_map *nlmp, Rt_map *clmp) 915 { 916 Rt_map **tobj = 0; 917 Lm_list *nlml, *clml; 918 919 /* 920 * Establish any .init processing. Note, in a world of lazy loading, 921 * objects may have been loaded regardless of whether the users request 922 * was fulfilled (i.e., a dlsym() request may have failed to find a 923 * symbol but objects might have been loaded during its search). Thus, 924 * any tsorting starts from the nlmp (new link-maps) pointer and not 925 * necessarily from the link-map that may have satisfied the request. 926 * 927 * Note, the primary link-map has an initialization phase where dynamic 928 * .init firing is suppressed. This provides for a simple and clean 929 * handshake with the primary link-maps libc, which is important for 930 * establishing uberdata. In addition, auditors often obtain handles 931 * to primary link-map objects as the objects are loaded, so as to 932 * inspect the link-map for symbols. This inspection is allowed without 933 * running any code on the primary link-map, as running this code may 934 * reenter the auditor, who may not yet have finished its own 935 * initialization. 936 */ 937 if (nlmp) 938 nlml = LIST(nlmp); 939 if (clmp) 940 clml = LIST(clmp); 941 942 if (nlmp && nlml->lm_init && 943 ((nlml != &lml_main) || (rtld_flags2 & RT_FL2_PLMSETUP))) { 944 if ((tobj = tsort(nlmp, LIST(nlmp)->lm_init, 945 RT_SORT_REV)) == (Rt_map **)S_ERROR) 946 tobj = 0; 947 } 948 949 /* 950 * Make sure any alternative link-map retrieves any external interfaces 951 * and initializes threads. 952 */ 953 if (nlmp && (nlml != &lml_main)) { 954 (void) rt_get_extern(nlml, nlmp); 955 rt_thr_init(nlml); 956 } 957 958 /* 959 * Traverse the list of new link-maps and register any dynamic TLS. 960 * This storage is established for any objects not on the primary 961 * link-map, and for any objects added to the primary link-map after 962 * static TLS has been registered. 963 */ 964 if (nlmp && nlml->lm_tls && 965 ((nlml != &lml_main) || (rtld_flags2 & RT_FL2_PLMSETUP))) { 966 Rt_map *lmp; 967 968 for (lmp = nlmp; lmp; lmp = (Rt_map *)NEXT(lmp)) { 969 if (PTTLS(lmp) && PTTLS(lmp)->p_memsz) 970 tls_modaddrem(lmp, TM_FLG_MODADD); 971 } 972 nlml->lm_tls = 0; 973 } 974 975 /* 976 * Indicate the link-map list is consistent. 977 */ 978 if (clmp && ((clml->lm_tflags | FLAGS1(clmp)) & LML_TFLG_AUD_ACTIVITY)) 979 audit_activity(clmp, LA_ACT_CONSISTENT); 980 981 /* 982 * Fire any .init's. 983 */ 984 if (tobj) 985 call_init(tobj, DBG_INIT_SORT); 986 } 987 988 /* 989 * Append an item to the specified list, and return a pointer to the list 990 * node created. 991 */ 992 Listnode * 993 list_append(List *lst, const void *item) 994 { 995 Listnode * _lnp; 996 997 if ((_lnp = malloc(sizeof (Listnode))) == 0) 998 return (0); 999 1000 _lnp->data = (void *)item; 1001 _lnp->next = NULL; 1002 1003 if (lst->head == NULL) 1004 lst->tail = lst->head = _lnp; 1005 else { 1006 lst->tail->next = _lnp; 1007 lst->tail = lst->tail->next; 1008 } 1009 return (_lnp); 1010 } 1011 1012 1013 /* 1014 * Add an item after specified listnode, and return a pointer to the list 1015 * node created. 1016 */ 1017 Listnode * 1018 list_insert(List *lst, const void *item, Listnode *lnp) 1019 { 1020 Listnode * _lnp; 1021 1022 if ((_lnp = malloc(sizeof (Listnode))) == (Listnode *)0) 1023 return (0); 1024 1025 _lnp->data = (void *)item; 1026 _lnp->next = lnp->next; 1027 if (_lnp->next == NULL) 1028 lst->tail = _lnp; 1029 lnp->next = _lnp; 1030 return (_lnp); 1031 } 1032 1033 /* 1034 * Prepend an item to the specified list, and return a pointer to the 1035 * list node created. 1036 */ 1037 Listnode * 1038 list_prepend(List * lst, const void * item) 1039 { 1040 Listnode * _lnp; 1041 1042 if ((_lnp = malloc(sizeof (Listnode))) == (Listnode *)0) 1043 return (0); 1044 1045 _lnp->data = (void *)item; 1046 1047 if (lst->head == NULL) { 1048 _lnp->next = NULL; 1049 lst->tail = lst->head = _lnp; 1050 } else { 1051 _lnp->next = lst->head; 1052 lst->head = _lnp; 1053 } 1054 return (_lnp); 1055 } 1056 1057 1058 /* 1059 * Delete a 'listnode' from a list. 1060 */ 1061 void 1062 list_delete(List * lst, void * item) 1063 { 1064 Listnode * clnp, * plnp; 1065 1066 for (plnp = NULL, clnp = lst->head; clnp; clnp = clnp->next) { 1067 if (item == clnp->data) 1068 break; 1069 plnp = clnp; 1070 } 1071 1072 if (clnp == 0) 1073 return; 1074 1075 if (lst->head == clnp) 1076 lst->head = clnp->next; 1077 if (lst->tail == clnp) 1078 lst->tail = plnp; 1079 1080 if (plnp) 1081 plnp->next = clnp->next; 1082 1083 free(clnp); 1084 } 1085 1086 /* 1087 * Append an item to the specified link map control list. 1088 */ 1089 void 1090 lm_append(Lm_list *lml, Aliste lmco, Rt_map *lmp) 1091 { 1092 Lm_cntl *lmc; 1093 int add = 1; 1094 1095 /* 1096 * Indicate that this link-map list has a new object. 1097 */ 1098 (lml->lm_obj)++; 1099 1100 /* 1101 * Alert the debuggers that we are about to mess with the main link-map 1102 * control list. 1103 */ 1104 if ((lmco == ALO_DATA) && ((lml->lm_flags & LML_FLG_DBNOTIF) == 0)) 1105 rd_event(lml, RD_DLACTIVITY, RT_DELETE); 1106 1107 /* LINTED */ 1108 lmc = (Lm_cntl *)((char *)lml->lm_lists + lmco); 1109 1110 /* 1111 * A link-map list header points to one of more link-map control lists 1112 * (see include/rtld.h). The initial list, pointed to by lm_cntl, is 1113 * the list of relocated objects. Other lists maintain objects that 1114 * are still being analyzed or relocated. This list provides the core 1115 * link-map list information used by all ld.so.1 routines. 1116 */ 1117 if (lmc->lc_head == NULL) { 1118 /* 1119 * If this is the first link-map for the given control list, 1120 * initialize the list. 1121 */ 1122 lmc->lc_head = lmc->lc_tail = lmp; 1123 add = 0; 1124 1125 } else if (FLAGS(lmp) & FLG_RT_INTRPOSE) { 1126 Rt_map *tlmp; 1127 1128 /* 1129 * If this is an interposer then append the link-map following 1130 * any other interposers (these are objects that have been 1131 * previously preloaded, or were identified with -z interpose). 1132 * Interposers can only be inserted on the first link-map 1133 * control list, as once relocation has started, interposition 1134 * from new interposers can't be guaranteed. 1135 * 1136 * NOTE: We do not interpose on the head of a list. This model 1137 * evolved because dynamic executables have already been fully 1138 * relocated within themselves and thus can't be interposed on. 1139 * Nowadays it's possible to have shared objects at the head of 1140 * a list, which conceptually means they could be interposed on. 1141 * But, shared objects can be created via dldump() and may only 1142 * be partially relocated (just relatives), in which case they 1143 * are interposable, but are marked as fixed (ET_EXEC). 1144 * 1145 * Thus we really don't have a clear method of deciding when the 1146 * head of a link-map is interposable. So, to be consistent, 1147 * for now only add interposers after the link-map lists head 1148 * object. 1149 */ 1150 for (tlmp = (Rt_map *)NEXT(lmc->lc_head); tlmp; 1151 tlmp = (Rt_map *)NEXT(tlmp)) { 1152 1153 if (FLAGS(tlmp) & FLG_RT_INTRPOSE) 1154 continue; 1155 1156 /* 1157 * Insert the new link-map before this non-interposer, 1158 * and indicate an interposer is found. 1159 */ 1160 NEXT((Rt_map *)PREV(tlmp)) = (Link_map *)lmp; 1161 PREV(lmp) = PREV(tlmp); 1162 1163 NEXT(lmp) = (Link_map *)tlmp; 1164 PREV(tlmp) = (Link_map *)lmp; 1165 1166 lmc->lc_flags |= LMC_FLG_REANALYZE; 1167 add = 0; 1168 break; 1169 } 1170 } 1171 1172 /* 1173 * Fall through to appending the new link map to the tail of the list. 1174 * If we're processing the initial objects of this link-map list, add 1175 * them to the backward compatibility list. 1176 */ 1177 if (add) { 1178 NEXT(lmc->lc_tail) = (Link_map *)lmp; 1179 PREV(lmp) = (Link_map *)lmc->lc_tail; 1180 lmc->lc_tail = lmp; 1181 } 1182 1183 /* 1184 * Having added this link-map to a control list, indicate which control 1185 * list the link-map belongs to. Note, control list information is 1186 * always maintained as an offset, as the Alist can be reallocated. 1187 */ 1188 CNTL(lmp) = lmco; 1189 1190 /* 1191 * Indicate if an interposer is found. Note that the first object on a 1192 * link-map can be explicitly defined as an interposer so that it can 1193 * provide interposition over direct binding requests. 1194 */ 1195 if (FLAGS(lmp) & FLG_RT_INTRPOSE) 1196 lml->lm_flags |= LML_FLG_INTRPOSE; 1197 1198 /* 1199 * For backward compatibility with debuggers, the link-map list contains 1200 * pointers to the main control list. 1201 */ 1202 if (lmco == ALO_DATA) { 1203 lml->lm_head = lmc->lc_head; 1204 lml->lm_tail = lmc->lc_tail; 1205 } 1206 } 1207 1208 /* 1209 * Delete an item from the specified link map control list. 1210 */ 1211 void 1212 lm_delete(Lm_list *lml, Rt_map *lmp) 1213 { 1214 Lm_cntl *lmc; 1215 1216 /* 1217 * If the control list pointer hasn't been initialized, this object 1218 * never got added to a link-map list. 1219 */ 1220 if (CNTL(lmp) == 0) 1221 return; 1222 1223 /* 1224 * Alert the debuggers that we are about to mess with the main link-map 1225 * control list. 1226 */ 1227 if ((CNTL(lmp) == ALO_DATA) && ((lml->lm_flags & LML_FLG_DBNOTIF) == 0)) 1228 rd_event(lml, RD_DLACTIVITY, RT_DELETE); 1229 1230 /* LINTED */ 1231 lmc = (Lm_cntl *)((char *)lml->lm_lists + CNTL(lmp)); 1232 1233 if (lmc->lc_head == lmp) 1234 lmc->lc_head = (Rt_map *)NEXT(lmp); 1235 else 1236 NEXT((Rt_map *)PREV(lmp)) = (void *)NEXT(lmp); 1237 1238 if (lmc->lc_tail == lmp) 1239 lmc->lc_tail = (Rt_map *)PREV(lmp); 1240 else 1241 PREV((Rt_map *)NEXT(lmp)) = PREV(lmp); 1242 1243 /* 1244 * For backward compatibility with debuggers, the link-map list contains 1245 * pointers to the main control list. 1246 */ 1247 if (lmc == (Lm_cntl *)&(lml->lm_lists->al_data)) { 1248 lml->lm_head = lmc->lc_head; 1249 lml->lm_tail = lmc->lc_tail; 1250 } 1251 1252 /* 1253 * Indicate we have one less object on this control list. 1254 */ 1255 (lml->lm_obj)--; 1256 } 1257 1258 /* 1259 * Move a link-map control list to another. Objects that are being relocated 1260 * are maintained on secondary control lists. Once their relocation is 1261 * complete, the entire list is appended to the previous control list, as this 1262 * list must have been the trigger for generating the new control list. 1263 */ 1264 void 1265 lm_move(Lm_list *lml, Aliste nlmco, Aliste plmco, Lm_cntl *nlmc, Lm_cntl *plmc) 1266 { 1267 Rt_map *lmp; 1268 1269 DBG_CALL(Dbg_file_cntl(lml, nlmco, plmco)); 1270 1271 /* 1272 * Alert the debuggers that we are about to mess with the main link-map 1273 * control list. 1274 */ 1275 if ((plmco == ALO_DATA) && ((lml->lm_flags & LML_FLG_DBNOTIF) == 0)) 1276 rd_event(lml, RD_DLACTIVITY, RT_ADD); 1277 1278 /* 1279 * Indicate each new link-map has been moved to the previous link-map 1280 * control list. 1281 */ 1282 for (lmp = nlmc->lc_head; lmp; lmp = (Rt_map *)NEXT(lmp)) 1283 CNTL(lmp) = plmco; 1284 1285 /* 1286 * Move the new link-map control list, to the callers link-map control 1287 * list. 1288 */ 1289 if (plmc->lc_head == 0) { 1290 plmc->lc_head = nlmc->lc_head; 1291 PREV(nlmc->lc_head) = 0; 1292 } else { 1293 NEXT(plmc->lc_tail) = (Link_map *)nlmc->lc_head; 1294 PREV(nlmc->lc_head) = (Link_map *)plmc->lc_tail; 1295 } 1296 1297 plmc->lc_tail = nlmc->lc_tail; 1298 nlmc->lc_head = nlmc->lc_tail = 0; 1299 1300 /* 1301 * For backward compatibility with debuggers, the link-map list contains 1302 * pointers to the main control list. 1303 */ 1304 if (plmco == ALO_DATA) { 1305 lml->lm_head = plmc->lc_head; 1306 lml->lm_tail = plmc->lc_tail; 1307 } 1308 } 1309 1310 /* 1311 * Dlopening a family of objects occurs on a new link-map control list. If the 1312 * dlopen fails, then its handle is used to tear down the family (dlclose). 1313 * However, the relocation of this family may have triggered other objects to 1314 * be loaded, and after their relocation they will have been moved to the 1315 * dlopen families control list. After a dlopen() failure, see if there are 1316 * any objects that can be savaged before tearing down this control list. 1317 */ 1318 int 1319 lm_salvage(Lm_list *lml, int test, Aliste nlmco) 1320 { 1321 Lm_cntl *nlmc; 1322 1323 /* 1324 * If a dlopen occurred on a new link-map list, then its dlclose may 1325 * have completely torn down the link-map list. Check that the link-map 1326 * list still exists before proceeding. 1327 */ 1328 if (test) { 1329 Listnode *lnp; 1330 Lm_list *tlml; 1331 int found = 0; 1332 1333 for (LIST_TRAVERSE(&dynlm_list, lnp, tlml)) { 1334 if (tlml == lml) { 1335 found++; 1336 break; 1337 } 1338 } 1339 if (found == 0) 1340 return (0); 1341 } 1342 1343 /* LINTED */ 1344 nlmc = (Lm_cntl *)((char *)lml->lm_lists + nlmco); 1345 1346 /* 1347 * If this link-map control list still contains objects, determine the 1348 * previous control list and move the objects. 1349 */ 1350 if (nlmc->lc_head) { 1351 Lm_cntl *plmc; 1352 Aliste plmco; 1353 1354 plmco = nlmco - lml->lm_lists->al_size; 1355 /* LINTED */ 1356 plmc = (Lm_cntl *)((char *)lml->lm_lists + plmco); 1357 1358 lm_move(lml, nlmco, plmco, nlmc, plmc); 1359 } 1360 return (1); 1361 } 1362 1363 /* 1364 * Environment variables can have a variety of defined permutations, and thus 1365 * the following infrastructure exists to allow this variety and to select the 1366 * required definition. 1367 * 1368 * Environment variables can be defined as 32- or 64-bit specific, and if so 1369 * they will take precedence over any instruction set neutral form. Typically 1370 * this is only useful when the environment value is an informational string. 1371 * 1372 * Environment variables may be obtained from the standard user environment or 1373 * from a configuration file. The latter provides a fallback if no user 1374 * environment setting is found, and can take two forms: 1375 * 1376 * . a replaceable definition - this will be used if no user environment 1377 * setting has been seen, or 1378 * 1379 * . an permanent definition - this will be used no matter what user 1380 * environment setting is seen. In the case of list variables it will be 1381 * appended to any process environment setting seen. 1382 * 1383 * Environment variables can be defined without a value (ie. LD_XXXX=) so as to 1384 * override any replaceable environment variables from a configuration file. 1385 */ 1386 static u_longlong_t rplgen; /* replaceable generic */ 1387 /* variables */ 1388 static u_longlong_t rplisa; /* replaceable ISA specific */ 1389 /* variables */ 1390 static u_longlong_t prmgen; /* permanent generic */ 1391 /* variables */ 1392 static u_longlong_t prmisa; /* permanent ISA specific */ 1393 /* variables */ 1394 1395 /* 1396 * Classify an environment variables type. 1397 */ 1398 #define ENV_TYP_IGNORE 0x1 /* ignore - variable is for */ 1399 /* the wrong ISA */ 1400 #define ENV_TYP_ISA 0x2 /* variable is ISA specific */ 1401 #define ENV_TYP_CONFIG 0x4 /* variable obtained from a */ 1402 /* config file */ 1403 #define ENV_TYP_PERMANT 0x8 /* variable is permanent */ 1404 1405 /* 1406 * Identify all environment variables. 1407 */ 1408 #define ENV_FLG_AUDIT 0x0000000001ULL 1409 #define ENV_FLG_AUDIT_ARGS 0x0000000002ULL 1410 #define ENV_FLG_BIND_NOW 0x0000000004ULL 1411 #define ENV_FLG_BIND_NOT 0x0000000008ULL 1412 #define ENV_FLG_BINDINGS 0x0000000010ULL 1413 #define ENV_FLG_CONCURRENCY 0x0000000020ULL 1414 #define ENV_FLG_CONFGEN 0x0000000040ULL 1415 #define ENV_FLG_CONFIG 0x0000000080ULL 1416 #define ENV_FLG_DEBUG 0x0000000100ULL 1417 #define ENV_FLG_DEBUG_OUTPUT 0x0000000200ULL 1418 #define ENV_FLG_DEMANGLE 0x0000000400ULL 1419 #define ENV_FLG_FLAGS 0x0000000800ULL 1420 #define ENV_FLG_INIT 0x0000001000ULL 1421 #define ENV_FLG_LIBPATH 0x0000002000ULL 1422 #define ENV_FLG_LOADAVAIL 0x0000004000ULL 1423 #define ENV_FLG_LOADFLTR 0x0000008000ULL 1424 #define ENV_FLG_NOAUDIT 0x0000010000ULL 1425 #define ENV_FLG_NOAUXFLTR 0x0000020000ULL 1426 #define ENV_FLG_NOBAPLT 0x0000040000ULL 1427 #define ENV_FLG_NOCONFIG 0x0000080000ULL 1428 #define ENV_FLG_NODIRCONFIG 0x0000100000ULL 1429 #define ENV_FLG_NODIRECT 0x0000200000ULL 1430 #define ENV_FLG_NOENVCONFIG 0x0000400000ULL 1431 #define ENV_FLG_NOLAZY 0x0000800000ULL 1432 #define ENV_FLG_NOOBJALTER 0x0001000000ULL 1433 #define ENV_FLG_NOVERSION 0x0002000000ULL 1434 #define ENV_FLG_PRELOAD 0x0004000000ULL 1435 #define ENV_FLG_PROFILE 0x0008000000ULL 1436 #define ENV_FLG_PROFILE_OUTPUT 0x0010000000ULL 1437 #define ENV_FLG_SIGNAL 0x0020000000ULL 1438 #define ENV_FLG_TRACE_OBJS 0x0040000000ULL 1439 #define ENV_FLG_TRACE_PTHS 0x0080000000ULL 1440 #define ENV_FLG_UNREF 0x0100000000ULL 1441 #define ENV_FLG_UNUSED 0x0200000000ULL 1442 #define ENV_FLG_VERBOSE 0x0400000000ULL 1443 #define ENV_FLG_WARN 0x0800000000ULL 1444 #define ENV_FLG_NOFLTCONFIG 0x1000000000ULL 1445 #define ENV_FLG_BIND_LAZY 0x2000000000ULL 1446 1447 #ifdef SIEBEL_DISABLE 1448 #define ENV_FLG_FIX_1 0x8000000000ULL 1449 #endif 1450 1451 #define SEL_REPLACE 0x0001 1452 #define SEL_PERMANT 0x0002 1453 #define SEL_ACT_RT 0x0100 /* setting rtld_flags */ 1454 #define SEL_ACT_RT2 0x0200 /* setting rtld_flags2 */ 1455 #define SEL_ACT_STR 0x0400 /* setting string value */ 1456 #define SEL_ACT_LML 0x0800 /* setting lml_flags */ 1457 #define SEL_ACT_LMLT 0x1000 /* setting lml_tflags */ 1458 #define SEL_ACT_SPEC_1 0x2000 /* For FLG_{FLAGS, LIBPATH} */ 1459 #define SEL_ACT_SPEC_2 0x4000 /* need special handling */ 1460 1461 /* 1462 * Pattern match an LD_XXXX environment variable. s1 points to the XXXX part 1463 * and len specifies its length (comparing a strings length before the string 1464 * itself speed things up). s2 points to the token itself which has already 1465 * had any leading white-space removed. 1466 */ 1467 static void 1468 ld_generic_env(const char *s1, size_t len, const char *s2, Word *lmflags, 1469 Word *lmtflags, uint_t env_flags, int aout) 1470 { 1471 u_longlong_t variable = 0; 1472 ushort_t select = 0; 1473 const char **str; 1474 Word val = 0; 1475 1476 /* 1477 * Determine whether we're dealing with a replaceable or permanent 1478 * string. 1479 */ 1480 if (env_flags & ENV_TYP_PERMANT) { 1481 /* 1482 * If the string is from a configuration file and defined as 1483 * permanent, assign it as permanent. 1484 */ 1485 select |= SEL_PERMANT; 1486 } else 1487 select |= SEL_REPLACE; 1488 1489 /* 1490 * Parse the variable given. 1491 * 1492 * The LD_AUDIT family. 1493 */ 1494 if (*s1 == 'A') { 1495 if ((len == MSG_LD_AUDIT_SIZE) && (strncmp(s1, 1496 MSG_ORIG(MSG_LD_AUDIT), MSG_LD_AUDIT_SIZE) == 0)) { 1497 /* 1498 * Replaceable and permanent audit objects can exist. 1499 */ 1500 select |= SEL_ACT_STR; 1501 if (select & SEL_REPLACE) 1502 str = &rpl_audit; 1503 else { 1504 str = &prm_audit; 1505 rpl_audit = 0; 1506 } 1507 variable = ENV_FLG_AUDIT; 1508 } else if ((len == MSG_LD_AUDIT_ARGS_SIZE) && 1509 (strncmp(s1, MSG_ORIG(MSG_LD_AUDIT_ARGS), 1510 MSG_LD_AUDIT_ARGS_SIZE) == 0)) { 1511 /* 1512 * A specialized variable for plt_exit() use, not 1513 * documented for general use. 1514 */ 1515 select |= SEL_ACT_SPEC_2; 1516 variable = ENV_FLG_AUDIT_ARGS; 1517 } 1518 } 1519 /* 1520 * The LD_BIND family and LD_BREADTH (historic). 1521 */ 1522 else if (*s1 == 'B') { 1523 if ((len == MSG_LD_BIND_LAZY_SIZE) && (strncmp(s1, 1524 MSG_ORIG(MSG_LD_BIND_LAZY), 1525 MSG_LD_BIND_LAZY_SIZE) == 0)) { 1526 select |= SEL_ACT_RT2; 1527 val = RT_FL2_BINDLAZY; 1528 variable = ENV_FLG_BIND_LAZY; 1529 } else if ((len == MSG_LD_BIND_NOW_SIZE) && (strncmp(s1, 1530 MSG_ORIG(MSG_LD_BIND_NOW), MSG_LD_BIND_NOW_SIZE) == 0)) { 1531 select |= SEL_ACT_RT2; 1532 val = RT_FL2_BINDNOW; 1533 variable = ENV_FLG_BIND_NOW; 1534 } else if ((len == MSG_LD_BIND_NOT_SIZE) && (strncmp(s1, 1535 MSG_ORIG(MSG_LD_BIND_NOT), MSG_LD_BIND_NOT_SIZE) == 0)) { 1536 /* 1537 * Another trick, enabled to help debug AOUT 1538 * applications under BCP, but not documented for 1539 * general use. 1540 */ 1541 select |= SEL_ACT_RT; 1542 val = RT_FL_NOBIND; 1543 variable = ENV_FLG_BIND_NOT; 1544 } else if ((len == MSG_LD_BINDINGS_SIZE) && (strncmp(s1, 1545 MSG_ORIG(MSG_LD_BINDINGS), MSG_LD_BINDINGS_SIZE) == 0)) { 1546 /* 1547 * This variable is simply for backward compatibility. 1548 * If this and LD_DEBUG are both specified, only one of 1549 * the strings is going to get processed. 1550 */ 1551 select |= SEL_ACT_SPEC_2; 1552 variable = ENV_FLG_BINDINGS; 1553 #ifndef LD_BREADTH_DISABLED 1554 } else if ((len == MSG_LD_BREADTH_SIZE) && (strncmp(s1, 1555 MSG_ORIG(MSG_LD_BREADTH), MSG_LD_BREADTH_SIZE) == 0)) { 1556 /* 1557 * Besides some old patches this is no longer available. 1558 */ 1559 rtld_flags |= RT_FL_BREADTH; 1560 return; 1561 #endif 1562 } 1563 } 1564 /* 1565 * LD_CONCURRENCY and LD_CONFIG family. 1566 */ 1567 else if (*s1 == 'C') { 1568 if ((len == MSG_LD_CONCURRENCY_SIZE) && (strncmp(s1, 1569 MSG_ORIG(MSG_LD_CONCURRENCY), 1570 MSG_LD_CONCURRENCY_SIZE) == 0)) { 1571 /* 1572 * Waiting in the wings, as concurrency checking isn't 1573 * yet enabled. 1574 */ 1575 select |= SEL_ACT_SPEC_2; 1576 variable = ENV_FLG_CONCURRENCY; 1577 } else if ((len == MSG_LD_CONFGEN_SIZE) && (strncmp(s1, 1578 MSG_ORIG(MSG_LD_CONFGEN), MSG_LD_CONFGEN_SIZE) == 0)) { 1579 /* 1580 * Set by crle(1) to indicate it's building a 1581 * configuration file, not documented for general use. 1582 */ 1583 select |= SEL_ACT_SPEC_2; 1584 variable = ENV_FLG_CONFGEN; 1585 } else if ((len == MSG_LD_CONFIG_SIZE) && (strncmp(s1, 1586 MSG_ORIG(MSG_LD_CONFIG), MSG_LD_CONFIG_SIZE) == 0)) { 1587 /* 1588 * Secure applications must use a default configuration 1589 * file. A setting from a configuration file doesn't 1590 * make sense (given we must be reading a configuration 1591 * file to have gotten this). 1592 */ 1593 if ((rtld_flags & RT_FL_SECURE) || 1594 (env_flags & ENV_TYP_CONFIG)) 1595 return; 1596 select |= SEL_ACT_STR; 1597 str = &config->c_name; 1598 variable = ENV_FLG_CONFIG; 1599 } 1600 } 1601 /* 1602 * The LD_DEBUG family and LD_DEMANGLE. 1603 */ 1604 else if (*s1 == 'D') { 1605 if ((len == MSG_LD_DEBUG_SIZE) && (strncmp(s1, 1606 MSG_ORIG(MSG_LD_DEBUG), MSG_LD_DEBUG_SIZE) == 0)) { 1607 select |= SEL_ACT_STR; 1608 if (select & SEL_REPLACE) 1609 str = &rpl_debug; 1610 else { 1611 str = &prm_debug; 1612 rpl_debug = 0; 1613 } 1614 variable = ENV_FLG_DEBUG; 1615 } else if ((len == MSG_LD_DEBUG_OUTPUT_SIZE) && (strncmp(s1, 1616 MSG_ORIG(MSG_LD_DEBUG_OUTPUT), 1617 MSG_LD_DEBUG_OUTPUT_SIZE) == 0)) { 1618 select |= SEL_ACT_STR; 1619 str = &dbg_file; 1620 variable = ENV_FLG_DEBUG_OUTPUT; 1621 } else if ((len == MSG_LD_DEMANGLE_SIZE) && (strncmp(s1, 1622 MSG_ORIG(MSG_LD_DEMANGLE), MSG_LD_DEMANGLE_SIZE) == 0)) { 1623 select |= SEL_ACT_RT; 1624 val = RT_FL_DEMANGLE; 1625 variable = ENV_FLG_DEMANGLE; 1626 } 1627 } 1628 /* 1629 * LD_FLAGS - collect the best variable definition. On completion of 1630 * environment variable processing pass the result to ld_flags_env() 1631 * where they'll be decomposed and passed back to this routine. 1632 */ 1633 else if (*s1 == 'F') { 1634 if ((len == MSG_LD_FLAGS_SIZE) && (strncmp(s1, 1635 MSG_ORIG(MSG_LD_FLAGS), MSG_LD_FLAGS_SIZE) == 0)) { 1636 select |= SEL_ACT_SPEC_1; 1637 if (select & SEL_REPLACE) 1638 str = &rpl_ldflags; 1639 else { 1640 str = &prm_ldflags; 1641 rpl_ldflags = 0; 1642 } 1643 variable = ENV_FLG_FLAGS; 1644 } 1645 } 1646 /* 1647 * LD_INIT (internal, used by ldd(1)). 1648 */ 1649 else if (*s1 == 'I') { 1650 if ((len == MSG_LD_INIT_SIZE) && (strncmp(s1, 1651 MSG_ORIG(MSG_LD_INIT), MSG_LD_INIT_SIZE) == 0)) { 1652 select |= SEL_ACT_LML; 1653 val = LML_FLG_TRC_INIT; 1654 variable = ENV_FLG_INIT; 1655 } 1656 } 1657 /* 1658 * The LD_LIBRARY_PATH and LD_LOAD families. 1659 */ 1660 else if (*s1 == 'L') { 1661 if ((len == MSG_LD_LIBPATH_SIZE) && (strncmp(s1, 1662 MSG_ORIG(MSG_LD_LIBPATH), MSG_LD_LIBPATH_SIZE) == 0)) { 1663 select |= SEL_ACT_SPEC_1; 1664 if (select & SEL_REPLACE) 1665 str = &rpl_libpath; 1666 else { 1667 str = &prm_libpath; 1668 rpl_libpath = 0; 1669 } 1670 variable = ENV_FLG_LIBPATH; 1671 } else if ((len == MSG_LD_LOADAVAIL_SIZE) && (strncmp(s1, 1672 MSG_ORIG(MSG_LD_LOADAVAIL), MSG_LD_LOADAVAIL_SIZE) == 0)) { 1673 /* 1674 * Internal use by crle(1), not documented for general 1675 * use. 1676 */ 1677 select |= SEL_ACT_LML; 1678 val = LML_FLG_LOADAVAIL; 1679 variable = ENV_FLG_LOADAVAIL; 1680 } else if ((len == MSG_LD_LOADFLTR_SIZE) && (strncmp(s1, 1681 MSG_ORIG(MSG_LD_LOADFLTR), MSG_LD_LOADFLTR_SIZE) == 0)) { 1682 select |= SEL_ACT_SPEC_2; 1683 variable = ENV_FLG_LOADFLTR; 1684 } 1685 } 1686 /* 1687 * The LD_NO family. 1688 */ 1689 else if (*s1 == 'N') { 1690 if ((len == MSG_LD_NOAUDIT_SIZE) && (strncmp(s1, 1691 MSG_ORIG(MSG_LD_NOAUDIT), MSG_LD_NOAUDIT_SIZE) == 0)) { 1692 select |= SEL_ACT_RT; 1693 val = RT_FL_NOAUDIT; 1694 variable = ENV_FLG_NOAUDIT; 1695 } else if ((len == MSG_LD_NOAUXFLTR_SIZE) && (strncmp(s1, 1696 MSG_ORIG(MSG_LD_NOAUXFLTR), MSG_LD_NOAUXFLTR_SIZE) == 0)) { 1697 select |= SEL_ACT_RT; 1698 val = RT_FL_NOAUXFLTR; 1699 variable = ENV_FLG_NOAUXFLTR; 1700 } else if ((len == MSG_LD_NOBAPLT_SIZE) && (strncmp(s1, 1701 MSG_ORIG(MSG_LD_NOBAPLT), MSG_LD_NOBAPLT_SIZE) == 0)) { 1702 select |= SEL_ACT_RT; 1703 val = RT_FL_NOBAPLT; 1704 variable = ENV_FLG_NOBAPLT; 1705 } else if ((len == MSG_LD_NOCONFIG_SIZE) && (strncmp(s1, 1706 MSG_ORIG(MSG_LD_NOCONFIG), MSG_LD_NOCONFIG_SIZE) == 0)) { 1707 select |= SEL_ACT_RT; 1708 val = RT_FL_NOCFG; 1709 variable = ENV_FLG_NOCONFIG; 1710 } else if ((len == MSG_LD_NODIRCONFIG_SIZE) && (strncmp(s1, 1711 MSG_ORIG(MSG_LD_NODIRCONFIG), 1712 MSG_LD_NODIRCONFIG_SIZE) == 0)) { 1713 select |= SEL_ACT_RT; 1714 val = RT_FL_NODIRCFG; 1715 variable = ENV_FLG_NODIRCONFIG; 1716 } else if ((len == MSG_LD_NODIRECT_SIZE) && (strncmp(s1, 1717 MSG_ORIG(MSG_LD_NODIRECT), MSG_LD_NODIRECT_SIZE) == 0)) { 1718 select |= SEL_ACT_LMLT; 1719 val = LML_TFLG_NODIRECT; 1720 variable = ENV_FLG_NODIRECT; 1721 } else if ((len == MSG_LD_NOENVCONFIG_SIZE) && (strncmp(s1, 1722 MSG_ORIG(MSG_LD_NOENVCONFIG), 1723 MSG_LD_NOENVCONFIG_SIZE) == 0)) { 1724 select |= SEL_ACT_RT; 1725 val = RT_FL_NOENVCFG; 1726 variable = ENV_FLG_NOENVCONFIG; 1727 } else if ((len == MSG_LD_NOFLTCONFIG_SIZE) && (strncmp(s1, 1728 MSG_ORIG(MSG_LD_NOFLTCONFIG), 1729 MSG_LD_NOFLTCONFIG_SIZE) == 0)) { 1730 select |= SEL_ACT_RT2; 1731 val = RT_FL2_NOFLTCFG; 1732 variable = ENV_FLG_NOFLTCONFIG; 1733 } else if ((len == MSG_LD_NOLAZY_SIZE) && (strncmp(s1, 1734 MSG_ORIG(MSG_LD_NOLAZY), MSG_LD_NOLAZY_SIZE) == 0)) { 1735 select |= SEL_ACT_LMLT; 1736 val = LML_TFLG_NOLAZYLD; 1737 variable = ENV_FLG_NOLAZY; 1738 } else if ((len == MSG_LD_NOOBJALTER_SIZE) && (strncmp(s1, 1739 MSG_ORIG(MSG_LD_NOOBJALTER), 1740 MSG_LD_NOOBJALTER_SIZE) == 0)) { 1741 select |= SEL_ACT_RT; 1742 val = RT_FL_NOOBJALT; 1743 variable = ENV_FLG_NOOBJALTER; 1744 } else if ((len == MSG_LD_NOVERSION_SIZE) && (strncmp(s1, 1745 MSG_ORIG(MSG_LD_NOVERSION), MSG_LD_NOVERSION_SIZE) == 0)) { 1746 select |= SEL_ACT_RT; 1747 val = RT_FL_NOVERSION; 1748 variable = ENV_FLG_NOVERSION; 1749 } 1750 } 1751 /* 1752 * LD_ORIGIN. 1753 */ 1754 else if (*s1 == 'O') { 1755 #ifndef EXPAND_RELATIVE 1756 if ((len == MSG_LD_ORIGIN_SIZE) && (strncmp(s1, 1757 MSG_ORIG(MSG_LD_ORIGIN), MSG_LD_ORIGIN_SIZE) == 0)) { 1758 /* 1759 * Besides some old patches this is no longer required. 1760 */ 1761 rtld_flags |= RT_FL_RELATIVE; 1762 } 1763 #endif 1764 return; 1765 } 1766 /* 1767 * LD_PRELOAD and LD_PROFILE family. 1768 */ 1769 else if (*s1 == 'P') { 1770 if ((len == MSG_LD_PRELOAD_SIZE) && (strncmp(s1, 1771 MSG_ORIG(MSG_LD_PRELOAD), MSG_LD_PRELOAD_SIZE) == 0)) { 1772 select |= SEL_ACT_STR; 1773 if (select & SEL_REPLACE) 1774 str = &rpl_preload; 1775 else { 1776 str = &prm_preload; 1777 rpl_preload = 0; 1778 } 1779 variable = ENV_FLG_PRELOAD; 1780 } else if ((len == MSG_LD_PROFILE_SIZE) && (strncmp(s1, 1781 MSG_ORIG(MSG_LD_PROFILE), MSG_LD_PROFILE_SIZE) == 0)) { 1782 /* 1783 * Only one user library can be profiled at a time. 1784 */ 1785 select |= SEL_ACT_SPEC_2; 1786 variable = ENV_FLG_PROFILE; 1787 } else if ((len == MSG_LD_PROFILE_OUTPUT_SIZE) && (strncmp(s1, 1788 MSG_ORIG(MSG_LD_PROFILE_OUTPUT), 1789 MSG_LD_PROFILE_OUTPUT_SIZE) == 0)) { 1790 /* 1791 * Only one user library can be profiled at a time. 1792 */ 1793 select |= SEL_ACT_STR; 1794 str = &profile_out; 1795 variable = ENV_FLG_PROFILE_OUTPUT; 1796 } 1797 } 1798 /* 1799 * LD_SIGNAL. 1800 */ 1801 else if (*s1 == 'S') { 1802 if (rtld_flags & RT_FL_SECURE) 1803 return; 1804 if ((len == MSG_LD_SIGNAL_SIZE) && 1805 (strncmp(s1, MSG_ORIG(MSG_LD_SIGNAL), 1806 MSG_LD_SIGNAL_SIZE) == 0)) { 1807 select |= SEL_ACT_SPEC_2; 1808 variable = ENV_FLG_SIGNAL; 1809 } 1810 } 1811 /* 1812 * The LD_TRACE family (internal, used by ldd(1)). 1813 */ 1814 else if (*s1 == 'T') { 1815 if (((len == MSG_LD_TRACE_OBJS_SIZE) && 1816 (strncmp(s1, MSG_ORIG(MSG_LD_TRACE_OBJS), 1817 MSG_LD_TRACE_OBJS_SIZE) == 0)) || 1818 ((len == MSG_LD_TRACE_OBJS_E_SIZE) && 1819 (((strncmp(s1, MSG_ORIG(MSG_LD_TRACE_OBJS_E), 1820 MSG_LD_TRACE_OBJS_E_SIZE) == 0) && !aout) || 1821 ((strncmp(s1, MSG_ORIG(MSG_LD_TRACE_OBJS_A), 1822 MSG_LD_TRACE_OBJS_A_SIZE) == 0) && aout)))) { 1823 select |= SEL_ACT_SPEC_2; 1824 variable = ENV_FLG_TRACE_OBJS; 1825 } else if ((len == MSG_LD_TRACE_PTHS_SIZE) && (strncmp(s1, 1826 MSG_ORIG(MSG_LD_TRACE_PTHS), 1827 MSG_LD_TRACE_PTHS_SIZE) == 0)) { 1828 select |= SEL_ACT_LML; 1829 val = LML_FLG_TRC_SEARCH; 1830 variable = ENV_FLG_TRACE_PTHS; 1831 } 1832 } 1833 /* 1834 * LD_UNREF and LD_UNUSED (internal, used by ldd(1)). 1835 */ 1836 else if (*s1 == 'U') { 1837 if ((len == MSG_LD_UNREF_SIZE) && (strncmp(s1, 1838 MSG_ORIG(MSG_LD_UNREF), MSG_LD_UNREF_SIZE) == 0)) { 1839 select |= SEL_ACT_LML; 1840 val = LML_FLG_TRC_UNREF; 1841 variable = ENV_FLG_UNREF; 1842 } else if ((len == MSG_LD_UNUSED_SIZE) && (strncmp(s1, 1843 MSG_ORIG(MSG_LD_UNUSED), MSG_LD_UNUSED_SIZE) == 0)) { 1844 select |= SEL_ACT_LML; 1845 val = LML_FLG_TRC_UNUSED; 1846 variable = ENV_FLG_UNUSED; 1847 } 1848 } 1849 /* 1850 * LD_VERBOSE (internal, used by ldd(1)). 1851 */ 1852 else if (*s1 == 'V') { 1853 if ((len == MSG_LD_VERBOSE_SIZE) && (strncmp(s1, 1854 MSG_ORIG(MSG_LD_VERBOSE), MSG_LD_VERBOSE_SIZE) == 0)) { 1855 select |= SEL_ACT_LML; 1856 val = LML_FLG_TRC_VERBOSE; 1857 variable = ENV_FLG_VERBOSE; 1858 } 1859 } 1860 /* 1861 * LD_WARN (internal, used by ldd(1)). 1862 */ 1863 else if (*s1 == 'W') { 1864 if ((len == MSG_LD_WARN_SIZE) && (strncmp(s1, 1865 MSG_ORIG(MSG_LD_WARN), MSG_LD_WARN_SIZE) == 0)) { 1866 select |= SEL_ACT_LML; 1867 val = LML_FLG_TRC_WARN; 1868 variable = ENV_FLG_WARN; 1869 } 1870 #ifdef SIEBEL_DISABLE 1871 } 1872 /* 1873 * LD__FIX__ (undocumented, enable future technology that can't be 1874 * delivered in a patch release). 1875 */ 1876 else if (*s1 == '_') { 1877 if ((len == MSG_LD_FIX_1_SIZE) && (strncmp(s1, 1878 MSG_ORIG(MSG_LD_FIX_1), MSG_LD_FIX_1_SIZE) == 0)) { 1879 select |= SEL_ACT_RT; 1880 val = RT_FL_DISFIX_1; 1881 variable = ENV_FLG_FIX_1; 1882 } 1883 #endif 1884 } 1885 if (variable == 0) 1886 return; 1887 1888 /* 1889 * If the variable is already processed with ISA specific variable, 1890 * no further processing needed. 1891 */ 1892 if (((select & SEL_REPLACE) && (rplisa & variable)) || 1893 ((select & SEL_PERMANT) && (prmisa & variable))) 1894 return; 1895 1896 /* 1897 * Now mark the appropriate variables. 1898 * If the replaceable variable is already set, then the 1899 * process environment variable must be set. Any replaceable 1900 * variable specified in a configuration file can be ignored. 1901 */ 1902 if (env_flags & ENV_TYP_ISA) { 1903 /* 1904 * This is ISA setting. We do the setting 1905 * even if s2 is NULL. 1906 * If s2 is NULL, we might need to undo 1907 * the setting. 1908 */ 1909 if (select & SEL_REPLACE) { 1910 if (rplisa & variable) 1911 return; 1912 rplisa |= variable; 1913 } else { 1914 prmisa |= variable; 1915 } 1916 } else if (s2) { 1917 /* 1918 * This is non0-ISA setting 1919 */ 1920 if (select & SEL_REPLACE) { 1921 if (rplgen & variable) 1922 return; 1923 rplgen |= variable; 1924 } else 1925 prmgen |= variable; 1926 } else 1927 /* 1928 * This is non-ISA setting which 1929 * can be ignored. 1930 */ 1931 return; 1932 1933 /* 1934 * Now perform the setting. 1935 */ 1936 if (select & SEL_ACT_RT) { 1937 if (s2) 1938 rtld_flags |= val; 1939 else 1940 rtld_flags &= ~val; 1941 } else if (select & SEL_ACT_RT2) { 1942 if (s2) 1943 rtld_flags2 |= val; 1944 else 1945 rtld_flags2 &= ~val; 1946 } else if (select & SEL_ACT_STR) 1947 *str = s2; 1948 else if (select & SEL_ACT_LML) { 1949 if (s2) 1950 *lmflags |= val; 1951 else 1952 *lmflags &= ~val; 1953 } else if (select & SEL_ACT_LMLT) { 1954 if (s2) 1955 *lmtflags |= val; 1956 else 1957 *lmtflags &= ~val; 1958 } else if (select & SEL_ACT_SPEC_1) { 1959 /* 1960 * variable is either ENV_FLG_FLAGS or ENV_FLG_LIBPATH 1961 */ 1962 *str = s2; 1963 if ((select & SEL_REPLACE) && (env_flags & ENV_TYP_CONFIG)) { 1964 if (s2) { 1965 if (variable == ENV_FLG_FLAGS) 1966 env_info |= ENV_INF_FLAGCFG; 1967 else 1968 env_info |= ENV_INF_PATHCFG; 1969 } else { 1970 if (variable == ENV_FLG_FLAGS) 1971 env_info &= ~ENV_INF_FLAGCFG; 1972 else 1973 env_info &= ~ENV_INF_PATHCFG; 1974 } 1975 } 1976 } else if (select & SEL_ACT_SPEC_2) { 1977 /* 1978 * variables can be: ENV_FLG_ 1979 * AUDIT_ARGS, BINDING, CONCURRENCY, CONFGEN, 1980 * LOADFLTR, PROFILE, SIGNAL, TRACE_OBJS 1981 */ 1982 if (variable == ENV_FLG_AUDIT_ARGS) { 1983 if (s2) { 1984 audit_argcnt = atoi(s2); 1985 audit_argcnt += audit_argcnt % 2; 1986 } else 1987 audit_argcnt = 0; 1988 } else if (variable == ENV_FLG_BINDINGS) { 1989 if (s2) 1990 rpl_debug = MSG_ORIG(MSG_TKN_BINDINGS); 1991 else 1992 rpl_debug = 0; 1993 } else if (variable == ENV_FLG_CONCURRENCY) { 1994 if (s2) 1995 rtld_flags &= ~RT_FL_NOCONCUR; 1996 else 1997 rtld_flags |= RT_FL_NOCONCUR; 1998 } else if (variable == ENV_FLG_CONFGEN) { 1999 if (s2) { 2000 rtld_flags |= RT_FL_CONFGEN; 2001 *lmflags |= LML_FLG_IGNRELERR; 2002 } else { 2003 rtld_flags &= ~RT_FL_CONFGEN; 2004 *lmflags &= ~LML_FLG_IGNRELERR; 2005 } 2006 } else if (variable == ENV_FLG_LOADFLTR) { 2007 if (s2) { 2008 *lmtflags |= LML_TFLG_LOADFLTR; 2009 if (*s2 == '2') 2010 rtld_flags |= RT_FL_WARNFLTR; 2011 } else { 2012 *lmtflags &= ~LML_TFLG_LOADFLTR; 2013 rtld_flags &= ~RT_FL_WARNFLTR; 2014 } 2015 } else if (variable == ENV_FLG_PROFILE) { 2016 profile_name = s2; 2017 if (s2) { 2018 if (strcmp(s2, MSG_ORIG(MSG_FIL_RTLD)) == 0) { 2019 return; 2020 } 2021 if (rtld_flags & RT_FL_SECURE) { 2022 profile_lib = 2023 #if defined(_ELF64) 2024 MSG_ORIG(MSG_PTH_LDPROFSE_64); 2025 #else 2026 MSG_ORIG(MSG_PTH_LDPROFSE); 2027 #endif 2028 } else { 2029 profile_lib = 2030 #if defined(_ELF64) 2031 MSG_ORIG(MSG_PTH_LDPROF_64); 2032 #else 2033 MSG_ORIG(MSG_PTH_LDPROF); 2034 #endif 2035 } 2036 } else 2037 profile_lib = 0; 2038 } else if (variable == ENV_FLG_SIGNAL) { 2039 killsig = s2 ? atoi(s2) : SIGKILL; 2040 } else if (variable == ENV_FLG_TRACE_OBJS) { 2041 if (s2) { 2042 *lmflags |= LML_FLG_TRC_ENABLE; 2043 if (*s2 == '2') 2044 *lmflags |= LML_FLG_TRC_LDDSTUB; 2045 } else 2046 *lmflags &= 2047 ~(LML_FLG_TRC_ENABLE|LML_FLG_TRC_LDDSTUB); 2048 } 2049 } 2050 } 2051 2052 /* 2053 * Determine whether we have an architecture specific environment variable. 2054 * If we do, and we're the wrong architecture, it'll just get ignored. 2055 * Otherwise the variable is processed in it's architecture neutral form. 2056 */ 2057 static int 2058 ld_arch_env(const char *s1, size_t *len) 2059 { 2060 size_t _len = *len - 3; 2061 2062 if (s1[_len++] == '_') { 2063 if ((s1[_len] == '3') && (s1[_len + 1] == '2')) { 2064 #if defined(_ELF64) 2065 return (ENV_TYP_IGNORE); 2066 #else 2067 *len = *len - 3; 2068 return (ENV_TYP_ISA); 2069 #endif 2070 } 2071 if ((s1[_len] == '6') && (s1[_len + 1] == '4')) { 2072 #if defined(_ELF64) 2073 *len = *len - 3; 2074 return (ENV_TYP_ISA); 2075 #else 2076 return (ENV_TYP_IGNORE); 2077 #endif 2078 } 2079 } 2080 return (0); 2081 } 2082 2083 2084 /* 2085 * Process an LD_FLAGS environment variable. The value can be a comma 2086 * separated set of tokens, which are sent (in upper case) into the generic 2087 * LD_XXXX environment variable engine. For example: 2088 * 2089 * LD_FLAGS=bind_now -> LD_BIND_NOW=1 2090 * LD_FLAGS=library_path=/foo:. -> LD_LIBRARY_PATH=/foo:. 2091 * LD_FLAGS=debug=files:detail -> LD_DEBUG=files:detail 2092 * or 2093 * LD_FLAGS=bind_now,library_path=/foo:.,debug=files:detail 2094 */ 2095 static int 2096 ld_flags_env(const char *str, Word *lmflags, Word *lmtflags, 2097 uint_t env_flags, int aout) 2098 { 2099 char *nstr, *sstr, *estr = 0; 2100 size_t nlen, len; 2101 2102 if (str == 0) 2103 return (0); 2104 2105 /* 2106 * Create a new string as we're going to transform the token(s) into 2107 * uppercase and separate tokens with nulls. 2108 */ 2109 len = strlen(str); 2110 if ((nstr = malloc(len + 1)) == 0) 2111 return (1); 2112 (void) strcpy(nstr, str); 2113 2114 for (sstr = nstr; sstr; sstr++, len--) { 2115 int flags; 2116 2117 if ((*sstr != '\0') && (*sstr != ',')) { 2118 if (estr == 0) { 2119 if (*sstr == '=') 2120 estr = sstr; 2121 else { 2122 /* 2123 * Translate token to uppercase. Don't 2124 * use toupper(3C) as including this 2125 * code doubles the size of ld.so.1. 2126 */ 2127 if ((*sstr >= 'a') && (*sstr <= 'z')) 2128 *sstr = *sstr - ('a' - 'A'); 2129 } 2130 } 2131 continue; 2132 } 2133 2134 *sstr = '\0'; 2135 if (estr) { 2136 nlen = estr - nstr; 2137 if ((*++estr == '\0') || (*estr == ',')) 2138 estr = 0; 2139 } else 2140 nlen = sstr - nstr; 2141 2142 /* 2143 * Fabricate a boolean definition for any unqualified variable. 2144 * Thus LD_FLAGS=bind_now is represented as BIND_NOW=(null). 2145 * The value is sufficient to assert any boolean variables, plus 2146 * the term "(null)" is specifically chosen in case someone 2147 * mistakenly supplies something like LD_FLAGS=library_path. 2148 */ 2149 if (estr == 0) 2150 estr = (char *)MSG_INTL(MSG_STR_NULL); 2151 2152 /* 2153 * Determine whether the environment variable is 32- or 64-bit 2154 * specific. The length, len, will reflect the architecture 2155 * neutral portion of the string. 2156 */ 2157 if ((flags = ld_arch_env(nstr, &nlen)) != ENV_TYP_IGNORE) { 2158 ld_generic_env(nstr, nlen, estr, lmflags, 2159 lmtflags, (env_flags | flags), aout); 2160 } 2161 if (len == 0) 2162 return (0); 2163 2164 nstr = sstr + 1; 2165 estr = 0; 2166 } 2167 return (0); 2168 } 2169 2170 2171 /* 2172 * Process a single environment string. Only strings starting with `LD_' are 2173 * reserved for our use. By convention, all strings should be of the form 2174 * `LD_XXXX=', if the string is followed by a non-null value the appropriate 2175 * functionality is enabled. Also pick off applicable locale variables. 2176 */ 2177 #define LOC_LANG 1 2178 #define LOC_MESG 2 2179 #define LOC_ALL 3 2180 2181 static void 2182 ld_str_env(const char *s1, Word *lmflags, Word *lmtflags, uint_t env_flags, 2183 int aout) 2184 { 2185 const char *s2; 2186 static size_t loc = 0; 2187 2188 if (*s1++ != 'L') 2189 return; 2190 2191 /* 2192 * See if we have any locale environment settings. These environment 2193 * variables have a precedence, LC_ALL is higher than LC_MESSAGES which 2194 * is higher than LANG. 2195 */ 2196 s2 = s1; 2197 if ((*s2++ == 'C') && (*s2++ == '_') && (*s2 != '\0')) { 2198 if (strncmp(s2, MSG_ORIG(MSG_LC_ALL), MSG_LC_ALL_SIZE) == 0) { 2199 s2 += MSG_LC_ALL_SIZE; 2200 if ((*s2 != '\0') && (loc < LOC_ALL)) { 2201 glcs[CI_LCMESSAGES].lc_un.lc_ptr = (char *)s2; 2202 loc = LOC_ALL; 2203 } 2204 } else if (strncmp(s2, MSG_ORIG(MSG_LC_MESSAGES), 2205 MSG_LC_MESSAGES_SIZE) == 0) { 2206 s2 += MSG_LC_MESSAGES_SIZE; 2207 if ((*s2 != '\0') && (loc < LOC_MESG)) { 2208 glcs[CI_LCMESSAGES].lc_un.lc_ptr = (char *)s2; 2209 loc = LOC_MESG; 2210 } 2211 } 2212 return; 2213 } 2214 2215 s2 = s1; 2216 if ((*s2++ == 'A') && (*s2++ == 'N') && (*s2++ == 'G') && 2217 (*s2++ == '=') && (*s2 != '\0') && (loc < LOC_LANG)) { 2218 glcs[CI_LCMESSAGES].lc_un.lc_ptr = (char *)s2; 2219 loc = LOC_LANG; 2220 return; 2221 } 2222 2223 /* 2224 * Pick off any LD_XXXX environment variables. 2225 */ 2226 if ((*s1++ == 'D') && (*s1++ == '_') && (*s1 != '\0')) { 2227 size_t len; 2228 int flags; 2229 2230 /* 2231 * Environment variables with no value (ie. LD_XXXX=) typically 2232 * have no impact, however if environment variables are defined 2233 * within a configuration file, these null user settings can be 2234 * used to disable any configuration replaceable definitions. 2235 */ 2236 if ((s2 = strchr(s1, '=')) == 0) { 2237 len = strlen(s1); 2238 s2 = 0; 2239 } else if (*++s2 == '\0') { 2240 len = strlen(s1) - 1; 2241 s2 = 0; 2242 } else { 2243 len = s2 - s1 - 1; 2244 while (isspace(*s2)) 2245 s2++; 2246 } 2247 2248 /* 2249 * Determine whether the environment variable is 32- or 64-bit 2250 * specific. The length, len, will reflect the architecture 2251 * neutral portion of the string. 2252 */ 2253 if ((flags = ld_arch_env(s1, &len)) == ENV_TYP_IGNORE) 2254 return; 2255 env_flags |= flags; 2256 2257 ld_generic_env(s1, len, s2, lmflags, lmtflags, env_flags, aout); 2258 } 2259 } 2260 2261 /* 2262 * Internal getenv routine. Called immediately after ld.so.1 initializes 2263 * itself. 2264 */ 2265 int 2266 readenv_user(const char ** envp, Word *lmflags, Word *lmtflags, int aout) 2267 { 2268 char *locale; 2269 2270 if (envp == (const char **)0) 2271 return (0); 2272 2273 while (*envp != (const char *)0) 2274 ld_str_env(*envp++, lmflags, lmtflags, 0, aout); 2275 2276 /* 2277 * Having collected the best representation of any LD_FLAGS, process 2278 * these strings. 2279 */ 2280 if (ld_flags_env(rpl_ldflags, lmflags, lmtflags, 0, aout) == 1) 2281 return (1); 2282 2283 /* 2284 * Don't allow environment controlled auditing when tracing or if 2285 * explicitly disabled. Trigger all tracing modes from 2286 * LML_FLG_TRC_ENABLE. 2287 */ 2288 if ((*lmflags & LML_FLG_TRC_ENABLE) || (rtld_flags & RT_FL_NOAUDIT)) 2289 rpl_audit = profile_lib = profile_name = 0; 2290 if ((*lmflags & LML_FLG_TRC_ENABLE) == 0) 2291 *lmflags &= ~LML_MSK_TRC; 2292 2293 /* 2294 * If both LD_BIND_NOW and LD_BIND_LAZY are specified, the former wins. 2295 */ 2296 if ((rtld_flags2 & (RT_FL2_BINDNOW | RT_FL2_BINDLAZY)) == 2297 (RT_FL2_BINDNOW | RT_FL2_BINDLAZY)) 2298 rtld_flags2 &= ~RT_FL2_BINDLAZY; 2299 2300 /* 2301 * If we have a locale setting make sure its worth processing further. 2302 * Duplicate the string so that new locale setting can generically 2303 * cleanup any previous locales. 2304 */ 2305 if ((locale = glcs[CI_LCMESSAGES].lc_un.lc_ptr) != 0) { 2306 if (((*locale == 'C') && (*(locale + 1) == '\0')) || 2307 (strcmp(locale, MSG_ORIG(MSG_TKN_POSIX)) == 0)) 2308 glcs[CI_LCMESSAGES].lc_un.lc_ptr = 0; 2309 else 2310 glcs[CI_LCMESSAGES].lc_un.lc_ptr = strdup(locale); 2311 } 2312 return (0); 2313 } 2314 2315 /* 2316 * Configuration environment processing. Called after the a.out has been 2317 * processed (as the a.out can specify its own configuration file). 2318 */ 2319 int 2320 readenv_config(Rtc_env * envtbl, Addr addr, int aout) 2321 { 2322 Word * lmflags = &(lml_main.lm_flags); 2323 Word * lmtflags = &(lml_main.lm_tflags); 2324 2325 if (envtbl == (Rtc_env *)0) 2326 return (0); 2327 2328 while (envtbl->env_str) { 2329 uint_t env_flags = ENV_TYP_CONFIG; 2330 2331 if (envtbl->env_flags & RTC_ENV_PERMANT) 2332 env_flags |= ENV_TYP_PERMANT; 2333 2334 ld_str_env((const char *)(envtbl->env_str + addr), 2335 lmflags, lmtflags, env_flags, 0); 2336 envtbl++; 2337 } 2338 2339 /* 2340 * Having collected the best representation of any LD_FLAGS, process 2341 * these strings. 2342 */ 2343 if (ld_flags_env(rpl_ldflags, lmflags, lmtflags, 0, aout) == 1) 2344 return (1); 2345 if (ld_flags_env(prm_ldflags, lmflags, lmtflags, ENV_TYP_CONFIG, 2346 aout) == 1) 2347 return (1); 2348 2349 /* 2350 * Don't allow environment controlled auditing when tracing or if 2351 * explicitly disabled. Trigger all tracing modes from 2352 * LML_FLG_TRC_ENABLE. 2353 */ 2354 if ((*lmflags & LML_FLG_TRC_ENABLE) || (rtld_flags & RT_FL_NOAUDIT)) 2355 prm_audit = profile_lib = profile_name = 0; 2356 if ((*lmflags & LML_FLG_TRC_ENABLE) == 0) 2357 *lmflags &= ~LML_MSK_TRC; 2358 2359 return (0); 2360 } 2361 2362 int 2363 dowrite(Prfbuf * prf) 2364 { 2365 /* 2366 * We do not have a valid file descriptor, so we are unable 2367 * to flush the buffer. 2368 */ 2369 if (prf->pr_fd == -1) 2370 return (0); 2371 (void) write(prf->pr_fd, prf->pr_buf, prf->pr_cur - prf->pr_buf); 2372 prf->pr_cur = prf->pr_buf; 2373 return (1); 2374 } 2375 2376 /* 2377 * Simplified printing. The following conversion specifications are supported: 2378 * 2379 * % [#] [-] [min field width] [. precision] s|d|x|c 2380 * 2381 * 2382 * dorprf takes the output buffer in the form of Prfbuf which permits 2383 * the verification of the output buffer size and the concatenation 2384 * of data to an already existing output buffer. The Prfbuf 2385 * structure contains the following: 2386 * 2387 * pr_buf pointer to the beginning of the output buffer. 2388 * pr_cur pointer to the next available byte in the output buffer. By 2389 * setting pr_cur ahead of pr_buf you can append to an already 2390 * existing buffer. 2391 * pr_len the size of the output buffer. By setting pr_len to '0' you 2392 * disable protection from overflows in the output buffer. 2393 * pr_fd a pointer to the file-descriptor the buffer will eventually be 2394 * output to. If pr_fd is set to '-1' then it's assumed there is 2395 * no output buffer and doprf() will return with an error if the 2396 * output buffer is overflowed. If pr_fd is > -1 then when the 2397 * output buffer is filled it will be flushed to pr_fd and then 2398 * the available for additional data. 2399 */ 2400 #define FLG_UT_MINUS 0x0001 /* - */ 2401 #define FLG_UT_SHARP 0x0002 /* # */ 2402 #define FLG_UT_DOTSEEN 0x0008 /* dot appeared in format spec */ 2403 2404 /* 2405 * This macro is for use from within doprf only. It is to be used for checking 2406 * the output buffer size and placing characters into the buffer. 2407 */ 2408 #define PUTC(c) \ 2409 { \ 2410 char tmpc; \ 2411 \ 2412 tmpc = (c); \ 2413 if (bufsiz && (bp >= bufend)) { \ 2414 prf->pr_cur = bp; \ 2415 if (dowrite(prf) == 0) \ 2416 return (0); \ 2417 bp = prf->pr_cur; \ 2418 } \ 2419 *bp++ = tmpc; \ 2420 } 2421 2422 size_t 2423 doprf(const char *format, va_list args, Prfbuf *prf) 2424 { 2425 char c; 2426 char *bp = prf->pr_cur; 2427 char *bufend = prf->pr_buf + prf->pr_len; 2428 size_t bufsiz = prf->pr_len; 2429 2430 while ((c = *format++) != '\0') { 2431 if (c != '%') { 2432 PUTC(c); 2433 } else { 2434 int base = 0, flag = 0, width = 0, prec = 0; 2435 size_t _i; 2436 int _c, _n; 2437 char *_s; 2438 int ls = 0; 2439 again: 2440 c = *format++; 2441 switch (c) { 2442 case '-': 2443 flag |= FLG_UT_MINUS; 2444 goto again; 2445 case '#': 2446 flag |= FLG_UT_SHARP; 2447 goto again; 2448 case '.': 2449 flag |= FLG_UT_DOTSEEN; 2450 goto again; 2451 case '0': 2452 case '1': 2453 case '2': 2454 case '3': 2455 case '4': 2456 case '5': 2457 case '6': 2458 case '7': 2459 case '8': 2460 case '9': 2461 if (flag & FLG_UT_DOTSEEN) 2462 prec = (prec * 10) + c - '0'; 2463 else 2464 width = (width * 10) + c - '0'; 2465 goto again; 2466 case 'x': 2467 case 'X': 2468 base = 16; 2469 break; 2470 case 'd': 2471 case 'D': 2472 case 'u': 2473 base = 10; 2474 flag &= ~FLG_UT_SHARP; 2475 break; 2476 case 'l': 2477 base = 10; 2478 ls++; /* number of l's (long or long long) */ 2479 if ((*format == 'l') || 2480 (*format == 'd') || (*format == 'D') || 2481 (*format == 'x') || (*format == 'X') || 2482 (*format == 'o') || (*format == 'O')) 2483 goto again; 2484 break; 2485 case 'o': 2486 case 'O': 2487 base = 8; 2488 break; 2489 case 'c': 2490 _c = va_arg(args, int); 2491 2492 for (_i = 24; _i > 0; _i -= 8) { 2493 if ((c = ((_c >> _i) & 0x7f)) != 0) { 2494 PUTC(c); 2495 } 2496 } 2497 if ((c = ((_c >> _i) & 0x7f)) != 0) { 2498 PUTC(c); 2499 } 2500 break; 2501 case 's': 2502 _s = va_arg(args, char *); 2503 _i = strlen(_s); 2504 /* LINTED */ 2505 _n = (int)(width - _i); 2506 if (!prec) 2507 /* LINTED */ 2508 prec = (int)_i; 2509 2510 if (width && !(flag & FLG_UT_MINUS)) { 2511 while (_n-- > 0) 2512 PUTC(' '); 2513 } 2514 while (((c = *_s++) != 0) && prec--) { 2515 PUTC(c); 2516 } 2517 if (width && (flag & FLG_UT_MINUS)) { 2518 while (_n-- > 0) 2519 PUTC(' '); 2520 } 2521 break; 2522 case '%': 2523 PUTC('%'); 2524 break; 2525 default: 2526 break; 2527 } 2528 2529 /* 2530 * Numeric processing 2531 */ 2532 if (base) { 2533 char local[20]; 2534 const char *string = 2535 MSG_ORIG(MSG_STR_HEXNUM); 2536 size_t ssize = 0, psize = 0; 2537 const char *prefix = 2538 MSG_ORIG(MSG_STR_EMPTY); 2539 u_longlong_t num; 2540 2541 switch (ls) { 2542 case 0: /* int */ 2543 num = (u_longlong_t) 2544 va_arg(args, uint_t); 2545 break; 2546 case 1: /* long */ 2547 num = (u_longlong_t) 2548 va_arg(args, ulong_t); 2549 break; 2550 case 2: /* long long */ 2551 num = va_arg(args, u_longlong_t); 2552 break; 2553 } 2554 2555 if (flag & FLG_UT_SHARP) { 2556 if (base == 16) { 2557 prefix = MSG_ORIG(MSG_STR_HEX); 2558 psize = 2; 2559 } else { 2560 prefix = MSG_ORIG(MSG_STR_ZERO); 2561 psize = 1; 2562 } 2563 } 2564 if ((base == 10) && (long)num < 0) { 2565 prefix = MSG_ORIG(MSG_STR_NEGATE); 2566 psize = MSG_STR_NEGATE_SIZE; 2567 num = (u_longlong_t)(-(longlong_t)num); 2568 } 2569 2570 /* 2571 * Convert the numeric value into a local 2572 * string (stored in reverse order). 2573 */ 2574 _s = local; 2575 do { 2576 *_s++ = string[num % base]; 2577 num /= base; 2578 ssize++; 2579 } while (num); 2580 2581 /* 2582 * Provide any precision or width padding. 2583 */ 2584 if (prec) { 2585 /* LINTED */ 2586 _n = (int)(prec - ssize); 2587 while (_n-- > 0) { 2588 *_s++ = '0'; 2589 ssize++; 2590 } 2591 } 2592 if (width && !(flag & FLG_UT_MINUS)) { 2593 /* LINTED */ 2594 _n = (int)(width - ssize - psize); 2595 while (_n-- > 0) { 2596 PUTC(' '); 2597 } 2598 } 2599 2600 /* 2601 * Print any prefix and the numeric string 2602 */ 2603 while (*prefix) 2604 PUTC(*prefix++); 2605 do { 2606 PUTC(*--_s); 2607 } while (_s > local); 2608 2609 /* 2610 * Provide any width padding. 2611 */ 2612 if (width && (flag & FLG_UT_MINUS)) { 2613 /* LINTED */ 2614 _n = (int)(width - ssize - psize); 2615 while (_n-- > 0) 2616 PUTC(' '); 2617 } 2618 } 2619 } 2620 } 2621 2622 PUTC('\0'); 2623 prf->pr_cur = bp; 2624 return (1); 2625 } 2626 2627 static int 2628 doprintf(const char *format, va_list args, Prfbuf *prf) 2629 { 2630 char *ocur = prf->pr_cur; 2631 2632 if (doprf(format, args, prf) == 0) 2633 return (0); 2634 /* LINTED */ 2635 return ((int)(prf->pr_cur - ocur)); 2636 } 2637 2638 /* VARARGS2 */ 2639 int 2640 sprintf(char *buf, const char *format, ...) 2641 { 2642 va_list args; 2643 int len; 2644 Prfbuf prf; 2645 2646 va_start(args, format); 2647 prf.pr_buf = prf.pr_cur = buf; 2648 prf.pr_len = 0; 2649 prf.pr_fd = -1; 2650 len = doprintf(format, args, &prf); 2651 va_end(args); 2652 2653 /* 2654 * sprintf() return value excludes the terminating null byte. 2655 */ 2656 return (len - 1); 2657 } 2658 2659 /* VARARGS3 */ 2660 int 2661 snprintf(char *buf, size_t n, const char *format, ...) 2662 { 2663 va_list args; 2664 int len; 2665 Prfbuf prf; 2666 2667 va_start(args, format); 2668 prf.pr_buf = prf.pr_cur = buf; 2669 prf.pr_len = n; 2670 prf.pr_fd = -1; 2671 len = doprintf(format, args, &prf); 2672 va_end(args); 2673 2674 return (len); 2675 } 2676 2677 /* VARARGS2 */ 2678 int 2679 bufprint(Prfbuf *prf, const char *format, ...) 2680 { 2681 va_list args; 2682 int len; 2683 2684 va_start(args, format); 2685 len = doprintf(format, args, prf); 2686 va_end(args); 2687 2688 return (len); 2689 } 2690 2691 /*PRINTFLIKE1*/ 2692 int 2693 printf(const char *format, ...) 2694 { 2695 va_list args; 2696 char buffer[ERRSIZE]; 2697 Prfbuf prf; 2698 2699 va_start(args, format); 2700 prf.pr_buf = prf.pr_cur = buffer; 2701 prf.pr_len = ERRSIZE; 2702 prf.pr_fd = 1; 2703 (void) doprf(format, args, &prf); 2704 va_end(args); 2705 /* 2706 * Trim trailing '\0' form buffer 2707 */ 2708 prf.pr_cur--; 2709 return (dowrite(&prf)); 2710 } 2711 2712 static char errbuf[ERRSIZE], *nextptr = errbuf, *prevptr = 0; 2713 2714 /*PRINTFLIKE3*/ 2715 void 2716 eprintf(Lm_list *lml, Error error, const char *format, ...) 2717 { 2718 va_list args; 2719 int overflow = 0; 2720 static int lock = 0; 2721 Prfbuf prf; 2722 2723 if (lock || (nextptr == (errbuf + ERRSIZE))) 2724 return; 2725 2726 /* 2727 * Note: this lock is here to prevent the same thread from recursively 2728 * entering itself during a eprintf. ie: during eprintf malloc() fails 2729 * and we try and call eprintf ... and then malloc() fails .... 2730 */ 2731 lock = 1; 2732 2733 /* 2734 * If we have completed startup initialization, all error messages 2735 * must be saved. These are reported through dlerror(). If we're 2736 * still in the initialization stage, output the error directly and 2737 * add a newline. 2738 */ 2739 va_start(args, format); 2740 2741 prf.pr_buf = prf.pr_cur = nextptr; 2742 prf.pr_len = ERRSIZE - (nextptr - errbuf); 2743 2744 if (!(rtld_flags & RT_FL_APPLIC)) 2745 prf.pr_fd = 2; 2746 else 2747 prf.pr_fd = -1; 2748 2749 if (error > ERR_NONE) { 2750 if ((error == ERR_FATAL) && (rtld_flags2 & RT_FL2_FTL2WARN)) 2751 error = ERR_WARNING; 2752 if (error == ERR_WARNING) { 2753 if (err_strs[ERR_WARNING] == 0) 2754 err_strs[ERR_WARNING] = MSG_INTL(MSG_ERR_WARNING); 2755 } else if (error == ERR_FATAL) { 2756 if (err_strs[ERR_FATAL] == 0) 2757 err_strs[ERR_FATAL] = MSG_INTL(MSG_ERR_FATAL); 2758 } else if (error == ERR_ELF) { 2759 if (err_strs[ERR_ELF] == 0) 2760 err_strs[ERR_ELF] = MSG_INTL(MSG_ERR_ELF); 2761 } 2762 if (procname) { 2763 if (bufprint(&prf, MSG_ORIG(MSG_STR_EMSGFOR1), 2764 rtldname, procname, err_strs[error]) == 0) 2765 overflow = 1; 2766 } else { 2767 if (bufprint(&prf, MSG_ORIG(MSG_STR_EMSGFOR2), 2768 rtldname, err_strs[error]) == 0) 2769 overflow = 1; 2770 } 2771 if (overflow == 0) { 2772 /* 2773 * Remove the terminating '\0'. 2774 */ 2775 prf.pr_cur--; 2776 } 2777 } 2778 2779 if ((overflow == 0) && doprf(format, args, &prf) == 0) 2780 overflow = 1; 2781 2782 /* 2783 * If this is an ELF error, it will have been generated by a support 2784 * object that has a dependency on libelf. ld.so.1 doesn't generate any 2785 * ELF error messages as it doesn't interact with libelf. Determine the 2786 * ELF error string. 2787 */ 2788 if ((overflow == 0) && (error == ERR_ELF)) { 2789 static int (*elfeno)() = 0; 2790 static const char *(*elfemg)(); 2791 const char *emsg; 2792 Rt_map *dlmp, *lmp = lml_rtld.lm_head; 2793 2794 if (NEXT(lmp) && (elfeno == 0)) { 2795 if (((elfemg = (const char *(*)())dlsym_intn(RTLD_NEXT, 2796 MSG_ORIG(MSG_SYM_ELFERRMSG), lmp, &dlmp)) == 0) || 2797 ((elfeno = (int (*)())dlsym_intn(RTLD_NEXT, 2798 MSG_ORIG(MSG_SYM_ELFERRNO), lmp, &dlmp)) == 0)) 2799 elfeno = 0; 2800 } 2801 2802 /* 2803 * Lookup the message; equivalent to elf_errmsg(elf_errno()). 2804 */ 2805 if (elfeno && ((emsg = (* elfemg)((* elfeno)())) != 0)) { 2806 prf.pr_cur--; 2807 if (bufprint(&prf, MSG_ORIG(MSG_STR_EMSGFOR2), 2808 emsg) == 0) 2809 overflow = 1; 2810 } 2811 } 2812 2813 /* 2814 * Push out any message that's been built. Note, in the case of an 2815 * overflow condition, this message may be incomplete, in which case 2816 * make sure any partial string is null terminated. 2817 */ 2818 if (overflow) 2819 *(prf.pr_cur) = '\0'; 2820 if ((rtld_flags & (RT_FL_APPLIC | RT_FL_SILENCERR)) == 0) { 2821 *(prf.pr_cur - 1) = '\n'; 2822 (void) dowrite(&prf); 2823 } 2824 2825 DBG_CALL(Dbg_util_str(lml, nextptr)); 2826 va_end(args); 2827 2828 /* 2829 * Determine if there was insufficient space left in the buffer to 2830 * complete the message. If so, we'll have printed out as much as had 2831 * been processed if we're not yet executing the application. 2832 * Otherwise, there will be some debugging diagnostic indicating 2833 * as much of the error message as possible. Write out a final buffer 2834 * overflow diagnostic - unlocalized, so we don't chance more errors. 2835 */ 2836 if (overflow) { 2837 char *str = (char *)MSG_INTL(MSG_EMG_BUFOVRFLW); 2838 2839 if ((rtld_flags & RT_FL_SILENCERR) == 0) { 2840 lasterr = str; 2841 2842 if ((rtld_flags & RT_FL_APPLIC) == 0) { 2843 (void) write(2, str, strlen(str)); 2844 (void) write(2, MSG_ORIG(MSG_STR_NL), 2845 MSG_STR_NL_SIZE); 2846 } 2847 } 2848 DBG_CALL(Dbg_util_str(lml, str)); 2849 2850 lock = 0; 2851 nextptr = errbuf + ERRSIZE; 2852 return; 2853 } 2854 2855 /* 2856 * If the application has started, then error messages are being saved 2857 * for retrieval by dlerror(), or possible flushing from rtldexit() in 2858 * the case of a fatal error. In this case, establish the next error 2859 * pointer. If we haven't started the application, the whole message 2860 * buffer can be reused. 2861 */ 2862 if ((rtld_flags & RT_FL_SILENCERR) == 0) { 2863 lasterr = nextptr; 2864 2865 /* 2866 * Note, should we encounter an error such as ENOMEM, there may 2867 * be a number of the same error messages (ie. an operation 2868 * fails with ENOMEM, and then the attempts to construct the 2869 * error message itself, which incurs additional ENOMEM errors). 2870 * Compare any previous error message with the one we've just 2871 * created to prevent any duplication clutter. 2872 */ 2873 if ((rtld_flags & RT_FL_APPLIC) && 2874 ((prevptr == 0) || (strcmp(prevptr, nextptr) != 0))) { 2875 prevptr = nextptr; 2876 nextptr = prf.pr_cur; 2877 *nextptr = '\0'; 2878 } 2879 } 2880 lock = 0; 2881 } 2882 2883 2884 #if DEBUG 2885 /* 2886 * Provide assfail() for ASSERT() statements, 2887 * see <sys/debug.h> for further details. 2888 */ 2889 int 2890 assfail(const char *a, const char *f, int l) 2891 { 2892 (void) printf("assertion failed: %s, file: %s, line: %d\n", a, f, l); 2893 (void) _lwp_kill(_lwp_self(), SIGABRT); 2894 return (0); 2895 } 2896 #endif 2897 2898 /* 2899 * Exit. If we arrive here with a non zero status it's because of a fatal 2900 * error condition (most commonly a relocation error). If the application has 2901 * already had control, then the actual fatal error message will have been 2902 * recorded in the dlerror() message buffer. Print the message before really 2903 * exiting. 2904 */ 2905 void 2906 rtldexit(Lm_list * lml, int status) 2907 { 2908 if (status) { 2909 if (rtld_flags & RT_FL_APPLIC) { 2910 /* 2911 * If the error buffer has been used, write out all 2912 * pending messages - lasterr is simply a pointer to 2913 * the last message in this buffer. However, if the 2914 * buffer couldn't be created at all, lasterr points 2915 * to a constant error message string. 2916 */ 2917 if (*errbuf) { 2918 char *errptr = errbuf; 2919 char *errend = errbuf + ERRSIZE; 2920 2921 while ((errptr < errend) && *errptr) { 2922 size_t size = strlen(errptr); 2923 (void) write(2, errptr, size); 2924 (void) write(2, MSG_ORIG(MSG_STR_NL), 2925 MSG_STR_NL_SIZE); 2926 errptr += (size + 1); 2927 } 2928 } 2929 if (lasterr && ((lasterr < errbuf) || 2930 (lasterr > (errbuf + ERRSIZE)))) { 2931 (void) write(2, lasterr, strlen(lasterr)); 2932 (void) write(2, MSG_ORIG(MSG_STR_NL), 2933 MSG_STR_NL_SIZE); 2934 } 2935 } 2936 leave(lml); 2937 (void) _lwp_kill(_lwp_self(), killsig); 2938 } 2939 _exit(status); 2940 } 2941 2942 /* 2943 * Routines to co-ordinate the opening of /dev/zero and /proc. 2944 * dz_fd is exported for possible use by libld.so, and to insure it gets 2945 * closed on leaving ld.so.1. 2946 */ 2947 int dz_fd = FD_UNAVAIL; 2948 2949 void 2950 dz_init(int fd) 2951 { 2952 dz_fd = fd; 2953 } 2954 2955 2956 /* 2957 * mmap() a page from MAP_ANON 2958 * 2959 * Note: MAP_ANON is only on Solaris8++, we use this routine to 2960 * not only mmap(MAP_ANON) but to also probe if it is available 2961 * on the current OS. 2962 */ 2963 Am_ret 2964 anon_map(Lm_list *lml, caddr_t *addr, size_t len, int prot, int flags) 2965 { 2966 #if defined(MAP_ANON) 2967 static int noanon = 0; 2968 caddr_t va; 2969 2970 if (noanon == 0) { 2971 if ((va = (caddr_t)mmap(*addr, len, prot, 2972 (flags | MAP_ANON), -1, 0)) != MAP_FAILED) { 2973 *addr = va; 2974 return (AM_OK); 2975 } 2976 2977 if ((errno != EBADF) && (errno != EINVAL)) { 2978 int err = errno; 2979 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_MMAPANON), 2980 MSG_ORIG(MSG_PTH_DEVZERO), strerror(err)); 2981 return (AM_ERROR); 2982 } else 2983 noanon = 1; 2984 } 2985 #endif 2986 return (AM_NOSUP); 2987 } 2988 2989 /* 2990 * Map anonymous memory from /dev/zero, or via MAP_ANON. 2991 * 2992 * (MAP_ANON only appears on Solaris 8, so we need fall-back 2993 * behavior for older systems.) 2994 */ 2995 caddr_t 2996 dz_map(Lm_list *lml, caddr_t addr, size_t len, int prot, int flags) 2997 { 2998 caddr_t va; 2999 int err; 3000 Am_ret amret; 3001 3002 amret = anon_map(lml, &addr, len, prot, flags); 3003 3004 if (amret == AM_OK) 3005 return (addr); 3006 if (amret == AM_ERROR) 3007 return (MAP_FAILED); 3008 3009 /* amret == AM_NOSUP -> fallback to a devzero mmaping */ 3010 3011 if (dz_fd == FD_UNAVAIL) { 3012 if ((dz_fd = open(MSG_ORIG(MSG_PTH_DEVZERO), 3013 O_RDONLY)) == FD_UNAVAIL) { 3014 err = errno; 3015 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), 3016 MSG_ORIG(MSG_PTH_DEVZERO), strerror(err)); 3017 return (MAP_FAILED); 3018 } 3019 } 3020 3021 if ((va = mmap(addr, len, prot, flags, dz_fd, 0)) == MAP_FAILED) { 3022 err = errno; 3023 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_MMAP), 3024 MSG_ORIG(MSG_PTH_DEVZERO), strerror(err)); 3025 } 3026 return (va); 3027 } 3028 3029 static int pr_fd = FD_UNAVAIL; 3030 3031 int 3032 pr_open(Lm_list *lml) 3033 { 3034 char proc[16]; 3035 3036 if (pr_fd == FD_UNAVAIL) { 3037 (void) snprintf(proc, 16, MSG_ORIG(MSG_FMT_PROC), 3038 (int)getpid()); 3039 if ((pr_fd = open(proc, O_RDONLY)) == FD_UNAVAIL) { 3040 int err = errno; 3041 3042 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), proc, 3043 strerror(err)); 3044 } 3045 } 3046 return (pr_fd); 3047 } 3048 3049 static int nu_fd = FD_UNAVAIL; 3050 3051 caddr_t 3052 nu_map(Lm_list *lml, caddr_t addr, size_t len, int prot, int flags) 3053 { 3054 caddr_t va; 3055 int err; 3056 3057 if (nu_fd == FD_UNAVAIL) { 3058 if ((nu_fd = open(MSG_ORIG(MSG_PTH_DEVNULL), 3059 O_RDONLY)) == FD_UNAVAIL) { 3060 err = errno; 3061 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), 3062 MSG_ORIG(MSG_PTH_DEVNULL), strerror(err)); 3063 return (MAP_FAILED); 3064 } 3065 } 3066 3067 if ((va = (caddr_t)mmap(addr, len, prot, flags, nu_fd, 0)) == 3068 MAP_FAILED) { 3069 err = errno; 3070 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_MMAP), 3071 MSG_ORIG(MSG_PTH_DEVNULL), strerror(err)); 3072 } 3073 return (va); 3074 } 3075 3076 /* 3077 * Generic entry point from user code - simply grabs a lock. 3078 */ 3079 int 3080 enter(void) 3081 { 3082 if (rt_bind_guard(THR_FLG_RTLD)) { 3083 (void) rt_mutex_lock(&rtldlock); 3084 return (1); 3085 } 3086 return (0); 3087 } 3088 3089 /* 3090 * Generate diagnostics as to whether an object has been used. A symbolic 3091 * reference that gets bound to an object marks it as used. Dependencies that 3092 * are unused when RTLD_NOW is in effect should be removed from future builds 3093 * of an object. Dependencies that are unused without RTLD_NOW in effect are 3094 * candidates for lazy-loading. 3095 * Unreferenced objects identify objects that are defined as dependencies but 3096 * are unreferenced by the caller (they may however be referenced by other 3097 * objects within the process, and therefore don't qualify as completely unused. 3098 */ 3099 void 3100 unused(Lm_list *lml) 3101 { 3102 Rt_map *lmp; 3103 int nl = 0; 3104 Word tracing; 3105 3106 /* 3107 * If we're not tracing unused references or dependencies, or debugging 3108 * there's nothing to do. 3109 */ 3110 tracing = lml->lm_flags & (LML_FLG_TRC_UNREF | LML_FLG_TRC_UNUSED); 3111 3112 if ((tracing == 0) && (DBG_ENABLED == 0)) 3113 return; 3114 3115 /* 3116 * Traverse the link-maps looking for unreferenced or unused 3117 * dependencies. Ignore the first object on a link-map list, as this 3118 * is effectively always used. 3119 */ 3120 for (lmp = (Rt_map *)NEXT(lml->lm_head); lmp; 3121 lmp = (Rt_map *)NEXT(lmp)) { 3122 /* 3123 * If tracing unreferenced objects, or under debugging, 3124 * determine whether any of this objects callers haven't 3125 * referenced it. 3126 */ 3127 if ((tracing & LML_FLG_TRC_UNREF) || DBG_ENABLED) { 3128 Bnd_desc ** bdpp; 3129 Aliste off; 3130 3131 for (ALIST_TRAVERSE(CALLERS(lmp), off, bdpp)) { 3132 Bnd_desc * bdp = *bdpp; 3133 Rt_map * clmp; 3134 3135 if (bdp->b_flags & BND_REFER) 3136 continue; 3137 3138 clmp = bdp->b_caller; 3139 if (FLAGS1(clmp) & FL1_RT_LDDSTUB) 3140 continue; 3141 3142 if (nl++ == 0) { 3143 if (tracing & LML_FLG_TRC_UNREF) 3144 (void) printf(MSG_ORIG(MSG_STR_NL)); 3145 else 3146 DBG_CALL(Dbg_util_nl(lml, 3147 DBG_NL_STD)); 3148 } 3149 3150 if (tracing & LML_FLG_TRC_UNREF) 3151 (void) printf(MSG_INTL(MSG_LDD_UNREF_FMT), 3152 NAME(lmp), NAME(clmp)); 3153 else 3154 DBG_CALL(Dbg_unused_unref(lmp, NAME(clmp))); 3155 } 3156 } 3157 3158 /* 3159 * If tracing unused objects simply display those objects that 3160 * haven't been referenced by anyone. 3161 */ 3162 if (FLAGS1(lmp) & FL1_RT_USED) 3163 continue; 3164 3165 if (nl++ == 0) { 3166 if (tracing) 3167 (void) printf(MSG_ORIG(MSG_STR_NL)); 3168 else 3169 DBG_CALL(Dbg_util_nl(lml, DBG_NL_STD)); 3170 } 3171 if (CYCGROUP(lmp)) { 3172 if (tracing) 3173 (void) printf(MSG_INTL(MSG_LDD_UNCYC_FMT), 3174 NAME(lmp), CYCGROUP(lmp)); 3175 else 3176 DBG_CALL(Dbg_unused_file(lml, NAME(lmp), 0, 3177 CYCGROUP(lmp))); 3178 } else { 3179 if (tracing) 3180 (void) printf(MSG_INTL(MSG_LDD_UNUSED_FMT), 3181 NAME(lmp)); 3182 else 3183 DBG_CALL(Dbg_unused_file(lml, NAME(lmp), 0, 0)); 3184 } 3185 } 3186 3187 DBG_CALL(Dbg_util_nl(lml, DBG_NL_STD)); 3188 } 3189 3190 /* 3191 * Initialization routine for the Fmap structure. If the fmap structure is 3192 * already in use, any mapping is released. The structure is then initialized 3193 * in preparation for further use. 3194 */ 3195 void 3196 fmap_setup() 3197 { 3198 #if defined(MAP_ALIGN) 3199 /* 3200 * If MAP_ALIGN is set, the fm_addr has been seeded with an alignment 3201 * value. Otherwise, if fm_addr is non-null it indicates a mapping that 3202 * should now be freed. 3203 */ 3204 if (fmap->fm_maddr && ((fmap->fm_mflags & MAP_ALIGN) == 0)) 3205 (void) munmap((caddr_t)fmap->fm_maddr, fmap->fm_msize); 3206 3207 /* 3208 * Providing we haven't determined that this system doesn't support 3209 * MAP_ALIGN, initialize the mapping address with the default segment 3210 * alignment. 3211 */ 3212 if ((rtld_flags2 & RT_FL2_NOMALIGN) == 0) { 3213 fmap->fm_maddr = (char *)M_SEGM_ALIGN; 3214 fmap->fm_mflags = MAP_PRIVATE | MAP_ALIGN; 3215 } else { 3216 fmap->fm_maddr = 0; 3217 fmap->fm_mflags = MAP_PRIVATE; 3218 } 3219 #else 3220 if (fmap->fm_maddr) 3221 (void) munmap((caddr_t)fmap->fm_maddr, fmap->fm_msize); 3222 3223 fmap->fm_maddr = 0; 3224 fmap->fm_mflags = MAP_PRIVATE; 3225 #endif 3226 3227 fmap->fm_msize = syspagsz; 3228 fmap->fm_hwptr = 0; 3229 } 3230 3231 /* 3232 * Generic cleanup routine called prior to returning control to the user. 3233 * Insures that any ld.so.1 specific file descriptors or temporary mapping are 3234 * released, and any locks dropped. 3235 */ 3236 void 3237 leave(Lm_list * lml) 3238 { 3239 /* 3240 * Alert the debuggers that the link-maps are consistent. 3241 */ 3242 if (lml) 3243 rd_event(lml, RD_DLACTIVITY, RT_CONSISTENT); 3244 3245 if (dz_fd != FD_UNAVAIL) { 3246 (void) close(dz_fd); 3247 dz_fd = FD_UNAVAIL; 3248 } 3249 3250 if (pr_fd != FD_UNAVAIL) { 3251 (void) close(pr_fd); 3252 pr_fd = FD_UNAVAIL; 3253 } 3254 3255 if (nu_fd != FD_UNAVAIL) { 3256 (void) close(nu_fd); 3257 nu_fd = FD_UNAVAIL; 3258 } 3259 3260 fmap_setup(); 3261 3262 /* 3263 * Reinitialize error message pointer, and any overflow indication. 3264 */ 3265 nextptr = errbuf; 3266 prevptr = 0; 3267 3268 /* 3269 * Don't drop our lock if we are running on our link-map list as 3270 * there's little point in doing so since we are single-threaded. 3271 * 3272 * LML_FLG_HOLDLOCK is set for: 3273 * *) The ld.so.1's link-map list. 3274 * *) The auditor's link-map if the environment is 3275 * libc/libthread un-unified. 3276 */ 3277 if (lml && (lml->lm_flags & LML_FLG_HOLDLOCK)) 3278 return; 3279 3280 if (rt_bind_clear(0) & THR_FLG_RTLD) { 3281 (void) rt_mutex_unlock(&rtldlock); 3282 (void) rt_bind_clear(THR_FLG_RTLD); 3283 } 3284 } 3285 3286 int 3287 callable(Rt_map * clmp, Rt_map * dlmp, Grp_hdl * ghp) 3288 { 3289 Alist * calp, * dalp; 3290 Aliste cnt1, cnt2; 3291 Grp_hdl ** ghpp1, ** ghpp2; 3292 3293 /* 3294 * An object can always find symbols within itself. 3295 */ 3296 if (clmp == dlmp) 3297 return (1); 3298 3299 /* 3300 * Don't allow an object to bind to an object that is being deleted 3301 * unless the binder is also being deleted. 3302 */ 3303 if ((FLAGS(dlmp) & FLG_RT_DELETE) && 3304 ((FLAGS(clmp) & FLG_RT_DELETE) == 0)) 3305 return (0); 3306 3307 /* 3308 * An object with world access can always bind to an object with global 3309 * visibility. 3310 */ 3311 if ((MODE(clmp) & RTLD_WORLD) && (MODE(dlmp) & RTLD_GLOBAL)) 3312 return (1); 3313 3314 /* 3315 * An object with local access can only bind to an object that is a 3316 * member of the same group. 3317 */ 3318 if (((MODE(clmp) & RTLD_GROUP) == 0) || 3319 ((calp = GROUPS(clmp)) == 0) || ((dalp = GROUPS(dlmp)) == 0)) 3320 return (0); 3321 3322 /* 3323 * Traverse the list of groups the caller is a part of. 3324 */ 3325 for (ALIST_TRAVERSE(calp, cnt1, ghpp1)) { 3326 /* 3327 * If we're testing for the ability of two objects to bind to 3328 * each other regardless of a specific group, ignore that group. 3329 */ 3330 if (ghp && (*ghpp1 == ghp)) 3331 continue; 3332 3333 /* 3334 * Traverse the list of groups the destination is a part of. 3335 */ 3336 for (ALIST_TRAVERSE(dalp, cnt2, ghpp2)) { 3337 if (*ghpp1 == *ghpp2) 3338 return (1); 3339 } 3340 } 3341 return (0); 3342 } 3343 3344 /* 3345 * Initialize the environ symbol. Traditionally this is carried out by the crt 3346 * code prior to jumping to main. However, init sections get fired before this 3347 * variable is initialized, so ld.so.1 sets this directly from the AUX vector 3348 * information. In addition, a process may have multiple link-maps (ld.so.1's 3349 * debugging and preloading objects), and link auditing, and each may need an 3350 * environ variable set. 3351 * 3352 * This routine is called after a relocation() pass, and thus provides for: 3353 * 3354 * o setting environ on the main link-map after the initial application and 3355 * its dependencies have been established. Typically environ lives in the 3356 * application (provided by its crt), but in older applications it might 3357 * be in libc. Who knows what's expected of applications not built on 3358 * Solaris. 3359 * 3360 * o after loading a new shared object. We can add shared objects to various 3361 * link-maps, and any link-map dependencies requiring getopt() require 3362 * their own environ. In addition, lazy loading might bring in the 3363 * supplier of environ (libc used to be a lazy loading candidate) after 3364 * the link-map has been established and other objects are present. 3365 * 3366 * This routine handles all these scenarios, without adding unnecessary overhead 3367 * to ld.so.1. 3368 */ 3369 void 3370 set_environ(Lm_list *lml) 3371 { 3372 Rt_map * dlmp; 3373 Sym * sym; 3374 Slookup sl; 3375 uint_t binfo; 3376 3377 sl.sl_name = MSG_ORIG(MSG_SYM_ENVIRON); 3378 sl.sl_cmap = lml->lm_head; 3379 sl.sl_imap = lml->lm_head; 3380 sl.sl_hash = 0; 3381 sl.sl_rsymndx = 0; 3382 sl.sl_flags = LKUP_WEAK; 3383 3384 if (sym = LM_LOOKUP_SYM(lml->lm_head)(&sl, &dlmp, &binfo)) { 3385 lml->lm_environ = (char ***)sym->st_value; 3386 3387 if (!(FLAGS(dlmp) & FLG_RT_FIXED)) 3388 lml->lm_environ = 3389 (char ***)((uintptr_t)lml->lm_environ + 3390 (uintptr_t)ADDR(dlmp)); 3391 *(lml->lm_environ) = (char **)environ; 3392 lml->lm_flags |= LML_FLG_ENVIRON; 3393 } 3394 } 3395 3396 /* 3397 * Determine whether we have a secure executable. Uid and gid information 3398 * can be passed to us via the aux vector, however if these values are -1 3399 * then use the appropriate system call to obtain them. 3400 * 3401 * o If the user is the root they can do anything 3402 * 3403 * o If the real and effective uid's don't match, or the real and 3404 * effective gid's don't match then this is determined to be a `secure' 3405 * application. 3406 * 3407 * This function is called prior to any dependency processing (see _setup.c). 3408 * Any secure setting will remain in effect for the life of the process. 3409 */ 3410 void 3411 security(uid_t uid, uid_t euid, gid_t gid, gid_t egid, int auxflags) 3412 { 3413 #ifdef AT_SUN_AUXFLAGS 3414 if (auxflags != -1) { 3415 if ((auxflags & AF_SUN_SETUGID) != 0) 3416 rtld_flags |= RT_FL_SECURE; 3417 return; 3418 } 3419 #endif 3420 if (uid == -1) 3421 uid = getuid(); 3422 if (uid) { 3423 if (euid == -1) 3424 euid = geteuid(); 3425 if (uid != euid) 3426 rtld_flags |= RT_FL_SECURE; 3427 else { 3428 if (gid == -1) 3429 gid = getgid(); 3430 if (egid == -1) 3431 egid = getegid(); 3432 if (gid != egid) 3433 rtld_flags |= RT_FL_SECURE; 3434 } 3435 } 3436 } 3437 3438 /* 3439 * _REENTRANT code gets errno redefined to a function so provide for return 3440 * of the thread errno if applicable. This has no meaning in ld.so.1 which 3441 * is basically singled threaded. Provide the interface for our dependencies. 3442 */ 3443 #undef errno 3444 #pragma weak _private___errno = ___errno 3445 int * 3446 ___errno() 3447 { 3448 extern int errno; 3449 3450 return (&errno); 3451 } 3452 3453 /* 3454 * The interface with the c library which is supplied through libdl.so.1. 3455 * A non-null argument allows a function pointer array to be passed to us which 3456 * is used to re-initialize the linker libc table. 3457 */ 3458 void 3459 _ld_libc(void * ptr) 3460 { 3461 get_lcinterface(_caller(caller(), CL_EXECDEF), (Lc_interface *)ptr); 3462 } 3463 3464 /* 3465 * Determine whether a symbol name should be demangled. 3466 */ 3467 const char * 3468 demangle(const char *name) 3469 { 3470 if (rtld_flags & RT_FL_DEMANGLE) 3471 return (conv_demangle_name(name)); 3472 else 3473 return (name); 3474 } 3475