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 2008 Sun Microsystems, Inc. All rights reserved. 27 * Use is subject to license terms. 28 */ 29 #pragma ident "%Z%%M% %I% %E% SMI" 30 31 #include "_synonyms.h" 32 33 #include <string.h> 34 #include <stdio.h> 35 #include <unistd.h> 36 #include <sys/stat.h> 37 #include <sys/mman.h> 38 #include <fcntl.h> 39 #include <limits.h> 40 #include <dlfcn.h> 41 #include <errno.h> 42 #include <link.h> 43 #include <debug.h> 44 #include <conv.h> 45 #include "_rtld.h" 46 #include "_audit.h" 47 #include "_elf.h" 48 #include "msg.h" 49 50 static Fct *vector[] = { 51 &elf_fct, 52 #ifdef A_OUT 53 &aout_fct, 54 #endif 55 0 56 }; 57 58 /* 59 * If a load filter flag is in effect, and this object is a filter, trigger the 60 * loading of all its filtees. The load filter flag is in effect when creating 61 * configuration files, or when under the control of ldd(1), or the LD_LOADFLTR 62 * environment variable is set, or this object was built with the -zloadfltr 63 * flag. Otherwise, filtee loading is deferred until triggered by a relocation. 64 */ 65 static void 66 load_filtees(Rt_map *lmp, int *in_nfavl) 67 { 68 if ((FLAGS1(lmp) & MSK_RT_FILTER) && 69 ((FLAGS(lmp) & FLG_RT_LOADFLTR) || 70 (LIST(lmp)->lm_tflags & LML_TFLG_LOADFLTR))) { 71 Dyninfo *dip = DYNINFO(lmp); 72 uint_t cnt, max = DYNINFOCNT(lmp); 73 Slookup sl; 74 75 /* 76 * Initialize the symbol lookup data structure. 77 */ 78 SLOOKUP_INIT(sl, 0, lmp, lmp, ld_entry_cnt, 0, 0, 0, 0, 0); 79 80 for (cnt = 0; cnt < max; cnt++, dip++) { 81 if (((dip->di_flags & MSK_DI_FILTER) == 0) || 82 ((dip->di_flags & FLG_DI_AUXFLTR) && 83 (rtld_flags & RT_FL_NOAUXFLTR))) 84 continue; 85 (void) elf_lookup_filtee(&sl, 0, 0, cnt, in_nfavl); 86 } 87 } 88 } 89 90 /* 91 * Analyze one or more link-maps of a link map control list. This routine is 92 * called at startup to continue the processing of the main executable. It is 93 * also called each time a new set of objects are loaded, ie. from filters, 94 * lazy-loaded objects, or dlopen(). 95 * 96 * In each instance we traverse the link-map control list starting with the 97 * initial object. As dependencies are analyzed they are added to the link-map 98 * control list. Thus the list grows as we traverse it - this results in the 99 * breadth first ordering of all needed objects. 100 */ 101 int 102 analyze_lmc(Lm_list *lml, Aliste nlmco, Rt_map *nlmp, int *in_nfavl) 103 { 104 Rt_map *lmp = nlmp; 105 Lm_cntl *nlmc; 106 int ret = 1; 107 108 /* 109 * If this link-map control list is being analyzed, return. The object 110 * that has just been added will be picked up by the existing analysis 111 * thread. Note, this is only really meaningful during process init- 112 * ialization, as objects are added to the main link-map control list. 113 * Following this initialization, each family of objects that are loaded 114 * are added to a new link-map control list. 115 */ 116 /* LINTED */ 117 nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco); 118 if (nlmc->lc_flags & LMC_FLG_ANALYZING) 119 return (1); 120 121 /* 122 * If this object doesn't belong to the present link-map control list 123 * then it must already have been analyzed, or it is in the process of 124 * being analyzed prior to us recursing into this analysis. In either 125 * case, ignore the object as it's already being taken care of. 126 */ 127 if (nlmco != CNTL(nlmp)) 128 return (1); 129 130 nlmc->lc_flags |= LMC_FLG_ANALYZING; 131 132 for (; lmp; lmp = (Rt_map *)NEXT(lmp)) { 133 if (FLAGS(lmp) & 134 (FLG_RT_ANALZING | FLG_RT_ANALYZED | FLG_RT_DELETE)) 135 continue; 136 137 /* 138 * Indicate that analyzing is under way. 139 */ 140 FLAGS(lmp) |= FLG_RT_ANALZING; 141 142 /* 143 * If this link map represents a relocatable object, then we 144 * need to finish the link-editing of the object at this point. 145 */ 146 if (FLAGS(lmp) & FLG_RT_OBJECT) { 147 if (elf_obj_fini(lml, lmp, in_nfavl) == 0) { 148 if (lml->lm_flags & LML_FLG_TRC_ENABLE) 149 continue; 150 ret = 0; 151 break; 152 } 153 } 154 155 DBG_CALL(Dbg_file_analyze(lmp)); 156 157 /* 158 * Establish any dependencies this object requires. 159 */ 160 if (LM_NEEDED(lmp)(lml, nlmco, lmp, in_nfavl) == 0) { 161 if (lml->lm_flags & LML_FLG_TRC_ENABLE) 162 continue; 163 ret = 0; 164 break; 165 } 166 167 FLAGS(lmp) &= ~FLG_RT_ANALZING; 168 FLAGS(lmp) |= FLG_RT_ANALYZED; 169 170 /* 171 * If we're building a configuration file, determine if this 172 * object is a filter and if so load its filtees. This 173 * traversal is only necessary for crle(1), as typical use of 174 * an object will load filters as part of relocation processing. 175 */ 176 if (MODE(nlmp) & RTLD_CONFGEN) 177 load_filtees(lmp, in_nfavl); 178 179 /* 180 * If an interposer has been added, it will have been inserted 181 * in the link-map before the link we're presently analyzing. 182 * Break out of this analysis loop and return to the head of 183 * the link-map control list to analyze the interposer. Note 184 * that this rescan preserves the breadth first loading of 185 * dependencies. 186 */ 187 /* LINTED */ 188 nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco); 189 if (nlmc->lc_flags & LMC_FLG_REANALYZE) { 190 nlmc->lc_flags &= ~LMC_FLG_REANALYZE; 191 lmp = nlmc->lc_head; 192 } 193 } 194 195 /* LINTED */ 196 nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco); 197 nlmc->lc_flags &= ~LMC_FLG_ANALYZING; 198 199 return (ret); 200 } 201 202 /* 203 * Determine whether a symbol represents zero, .bss, bits. Most commonly this 204 * function is used to determine whether the data for a copy relocation refers 205 * to initialized data or .bss. If the data definition is within .bss, then the 206 * data is zero filled, and as the copy destination within the executable is 207 * .bss, we can skip copying zero's to zero's. 208 * 209 * However, if the defining object has MOVE data, it's .bss might contain 210 * non-zero data, in which case copy the definition regardless. 211 * 212 * For backward compatibility copy relocation processing, this routine can be 213 * used to determine precisely if a copy destination is a move record recipient. 214 */ 215 static int 216 are_bits_zero(Rt_map *dlmp, Sym *dsym, int dest) 217 { 218 Mmap *mmap = NULL, *mmaps; 219 caddr_t daddr = (caddr_t)dsym->st_value; 220 221 if ((FLAGS(dlmp) & FLG_RT_FIXED) == 0) 222 daddr += ADDR(dlmp); 223 224 /* 225 * Determine the segment that contains the copy definition. Given that 226 * the copy relocation records have already been captured and verified, 227 * a segment must be found (but we add an escape clause never the less). 228 */ 229 for (mmaps = MMAPS(dlmp); mmaps->m_vaddr; mmaps++) { 230 if ((daddr >= mmaps->m_vaddr) && 231 (daddr < (mmaps->m_vaddr + mmaps->m_msize))) { 232 mmap = mmaps; 233 break; 234 } 235 } 236 if (mmap == NULL) 237 return (1); 238 239 /* 240 * If the definition is not within .bss, indicate this is not zero data. 241 */ 242 if (daddr < (mmap->m_vaddr + mmaps->m_fsize)) 243 return (0); 244 245 /* 246 * If the definition is within .bss, make sure the definition isn't the 247 * recipient of a move record. Note, we don't precisely analyze whether 248 * the address is a move record recipient, as the infrastructure to 249 * prepare for, and carry out this analysis, is probably more costly 250 * than just copying the bytes regardless. 251 */ 252 if ((FLAGS(dlmp) & FLG_RT_MOVE) == 0) 253 return (1); 254 255 /* 256 * However, for backward compatibility copy relocation processing, we 257 * can afford to work a little harder. Here, determine precisely 258 * whether the destination in the executable is a move record recipient. 259 * See comments in lookup_sym_interpose(), below. 260 */ 261 if (dest && is_move_data(daddr)) 262 return (0); 263 264 return (1); 265 } 266 267 /* 268 * Relocate an individual object. 269 */ 270 static int 271 relocate_so(Lm_list *lml, Rt_map *lmp, int *relocated, int now, int *in_nfavl) 272 { 273 /* 274 * If we're running under ldd(1), and haven't been asked to trace any 275 * warnings, skip any actual relocation processing. 276 */ 277 if (((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0) || 278 (lml->lm_flags & LML_FLG_TRC_WARN)) { 279 280 if (relocated) 281 (*relocated)++; 282 283 if ((LM_RELOC(lmp)(lmp, now, in_nfavl) == 0) && 284 ((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0)) 285 return (0); 286 } 287 return (1); 288 } 289 290 /* 291 * Relocate the objects on a link-map control list. 292 */ 293 static int 294 _relocate_lmc(Lm_list *lml, Rt_map *nlmp, int *relocated, int *in_nfavl) 295 { 296 Rt_map *lmp; 297 298 for (lmp = nlmp; lmp; lmp = (Rt_map *)NEXT(lmp)) { 299 /* 300 * If this object has already been relocated, we're done. If 301 * this object is being deleted, skip it, there's probably a 302 * relocation error somewhere that's causing this deletion. 303 */ 304 if (FLAGS(lmp) & 305 (FLG_RT_RELOCING | FLG_RT_RELOCED | FLG_RT_DELETE)) 306 continue; 307 308 /* 309 * Indicate that relocation processing is under way. 310 */ 311 FLAGS(lmp) |= FLG_RT_RELOCING; 312 313 /* 314 * Relocate the object. 315 */ 316 if (relocate_so(lml, lmp, relocated, 0, in_nfavl) == 0) 317 return (0); 318 319 /* 320 * Indicate that the objects relocation is complete. 321 */ 322 FLAGS(lmp) &= ~FLG_RT_RELOCING; 323 FLAGS(lmp) |= FLG_RT_RELOCED; 324 325 /* 326 * Mark this object's init is available for harvesting. Under 327 * ldd(1) this marking is necessary for -i (tsort) gathering. 328 */ 329 lml->lm_init++; 330 lml->lm_flags |= LML_FLG_OBJADDED; 331 332 /* 333 * Process any move data. Note, this is carried out under ldd 334 * under relocation processing too, as it can flush out move 335 * errors, and enables lari(1) to provide a true representation 336 * of the runtime bindings. 337 */ 338 if ((FLAGS(lmp) & FLG_RT_MOVE) && 339 (((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0) || 340 (lml->lm_flags & LML_FLG_TRC_WARN))) { 341 if (move_data(lmp) == 0) 342 return (0); 343 } 344 345 /* 346 * Determine if this object is a filter, and if a load filter 347 * flag is in effect, trigger the loading of all its filtees. 348 */ 349 load_filtees(lmp, in_nfavl); 350 } 351 352 /* 353 * Perform special copy relocations. These are only meaningful for 354 * dynamic executables (fixed and head of their link-map list). If 355 * this ever has to change then the infrastructure of COPY() has to 356 * change. Presently, a given link map can only have a receiver or 357 * supplier of copy data, so a union is used to overlap the storage 358 * for the COPY_R() and COPY_S() lists. These lists would need to 359 * be separated. 360 */ 361 if ((FLAGS(nlmp) & FLG_RT_FIXED) && (nlmp == LIST(nlmp)->lm_head) && 362 (((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0) || 363 (lml->lm_flags & LML_FLG_TRC_WARN))) { 364 Rt_map *lmp; 365 Aliste idx1; 366 Word tracing; 367 368 #if defined(__i386) 369 if (elf_copy_gen(nlmp) == 0) 370 return (0); 371 #endif 372 if (COPY_S(nlmp) == NULL) 373 return (1); 374 375 if ((LIST(nlmp)->lm_flags & LML_FLG_TRC_ENABLE) && 376 (((rtld_flags & RT_FL_SILENCERR) == 0) || 377 (LIST(nlmp)->lm_flags & LML_FLG_TRC_VERBOSE))) 378 tracing = 1; 379 else 380 tracing = 0; 381 382 DBG_CALL(Dbg_util_nl(lml, DBG_NL_STD)); 383 384 for (APLIST_TRAVERSE(COPY_S(nlmp), idx1, lmp)) { 385 Rel_copy *rcp; 386 Aliste idx2; 387 388 for (ALIST_TRAVERSE(COPY_R(lmp), idx2, rcp)) { 389 int zero; 390 391 /* 392 * Only copy the data if the data is from 393 * a non-zero definition (ie. not .bss). 394 */ 395 zero = are_bits_zero(rcp->r_dlmp, 396 rcp->r_dsym, 0); 397 DBG_CALL(Dbg_reloc_copy(rcp->r_dlmp, nlmp, 398 rcp->r_name, zero)); 399 if (zero) 400 continue; 401 402 (void) memcpy(rcp->r_radd, rcp->r_dadd, 403 rcp->r_size); 404 405 if ((tracing == 0) || ((FLAGS1(rcp->r_dlmp) & 406 FL1_RT_DISPREL) == 0)) 407 continue; 408 409 (void) printf(MSG_INTL(MSG_LDD_REL_CPYDISP), 410 demangle(rcp->r_name), NAME(rcp->r_dlmp)); 411 } 412 } 413 414 DBG_CALL(Dbg_util_nl(lml, DBG_NL_STD)); 415 416 free(COPY_S(nlmp)); 417 COPY_S(nlmp) = 0; 418 } 419 return (1); 420 } 421 422 int 423 relocate_lmc(Lm_list *lml, Aliste nlmco, Rt_map *clmp, Rt_map *nlmp, 424 int *in_nfavl) 425 { 426 int lret = 1, pret = 1; 427 APlist *alp; 428 Aliste plmco; 429 Lm_cntl *plmc, *nlmc; 430 431 /* 432 * If this link-map control list is being relocated, return. The object 433 * that has just been added will be picked up by the existing relocation 434 * thread. Note, this is only really meaningful during process init- 435 * ialization, as objects are added to the main link-map control list. 436 * Following this initialization, each family of objects that are loaded 437 * are added to a new link-map control list. 438 */ 439 /* LINTED */ 440 nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco); 441 442 if (nlmc->lc_flags & LMC_FLG_RELOCATING) 443 return (1); 444 445 nlmc->lc_flags |= LMC_FLG_RELOCATING; 446 447 /* 448 * Relocate one or more link-maps of a link map control list. If this 449 * object doesn't belong to the present link-map control list then it 450 * must already have been relocated, or it is in the process of being 451 * relocated prior to us recursing into this relocation. In either 452 * case, ignore the object as it's already being taken care of, however, 453 * fall through and capture any relocation promotions that might have 454 * been established from the reference mode of this object. 455 * 456 * If we're generating a configuration file using crle(1), two passes 457 * may be involved. Under the first pass, RTLD_CONFGEN is set. Under 458 * this pass, crle() loads objects into the process address space. No 459 * relocation is necessary at this point, we simply need to analyze the 460 * objects to insure any directly bound dependencies, filtees, etc. 461 * get loaded. Although we skip the relocation, fall through to insure 462 * any control lists are maintained appropriately. 463 * 464 * If objects are to be dldump(3c)'ed, crle(1) makes a second pass, 465 * using RTLD_NOW and RTLD_CONFGEN. The RTLD_NOW effectively carries 466 * out the relocations of all loaded objects. 467 */ 468 if ((nlmco == CNTL(nlmp)) && 469 ((MODE(nlmp) & (RTLD_NOW | RTLD_CONFGEN)) != RTLD_CONFGEN)) { 470 int relocated = 0; 471 472 /* 473 * Determine whether the initial link-map control list has 474 * started relocation. From this point, should any interposing 475 * objects be added to this link-map control list, the objects 476 * are demoted to standard objects. Their interposition can't 477 * be guaranteed once relocations have been carried out. 478 */ 479 if (nlmco == ALIST_OFF_DATA) 480 lml->lm_flags |= LML_FLG_STARTREL; 481 482 /* 483 * Relocate the link-map control list. Should this relocation 484 * fail, clean up this link-map list. Relocations within this 485 * list may have required relocation promotions on other lists, 486 * so before acting upon these, and possibly adding more objects 487 * to the present link-map control list, try and clean up any 488 * failed objects now. 489 */ 490 lret = _relocate_lmc(lml, nlmp, &relocated, in_nfavl); 491 if ((lret == 0) && (nlmco != ALIST_OFF_DATA)) 492 remove_lmc(lml, clmp, nlmc, nlmco, NAME(nlmp)); 493 } 494 495 /* 496 * Determine the new, and previous link-map control lists. 497 */ 498 /* LINTED */ 499 nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco); 500 if (nlmco == ALIST_OFF_DATA) { 501 plmco = nlmco; 502 plmc = nlmc; 503 } else { 504 plmco = nlmco - lml->lm_lists->al_size; 505 /* LINTED */ 506 plmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, plmco); 507 } 508 509 /* 510 * Having completed this control list of objects, they can now be bound 511 * to from other objects. Move this control list to the control list 512 * that precedes it. Although this control list may have only bound to 513 * controls lists much higher up the control list stack, it must only 514 * be moved up one control list so as to preserve the link-map order 515 * that may have already been traversed in search of symbols. 516 */ 517 if (lret && (nlmco != ALIST_OFF_DATA) && nlmc->lc_head) 518 lm_move(lml, nlmco, plmco, nlmc, plmc); 519 520 /* 521 * Determine whether existing objects that have already been relocated, 522 * need any additional relocations performed. This can occur when new 523 * objects are loaded with RTLD_NOW, and these new objects have 524 * dependencies on objects that are already loaded. Note, that we peel 525 * any relocation promotions off of one control list at a time. This 526 * prevents relocations from being bound to objects that might yet fail 527 * to relocate themselves. 528 */ 529 while ((alp = plmc->lc_now) != NULL) { 530 Aliste idx; 531 Rt_map *lmp; 532 533 /* 534 * Remove the relocation promotion list, as performing more 535 * relocations may result in discovering more objects that need 536 * promotion. 537 */ 538 plmc->lc_now = NULL; 539 540 for (APLIST_TRAVERSE(alp, idx, lmp)) { 541 /* 542 * If the original relocation of the link-map control 543 * list failed, or one of the relocation promotions of 544 * this loop has failed, demote any pending objects 545 * relocation mode. 546 */ 547 if ((lret == 0) || (pret == 0)) { 548 MODE(lmp) &= ~RTLD_NOW; 549 MODE(lmp) |= RTLD_LAZY; 550 continue; 551 } 552 553 /* 554 * If a relocation fails, save the error condition. 555 * It's possible that all new objects on the original 556 * link-map control list have been relocated 557 * successfully, but if the user request requires 558 * promoting objects that have already been loaded, we 559 * have to indicate that this operation couldn't be 560 * performed. The unrelocated objects are in use on 561 * another control list, and may continue to be used. 562 * If the .plt that resulted in the error is called, 563 * then the process will receive a fatal error at that 564 * time. But, the .plt may never be called. 565 */ 566 if (relocate_so(lml, lmp, 0, 1, in_nfavl) == 0) 567 pret = 0; 568 } 569 570 /* 571 * Having promoted any objects, determine whether additional 572 * dependencies were added, and if so move them to the previous 573 * link-map control list. 574 */ 575 /* LINTED */ 576 nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco); 577 /* LINTED */ 578 plmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, plmco); 579 if ((nlmco != ALIST_OFF_DATA) && nlmc->lc_head) 580 lm_move(lml, nlmco, plmco, nlmc, plmc); 581 free(alp); 582 } 583 584 /* 585 * If relocations have been successful, indicate that relocations are 586 * no longer active for this control list. Otherwise, leave the 587 * relocation flag, as this flag is used to determine the style of 588 * cleanup (see remove_lmc()). 589 */ 590 if (lret && pret) { 591 /* LINTED */ 592 nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco); 593 nlmc->lc_flags &= ~LMC_FLG_RELOCATING; 594 595 return (1); 596 } 597 598 return (0); 599 } 600 601 /* 602 * Inherit the first rejection message for possible later diagnostics. 603 * 604 * Any attempt to process a file that is unsuccessful, should be accompanied 605 * with an error diagnostic. However, some operations like searching for a 606 * simple filename, involve trying numerous paths, and an error message for each 607 * lookup is not required. Although a multiple search can fail, it's possible 608 * that a file was found, but was rejected because it was the wrong type. 609 * To satisfy these possibilities, the first failure is recorded as a rejection 610 * message, and this message is used later for a more specific diagnostic. 611 * 612 * File searches are focused at load_one(), and from here a rejection descriptor 613 * is passed down to various child routines. If these child routines can 614 * process multiple files, then they will maintain their own rejection desc- 615 * riptor. This is filled in for any failures, and a diagnostic produced to 616 * reflect the failure. The child routines then employ rejection_inherit() to 617 * pass the first rejection message back to load_one(). 618 * 619 * Note that the name, and rejection string must be duplicated, as the name 620 * buffer and error string buffer (see conv_ routines) may be reused for 621 * additional processing or rejection messages. 622 */ 623 void 624 rejection_inherit(Rej_desc *rej1, Rej_desc *rej2) 625 { 626 if (rej2->rej_type && (rej1->rej_type == 0)) { 627 rej1->rej_type = rej2->rej_type; 628 rej1->rej_info = rej2->rej_info; 629 rej1->rej_flag = rej2->rej_flag; 630 if (rej2->rej_name) 631 rej1->rej_name = strdup(rej2->rej_name); 632 if (rej2->rej_str) { 633 if ((rej1->rej_str = strdup(rej2->rej_str)) == NULL) 634 rej1->rej_str = MSG_ORIG(MSG_EMG_ENOMEM); 635 } 636 } 637 } 638 639 /* 640 * Determine the object type of a file. 641 */ 642 Fct * 643 are_u_this(Rej_desc *rej, int fd, struct stat *status, const char *name) 644 { 645 int i; 646 char *maddr = 0; 647 648 fmap->fm_fsize = status->st_size; 649 650 /* 651 * If this is a directory (which can't be mmap()'ed) generate a precise 652 * error message. 653 */ 654 if ((status->st_mode & S_IFMT) == S_IFDIR) { 655 rej->rej_type = SGS_REJ_STR; 656 rej->rej_str = strerror(EISDIR); 657 return (0); 658 } 659 660 /* 661 * Map in the first page of the file. When this buffer is first used, 662 * the mapping is a single system page. This is typically enough to 663 * inspect the ehdr and phdrs of the file, and can be reused for each 664 * file that get loaded. If a larger mapping is required to read the 665 * ehdr and phdrs, a new mapping is created (see elf_map_it()). This 666 * new mapping is again used for each new file loaded. Some objects, 667 * such as filters, only take up one page, and in this case this mapping 668 * will suffice for the file. 669 */ 670 maddr = mmap(fmap->fm_maddr, fmap->fm_msize, (PROT_READ | PROT_EXEC), 671 fmap->fm_mflags, fd, 0); 672 #if defined(MAP_ALIGN) 673 if ((maddr == MAP_FAILED) && (errno == EINVAL)) { 674 /* 675 * If the mapping failed, and we used MAP_ALIGN, assume we're 676 * on a system that doesn't support this option. Try again 677 * without MAP_ALIGN. 678 */ 679 if (fmap->fm_mflags & MAP_ALIGN) { 680 rtld_flags2 |= RT_FL2_NOMALIGN; 681 fmap_setup(); 682 683 maddr = (char *)mmap(fmap->fm_maddr, fmap->fm_msize, 684 (PROT_READ | PROT_EXEC), fmap->fm_mflags, fd, 0); 685 } 686 } 687 #endif 688 if (maddr == MAP_FAILED) { 689 rej->rej_type = SGS_REJ_STR; 690 rej->rej_str = strerror(errno); 691 return (0); 692 } 693 694 /* 695 * From now on we will re-use fmap->fm_maddr as the mapping address 696 * so we augment the flags with MAP_FIXED and drop any MAP_ALIGN. 697 */ 698 fmap->fm_maddr = maddr; 699 fmap->fm_mflags |= MAP_FIXED; 700 #if defined(MAP_ALIGN) 701 fmap->fm_mflags &= ~MAP_ALIGN; 702 #endif 703 704 /* 705 * Search through the object vectors to determine what kind of 706 * object we have. 707 */ 708 for (i = 0; vector[i]; i++) { 709 if ((vector[i]->fct_are_u_this)(rej)) 710 return (vector[i]); 711 else if (rej->rej_type) { 712 Rt_map *lmp; 713 714 /* 715 * If this object is an explicitly defined shared 716 * object under inspection by ldd, and contains a 717 * incompatible hardware capabilities requirement, then 718 * inform the user, but continue processing. 719 * 720 * XXXX - ldd -v for any rej failure. 721 */ 722 if ((rej->rej_type == SGS_REJ_HWCAP_1) && 723 (lml_main.lm_flags & LML_FLG_TRC_LDDSTUB) && 724 ((lmp = lml_main.lm_head) != 0) && 725 (FLAGS1(lmp) & FL1_RT_LDDSTUB) && 726 (NEXT(lmp) == 0)) { 727 (void) printf(MSG_INTL(MSG_LDD_GEN_HWCAP_1), 728 name, rej->rej_str); 729 return (vector[i]); 730 } 731 return (0); 732 } 733 } 734 735 /* 736 * Unknown file type. 737 */ 738 rej->rej_type = SGS_REJ_UNKFILE; 739 return (0); 740 } 741 742 /* 743 * Helper routine for is_so_matched() that consolidates matching a path name, 744 * or file name component of a link-map name. 745 */ 746 static int 747 _is_so_matched(const char *name, const char *str, int path) 748 { 749 const char *_str; 750 751 if ((path == 0) && ((_str = strrchr(str, '/')) != NULL)) 752 _str++; 753 else 754 _str = str; 755 756 return (strcmp(name, _str)); 757 } 758 759 /* 760 * Determine whether a search name matches one of the names associated with a 761 * link-map. A link-map contains several names: 762 * 763 * . a NAME() - typically the full pathname of an object that has been 764 * loaded. For example, when looking for the dependency "libc.so.1", a 765 * search path is applied, with the eventual NAME() being "/lib/ld.so.1". 766 * The name of the executable is typically a simple filename, such as 767 * "main", as this is the name passed to exec() to start the process. 768 * 769 * . a PATHNAME() - this is maintained if the resolved NAME() is different 770 * to NAME(), ie. the original name is a symbolic link. This is also 771 * the resolved full pathname for a dynamic executable. 772 * 773 * . a list of ALIAS() names - these are alternative names by which the 774 * object has been found, ie. when dependencies are loaded through a 775 * variety of different symbolic links. 776 * 777 * The name pattern matching can differ depending on whether we are looking 778 * for a full path name (path != 0), or a simple file name (path == 0). Full 779 * path names typically match NAME() or PATHNAME() entries, so these link-map 780 * names are inspected first when a full path name is being searched for. 781 * Simple file names typically match ALIAS() names, so these link-map names are 782 * inspected first when a simple file name is being searched for. 783 * 784 * For all full path name searches, the link-map names are taken as is. For 785 * simple file name searches, only the file name component of any link-map 786 * names are used for comparison. 787 */ 788 static Rt_map * 789 is_so_matched(Rt_map *lmp, const char *name, int path) 790 { 791 Aliste idx; 792 const char *cp; 793 794 /* 795 * A pathname is typically going to match a NAME() or PATHNAME(), so 796 * check these first. 797 */ 798 if (path) { 799 if (strcmp(name, NAME(lmp)) == 0) 800 return (lmp); 801 802 if (PATHNAME(lmp) != NAME(lmp)) { 803 if (strcmp(name, PATHNAME(lmp)) == 0) 804 return (lmp); 805 } 806 } 807 808 /* 809 * Typically, dependencies are specified as simple file names 810 * (DT_NEEDED == libc.so.1), which are expanded to full pathnames to 811 * open the file. The full pathname is NAME(), and the original name 812 * is maintained on the ALIAS() list. 813 * 814 * If this is a simple filename, or a pathname has failed to match the 815 * NAME() and PATHNAME() check above, look through the ALIAS() list. 816 */ 817 for (APLIST_TRAVERSE(ALIAS(lmp), idx, cp)) { 818 /* 819 * If we're looking for a simple filename, _is_so_matched() 820 * will reduce the ALIAS name to its simple name. 821 */ 822 if (_is_so_matched(name, cp, path) == 0) 823 return (lmp); 824 } 825 826 /* 827 * Finally, if this is a simple file name, and any ALIAS() search has 828 * been completed, match the simple file name of NAME() and PATHNAME(). 829 */ 830 if (path == 0) { 831 if (_is_so_matched(name, NAME(lmp), 0) == 0) 832 return (lmp); 833 834 if (PATHNAME(lmp) != NAME(lmp)) { 835 if (_is_so_matched(name, PATHNAME(lmp), 0) == 0) 836 return (lmp); 837 } 838 } 839 840 return (0); 841 } 842 843 /* 844 * Files are opened by ld.so.1 to satisfy dependencies, filtees and dlopen() 845 * requests. Each request investigates the file based upon the callers 846 * environment. Once a full path name has been established, the following 847 * checks are made: 848 * 849 * . does the path exist in the link-map lists FullPathNode AVL tree? if 850 * so, the file is already loaded, and its associated link-map pointer 851 * is returned. 852 * . does the path exist in the not-found AVL tree? if so, this path has 853 * already been determined to not exist, and a failure is returned. 854 * . a device/inode check, to ensure the same file isn't mapped multiple 855 * times through different paths. See file_open(). 856 * 857 * However, there are cases where a test for an existing file name needs to be 858 * carried out, such as dlopen(NOLOAD) requests, dldump() requests, and as a 859 * final fallback to dependency loading. These requests are handled by 860 * is_so_loaded(). 861 * 862 * A traversal through the callers link-map list is carried out, and from each 863 * link-map, a comparison is made against all of the various names by which the 864 * object has been referenced. is_so_matched() is used to compares the link-map 865 * names against the name being searched for. Whether the search name is a full 866 * path name or a simple file name, governs what comparisons are made. 867 * 868 * A full path name, which is a fully resolved path name that starts with a "/" 869 * character, or a relative path name that includes a "/" character, must match 870 * the link-map names explicitly. A simple file name, which is any name *not* 871 * containing a "/" character, are matched against the file name component of 872 * any link-map names. 873 */ 874 Rt_map * 875 is_so_loaded(Lm_list *lml, const char *name, int *in_nfavl) 876 { 877 Rt_map *lmp; 878 avl_index_t where; 879 Lm_cntl *lmc; 880 Aliste idx; 881 int path = 0; 882 883 /* 884 * If the name is a full path name, first determine if the path name is 885 * registered on the FullPathNode AVL, or not-found AVL trees. 886 */ 887 if (name[0] == '/') { 888 if (((lmp = fpavl_recorded(lml, name, &where)) != NULL) && 889 ((FLAGS(lmp) & (FLG_RT_OBJECT | FLG_RT_DELETE)) == 0)) 890 return (lmp); 891 if (nfavl_recorded(name, 0)) { 892 /* 893 * For dlopen() and dlsym() fall backs, indicate that 894 * a registered not-found path has indicated that this 895 * object does not exist. 896 */ 897 if (in_nfavl) 898 (*in_nfavl)++; 899 return (0); 900 } 901 } 902 903 /* 904 * Determine whether the name is a simple file name, or a path name. 905 */ 906 if (strchr(name, '/')) 907 path++; 908 909 /* 910 * Loop through the callers link-map lists. 911 */ 912 for (ALIST_TRAVERSE(lml->lm_lists, idx, lmc)) { 913 for (lmp = lmc->lc_head; lmp; lmp = (Rt_map *)NEXT(lmp)) { 914 if (FLAGS(lmp) & (FLG_RT_OBJECT | FLG_RT_DELETE)) 915 continue; 916 917 if (is_so_matched(lmp, name, path)) 918 return (lmp); 919 } 920 } 921 return ((Rt_map *)0); 922 } 923 924 /* 925 * Tracing is enabled by the LD_TRACE_LOADED_OPTIONS environment variable which 926 * is normally set from ldd(1). For each link map we load, print the load name 927 * and the full pathname of the shared object. 928 */ 929 /* ARGSUSED4 */ 930 static void 931 trace_so(Rt_map *clmp, Rej_desc *rej, const char *name, const char *path, 932 int alter, const char *nfound) 933 { 934 const char *str = MSG_ORIG(MSG_STR_EMPTY); 935 const char *reject = MSG_ORIG(MSG_STR_EMPTY); 936 char _reject[PATH_MAX]; 937 938 /* 939 * The first time through trace_so() will only have lddstub on the 940 * link-map list and the preloaded shared object is supplied as "path". 941 * As we don't want to print this shared object as a dependency, but 942 * instead inspect *its* dependencies, return. 943 */ 944 if (FLAGS1(clmp) & FL1_RT_LDDSTUB) 945 return; 946 947 /* 948 * Without any rejection info, this is a supplied not-found condition. 949 */ 950 if (rej && (rej->rej_type == 0)) { 951 (void) printf(nfound, name); 952 return; 953 } 954 955 /* 956 * If rejection information exists then establish what object was 957 * found and the reason for its rejection. 958 */ 959 if (rej) { 960 Conv_reject_desc_buf_t rej_buf; 961 962 /* LINTED */ 963 (void) snprintf(_reject, PATH_MAX, 964 MSG_INTL(ldd_reject[rej->rej_type]), 965 conv_reject_desc(rej, &rej_buf, M_MACH)); 966 if (rej->rej_name) 967 path = rej->rej_name; 968 reject = (char *)_reject; 969 970 /* 971 * Was an alternative pathname defined (from a configuration 972 * file). 973 */ 974 if (rej->rej_flag & FLG_FD_ALTER) 975 str = MSG_INTL(MSG_LDD_FIL_ALTER); 976 } else { 977 if (alter) 978 str = MSG_INTL(MSG_LDD_FIL_ALTER); 979 } 980 981 /* 982 * If the load name isn't a full pathname print its associated pathname 983 * together with all the other information we've gathered. 984 */ 985 if (*name == '/') 986 (void) printf(MSG_ORIG(MSG_LDD_FIL_PATH), path, str, reject); 987 else 988 (void) printf(MSG_ORIG(MSG_LDD_FIL_EQUIV), name, path, str, 989 reject); 990 } 991 992 993 /* 994 * Establish a link-map mode, initializing it if it has just been loaded, or 995 * potentially updating it if it already exists. 996 */ 997 int 998 update_mode(Rt_map *lmp, int omode, int nmode) 999 { 1000 Lm_list *lml = LIST(lmp); 1001 int pmode = 0; 1002 1003 /* 1004 * A newly loaded object hasn't had its mode set yet. Modes are used to 1005 * load dependencies, so don't propagate any parent or no-load flags, as 1006 * these would adversely affect this objects ability to load any of its 1007 * dependencies that aren't already loaded. RTLD_FIRST is applicable to 1008 * this objects handle creation only, and should not be propagated. 1009 */ 1010 if ((FLAGS(lmp) & FLG_RT_MODESET) == 0) { 1011 MODE(lmp) |= nmode & ~(RTLD_PARENT | RTLD_NOLOAD | RTLD_FIRST); 1012 FLAGS(lmp) |= FLG_RT_MODESET; 1013 return (1); 1014 } 1015 1016 /* 1017 * Establish any new overriding modes. RTLD_LAZY and RTLD_NOW should be 1018 * represented individually (this is historic, as these two flags were 1019 * the only flags originally available to dlopen()). Other flags are 1020 * accumulative, but have a hierarchy of preference. 1021 */ 1022 if ((omode & RTLD_LAZY) && (nmode & RTLD_NOW)) { 1023 MODE(lmp) &= ~RTLD_LAZY; 1024 pmode |= RTLD_NOW; 1025 } 1026 1027 pmode |= ((~omode & nmode) & 1028 (RTLD_GLOBAL | RTLD_WORLD | RTLD_NODELETE)); 1029 if (pmode) { 1030 DBG_CALL(Dbg_file_mode_promote(lmp, pmode)); 1031 MODE(lmp) |= pmode; 1032 } 1033 1034 /* 1035 * If this load is an RTLD_NOW request and the object has already been 1036 * loaded non-RTLD_NOW, append this object to the relocation-now list 1037 * of the objects associated control list. Note, if the object hasn't 1038 * yet been relocated, setting its MODE() to RTLD_NOW will establish 1039 * full relocation processing when it eventually gets relocated. 1040 */ 1041 if ((pmode & RTLD_NOW) && 1042 (FLAGS(lmp) & (FLG_RT_RELOCED | FLG_RT_RELOCING))) { 1043 Lm_cntl *lmc; 1044 1045 /* LINTED */ 1046 lmc = (Lm_cntl *)alist_item_by_offset(LIST(lmp)->lm_lists, 1047 CNTL(lmp)); 1048 (void) aplist_append(&lmc->lc_now, lmp, AL_CNT_LMNOW); 1049 } 1050 1051 #ifdef SIEBEL_DISABLE 1052 /* 1053 * For patch backward compatibility the following .init collection 1054 * is disabled. 1055 */ 1056 if (rtld_flags & RT_FL_DISFIX_1) 1057 return (pmode); 1058 #endif 1059 1060 /* 1061 * If this objects .init has been collected but has not yet been called, 1062 * it may be necessary to reevaluate the object using tsort(). For 1063 * example, a new dlopen() hierarchy may bind to uninitialized objects 1064 * that are already loaded, or a dlopen(RTLD_NOW) can establish new 1065 * bindings between already loaded objects that require the tsort() 1066 * information be recomputed. If however, no new objects have been 1067 * added to the process, and this object hasn't been promoted, don't 1068 * bother reevaluating the .init. The present tsort() information is 1069 * probably as accurate as necessary, and by not establishing a parallel 1070 * tsort() we can help reduce the amount of recursion possible between 1071 * .inits. 1072 */ 1073 if (((FLAGS(lmp) & 1074 (FLG_RT_INITCLCT | FLG_RT_INITCALL)) == FLG_RT_INITCLCT) && 1075 ((lml->lm_flags & LML_FLG_OBJADDED) || ((pmode & RTLD_NOW) && 1076 (FLAGS(lmp) & (FLG_RT_RELOCED | FLG_RT_RELOCING))))) { 1077 FLAGS(lmp) &= ~FLG_RT_INITCLCT; 1078 LIST(lmp)->lm_init++; 1079 LIST(lmp)->lm_flags |= LML_FLG_OBJREEVAL; 1080 } 1081 1082 return (pmode); 1083 } 1084 1085 /* 1086 * Determine whether an alias name already exists, and if not create one. This 1087 * is typically used to retain dependency names, such as "libc.so.1", which 1088 * would have been expanded to full path names when they were loaded. The 1089 * full path names (NAME() and possibly PATHNAME()) are maintained as Fullpath 1090 * AVL nodes, and thus would have been matched by fpavl_loaded() during 1091 * file_open(). 1092 */ 1093 int 1094 append_alias(Rt_map *lmp, const char *str, int *added) 1095 { 1096 Aliste idx; 1097 char *cp; 1098 1099 /* 1100 * Determine if this filename is already on the alias list. 1101 */ 1102 for (APLIST_TRAVERSE(ALIAS(lmp), idx, cp)) { 1103 if (strcmp(cp, str) == 0) 1104 return (1); 1105 } 1106 1107 /* 1108 * This is a new alias, append it to the alias list. 1109 */ 1110 if ((cp = strdup(str)) == NULL) 1111 return (0); 1112 1113 if (aplist_append(&ALIAS(lmp), cp, AL_CNT_ALIAS) == NULL) { 1114 free(cp); 1115 return (0); 1116 } 1117 if (added) 1118 *added = 1; 1119 return (1); 1120 } 1121 1122 /* 1123 * Determine whether a file is already loaded by comparing device and inode 1124 * values. 1125 */ 1126 static Rt_map * 1127 is_devinode_loaded(struct stat *status, Lm_list *lml, const char *name, 1128 uint_t flags) 1129 { 1130 Lm_cntl *lmc; 1131 Aliste idx; 1132 1133 /* 1134 * If this is an auditor, it will have been opened on a new link-map. 1135 * To prevent multiple occurrences of the same auditor on multiple 1136 * link-maps, search the head of each link-map list and see if this 1137 * object is already loaded as an auditor. 1138 */ 1139 if (flags & FLG_RT_AUDIT) { 1140 Lm_list *lml; 1141 Listnode *lnp; 1142 1143 for (LIST_TRAVERSE(&dynlm_list, lnp, lml)) { 1144 Rt_map *nlmp = lml->lm_head; 1145 1146 if (nlmp && ((FLAGS(nlmp) & 1147 (FLG_RT_AUDIT | FLG_RT_DELETE)) == FLG_RT_AUDIT) && 1148 (STDEV(nlmp) == status->st_dev) && 1149 (STINO(nlmp) == status->st_ino)) 1150 return (nlmp); 1151 } 1152 return ((Rt_map *)0); 1153 } 1154 1155 /* 1156 * If the file has been found determine from the new files status 1157 * information if this file is actually linked to one we already have 1158 * mapped. This catches symlink names not caught by is_so_loaded(). 1159 */ 1160 for (ALIST_TRAVERSE(lml->lm_lists, idx, lmc)) { 1161 Rt_map *nlmp; 1162 1163 for (nlmp = lmc->lc_head; nlmp; nlmp = (Rt_map *)NEXT(nlmp)) { 1164 if ((FLAGS(nlmp) & FLG_RT_DELETE) || 1165 (FLAGS1(nlmp) & FL1_RT_LDDSTUB)) 1166 continue; 1167 1168 if ((STDEV(nlmp) != status->st_dev) || 1169 (STINO(nlmp) != status->st_ino)) 1170 continue; 1171 1172 if (lml->lm_flags & LML_FLG_TRC_VERBOSE) { 1173 /* BEGIN CSTYLED */ 1174 if (*name == '/') 1175 (void) printf(MSG_ORIG(MSG_LDD_FIL_PATH), 1176 name, MSG_ORIG(MSG_STR_EMPTY), 1177 MSG_ORIG(MSG_STR_EMPTY)); 1178 else 1179 (void) printf(MSG_ORIG(MSG_LDD_FIL_EQUIV), 1180 name, NAME(nlmp), 1181 MSG_ORIG(MSG_STR_EMPTY), 1182 MSG_ORIG(MSG_STR_EMPTY)); 1183 /* END CSTYLED */ 1184 } 1185 return (nlmp); 1186 } 1187 } 1188 return ((Rt_map *)0); 1189 } 1190 1191 /* 1192 * Generate any error messages indicating a file could not be found. When 1193 * preloading or auditing a secure application, it can be a little more helpful 1194 * to indicate that a search of secure directories has failed, so adjust the 1195 * messages accordingly. 1196 */ 1197 void 1198 file_notfound(Lm_list *lml, const char *name, Rt_map *clmp, uint_t flags, 1199 Rej_desc * rej) 1200 { 1201 int secure = 0; 1202 1203 if ((rtld_flags & RT_FL_SECURE) && 1204 (flags & (FLG_RT_PRELOAD | FLG_RT_AUDIT))) 1205 secure++; 1206 1207 if (lml->lm_flags & LML_FLG_TRC_ENABLE) { 1208 /* 1209 * Under ldd(1), auxiliary filtees that can't be loaded are 1210 * ignored, unless verbose errors are requested. 1211 */ 1212 if ((rtld_flags & RT_FL_SILENCERR) && 1213 ((lml->lm_flags & LML_FLG_TRC_VERBOSE) == 0)) 1214 return; 1215 1216 if (secure) 1217 trace_so(clmp, rej, name, 0, 0, 1218 MSG_INTL(MSG_LDD_SEC_NFOUND)); 1219 else 1220 trace_so(clmp, rej, name, 0, 0, 1221 MSG_INTL(MSG_LDD_FIL_NFOUND)); 1222 return; 1223 } 1224 1225 if (rej->rej_type) { 1226 Conv_reject_desc_buf_t rej_buf; 1227 1228 eprintf(lml, ERR_FATAL, MSG_INTL(err_reject[rej->rej_type]), 1229 rej->rej_name ? rej->rej_name : MSG_INTL(MSG_STR_UNKNOWN), 1230 conv_reject_desc(rej, &rej_buf, M_MACH)); 1231 return; 1232 } 1233 1234 if (secure) 1235 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SEC_OPEN), name); 1236 else 1237 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), name, 1238 strerror(ENOENT)); 1239 } 1240 1241 static int 1242 file_open(int err, Lm_list *lml, const char *oname, const char *nname, 1243 Rt_map *clmp, uint_t flags, Fdesc *fdesc, Rej_desc *rej, int *in_nfavl) 1244 { 1245 struct stat status; 1246 Rt_map *nlmp; 1247 int resolved = 0; 1248 char *name; 1249 avl_index_t nfavlwhere = 0; 1250 1251 fdesc->fd_oname = oname; 1252 1253 if ((err == 0) && (fdesc->fd_flags & FLG_FD_ALTER)) 1254 DBG_CALL(Dbg_file_config_obj(lml, oname, 0, nname)); 1255 1256 /* 1257 * If we're dealing with a full pathname, determine whether this 1258 * pathname is already known. Other pathnames fall through to the 1259 * dev/inode check, as even though the pathname may look the same as 1260 * one previously used, the process may have changed directory. 1261 */ 1262 if ((err == 0) && (nname[0] == '/')) { 1263 if ((nlmp = fpavl_recorded(lml, nname, 1264 &(fdesc->fd_avlwhere))) != NULL) { 1265 fdesc->fd_nname = nname; 1266 fdesc->fd_lmp = nlmp; 1267 return (1); 1268 } 1269 if (nfavl_recorded(nname, &nfavlwhere)) { 1270 /* 1271 * For dlopen() and dlsym() fall backs, indicate that 1272 * a registered not-found path has indicated that this 1273 * object does not exist. If this path has been 1274 * constructed as part of expanding a HWCAP directory, 1275 * and as this is a silent failure, where no rejection 1276 * message is created, free the original name to 1277 * simplify the life of the caller. 1278 */ 1279 if (in_nfavl) 1280 (*in_nfavl)++; 1281 if (flags & FLG_RT_HWCAP) 1282 free((void *)nname); 1283 return (0); 1284 } 1285 } 1286 1287 if ((err == 0) && ((stat(nname, &status)) != -1)) { 1288 char path[PATH_MAX]; 1289 int fd, size, added; 1290 1291 /* 1292 * If this path has been constructed as part of expanding a 1293 * HWCAP directory, ignore any subdirectories. As this is a 1294 * silent failure, where no rejection message is created, free 1295 * the original name to simplify the life of the caller. For 1296 * any other reference that expands to a directory, fall through 1297 * to construct a meaningful rejection message. 1298 */ 1299 if ((flags & FLG_RT_HWCAP) && 1300 ((status.st_mode & S_IFMT) == S_IFDIR)) { 1301 free((void *)nname); 1302 return (0); 1303 } 1304 1305 /* 1306 * Resolve the filename and determine whether the resolved name 1307 * is already known. Typically, the previous fpavl_loaded() 1308 * will have caught this, as both NAME() and PATHNAME() for a 1309 * link-map are recorded in the FullNode AVL tree. However, 1310 * instances exist where a file can be replaced (loop-back 1311 * mounts, bfu, etc.), and reference is made to the original 1312 * file through a symbolic link. By checking the pathname here, 1313 * we don't fall through to the dev/inode check and conclude 1314 * that a new file should be loaded. 1315 */ 1316 if ((nname[0] == '/') && (rtld_flags & RT_FL_EXECNAME) && 1317 ((size = resolvepath(nname, path, (PATH_MAX - 1))) > 0)) { 1318 path[size] = '\0'; 1319 1320 if (strcmp(nname, path)) { 1321 if ((nlmp = 1322 fpavl_recorded(lml, path, 0)) != NULL) { 1323 added = 0; 1324 1325 if (append_alias(nlmp, nname, 1326 &added) == 0) 1327 return (0); 1328 /* BEGIN CSTYLED */ 1329 if (added) 1330 DBG_CALL(Dbg_file_skip(LIST(clmp), 1331 NAME(nlmp), nname)); 1332 /* END CSTYLED */ 1333 fdesc->fd_nname = nname; 1334 fdesc->fd_lmp = nlmp; 1335 return (1); 1336 } 1337 1338 /* 1339 * If this pathname hasn't been loaded, save 1340 * the resolved pathname so that it doesn't 1341 * have to be recomputed as part of fullpath() 1342 * processing. 1343 */ 1344 if ((fdesc->fd_pname = strdup(path)) == NULL) 1345 return (0); 1346 resolved = 1; 1347 } else { 1348 /* 1349 * If the resolved name doesn't differ from the 1350 * original, save it without duplication. 1351 * Having fd_pname set indicates that no further 1352 * resolvepath processing is necessary. 1353 */ 1354 fdesc->fd_pname = nname; 1355 } 1356 } 1357 1358 if (nlmp = is_devinode_loaded(&status, lml, nname, flags)) { 1359 if (flags & FLG_RT_AUDIT) { 1360 /* 1361 * If we've been requested to load an auditor, 1362 * and an auditor of the same name already 1363 * exists, then the original auditor is used. 1364 */ 1365 DBG_CALL(Dbg_audit_skip(LIST(clmp), 1366 NAME(nlmp), LIST(nlmp)->lm_lmidstr)); 1367 } else { 1368 /* 1369 * Otherwise, if an alternatively named file 1370 * has been found for the same dev/inode, add 1371 * a new name alias, and insert any alias full 1372 * pathname in the link-map lists AVL tree. 1373 */ 1374 added = 0; 1375 1376 if (append_alias(nlmp, nname, &added) == 0) 1377 return (0); 1378 if (added) { 1379 if ((nname[0] == '/') && 1380 (fpavl_insert(lml, nlmp, 1381 nname, 0) == 0)) 1382 return (0); 1383 DBG_CALL(Dbg_file_skip(LIST(clmp), 1384 NAME(nlmp), nname)); 1385 } 1386 } 1387 1388 /* 1389 * Record in the file descriptor the existing object 1390 * that satisfies this open request. 1391 */ 1392 fdesc->fd_nname = nname; 1393 fdesc->fd_lmp = nlmp; 1394 return (1); 1395 } 1396 1397 if ((fd = open(nname, O_RDONLY, 0)) == -1) { 1398 /* 1399 * As the file must exist for the previous stat() to 1400 * have succeeded, record the error condition. 1401 */ 1402 rej->rej_type = SGS_REJ_STR; 1403 rej->rej_str = strerror(errno); 1404 } else { 1405 Fct *ftp; 1406 1407 if ((ftp = are_u_this(rej, fd, &status, nname)) != 0) { 1408 fdesc->fd_nname = nname; 1409 fdesc->fd_ftp = ftp; 1410 fdesc->fd_dev = status.st_dev; 1411 fdesc->fd_ino = status.st_ino; 1412 fdesc->fd_fd = fd; 1413 1414 /* 1415 * Trace that this open has succeeded. 1416 */ 1417 if (lml->lm_flags & LML_FLG_TRC_ENABLE) { 1418 trace_so(clmp, 0, oname, nname, 1419 (fdesc->fd_flags & FLG_FD_ALTER), 1420 0); 1421 } 1422 return (1); 1423 } 1424 (void) close(fd); 1425 } 1426 1427 } else if (errno != ENOENT) { 1428 /* 1429 * If the open() failed for anything other than the file not 1430 * existing, record the error condition. 1431 */ 1432 rej->rej_type = SGS_REJ_STR; 1433 rej->rej_str = strerror(errno); 1434 } 1435 1436 /* 1437 * Regardless of error, duplicate and record any full path names that 1438 * can't be used on the "not-found" AVL tree. 1439 */ 1440 if ((nname[0] == '/') && ((name = strdup(nname)) != NULL)) 1441 nfavl_insert(name, nfavlwhere); 1442 1443 /* 1444 * Indicate any rejection. 1445 */ 1446 if (rej->rej_type) { 1447 /* 1448 * If this pathname was resolved and duplicated, remove the 1449 * allocated name to simplify the cleanup of the callers. 1450 */ 1451 if (resolved) { 1452 free((void *)fdesc->fd_pname); 1453 fdesc->fd_pname = NULL; 1454 } 1455 rej->rej_name = nname; 1456 rej->rej_flag = (fdesc->fd_flags & FLG_FD_ALTER); 1457 DBG_CALL(Dbg_file_rejected(lml, rej, M_MACH)); 1458 } 1459 return (0); 1460 } 1461 1462 /* 1463 * Find a full pathname (it contains a "/"). 1464 */ 1465 int 1466 find_path(Lm_list *lml, const char *oname, Rt_map *clmp, uint_t flags, 1467 Fdesc *fdesc, Rej_desc *rej, int *in_nfavl) 1468 { 1469 int err = 0; 1470 1471 /* 1472 * If directory configuration exists determine if this path is known. 1473 */ 1474 if (rtld_flags & RT_FL_DIRCFG) { 1475 Rtc_obj *obj; 1476 const char *aname; 1477 1478 if ((obj = elf_config_ent(oname, (Word)elf_hash(oname), 1479 0, &aname)) != 0) { 1480 /* 1481 * If the configuration file states that this path is a 1482 * directory, or the path is explicitly defined as 1483 * non-existent (ie. a unused platform specific 1484 * library), then go no further. 1485 */ 1486 if (obj->co_flags & RTC_OBJ_DIRENT) { 1487 err = EISDIR; 1488 } else if ((obj->co_flags & 1489 (RTC_OBJ_NOEXIST | RTC_OBJ_ALTER)) == 1490 RTC_OBJ_NOEXIST) { 1491 err = ENOENT; 1492 } else if ((obj->co_flags & RTC_OBJ_ALTER) && 1493 (rtld_flags & RT_FL_OBJALT) && (lml == &lml_main)) { 1494 int ret; 1495 1496 fdesc->fd_flags |= FLG_FD_ALTER; 1497 /* 1498 * Attempt to open the alternative path. If 1499 * this fails, and the alternative is flagged 1500 * as optional, fall through to open the 1501 * original path. 1502 */ 1503 DBG_CALL(Dbg_libs_found(lml, aname, 1504 FLG_FD_ALTER)); 1505 if (((ret = file_open(0, lml, oname, aname, 1506 clmp, flags, fdesc, rej, in_nfavl)) != 0) || 1507 ((obj->co_flags & RTC_OBJ_OPTINAL) == 0)) 1508 return (ret); 1509 1510 fdesc->fd_flags &= ~FLG_FD_ALTER; 1511 } 1512 } 1513 } 1514 DBG_CALL(Dbg_libs_found(lml, oname, 0)); 1515 return (file_open(err, lml, oname, oname, clmp, flags, fdesc, 1516 rej, in_nfavl)); 1517 } 1518 1519 /* 1520 * Find a simple filename (it doesn't contain a "/"). 1521 */ 1522 static int 1523 _find_file(Lm_list *lml, const char *oname, const char *nname, Rt_map *clmp, 1524 uint_t flags, Fdesc *fdesc, Rej_desc *rej, Pnode *dir, int aflag, 1525 int *in_nfavl) 1526 { 1527 DBG_CALL(Dbg_libs_found(lml, nname, aflag)); 1528 if ((lml->lm_flags & LML_FLG_TRC_SEARCH) && 1529 ((FLAGS1(clmp) & FL1_RT_LDDSTUB) == 0)) { 1530 (void) printf(MSG_INTL(MSG_LDD_PTH_TRYING), nname, aflag ? 1531 MSG_INTL(MSG_LDD_FIL_ALTER) : MSG_ORIG(MSG_STR_EMPTY)); 1532 } 1533 1534 /* 1535 * If we're being audited tell the audit library of the file we're about 1536 * to go search for. The audit library may offer an alternative 1537 * dependency, or indicate that this dependency should be ignored. 1538 */ 1539 if ((lml->lm_tflags | FLAGS1(clmp)) & LML_TFLG_AUD_OBJSEARCH) { 1540 char *aname; 1541 1542 if ((aname = audit_objsearch(clmp, nname, 1543 (dir->p_orig & LA_SER_MASK))) == 0) { 1544 DBG_CALL(Dbg_audit_terminate(lml, nname)); 1545 return (0); 1546 } 1547 1548 /* 1549 * Protect ourselves from auditor mischief, by copying any 1550 * alternative name over the present name (the present name is 1551 * maintained in a static buffer - see elf_get_so()); 1552 */ 1553 if (nname != aname) 1554 (void) strncpy((char *)nname, aname, PATH_MAX); 1555 } 1556 return (file_open(0, lml, oname, nname, clmp, flags, fdesc, 1557 rej, in_nfavl)); 1558 } 1559 1560 static int 1561 find_file(Lm_list *lml, const char *oname, Rt_map *clmp, uint_t flags, 1562 Fdesc *fdesc, Rej_desc *rej, Pnode *dir, Word * strhash, size_t olen, 1563 int *in_nfavl) 1564 { 1565 static Rtc_obj Obj = { 0 }; 1566 Rtc_obj *dobj; 1567 const char *nname = oname; 1568 1569 if (dir->p_name == 0) 1570 return (0); 1571 if (dir->p_info) { 1572 dobj = (Rtc_obj *)dir->p_info; 1573 if ((dobj->co_flags & 1574 (RTC_OBJ_NOEXIST | RTC_OBJ_ALTER)) == RTC_OBJ_NOEXIST) 1575 return (0); 1576 } else 1577 dobj = 0; 1578 1579 /* 1580 * If configuration information exists see if this directory/file 1581 * combination exists. 1582 */ 1583 if ((rtld_flags & RT_FL_DIRCFG) && 1584 ((dobj == 0) || (dobj->co_id != 0))) { 1585 Rtc_obj *fobj; 1586 const char *alt = 0; 1587 1588 /* 1589 * If this pnode has not yet been searched for in the 1590 * configuration file go find it. 1591 */ 1592 if (dobj == 0) { 1593 dobj = elf_config_ent(dir->p_name, 1594 (Word)elf_hash(dir->p_name), 0, 0); 1595 if (dobj == 0) 1596 dobj = &Obj; 1597 dir->p_info = (void *)dobj; 1598 1599 if ((dobj->co_flags & (RTC_OBJ_NOEXIST | 1600 RTC_OBJ_ALTER)) == RTC_OBJ_NOEXIST) 1601 return (0); 1602 } 1603 1604 /* 1605 * If we found a directory search for the file. 1606 */ 1607 if (dobj->co_id != 0) { 1608 if (*strhash == 0) 1609 *strhash = (Word)elf_hash(nname); 1610 fobj = elf_config_ent(nname, *strhash, 1611 dobj->co_id, &alt); 1612 1613 /* 1614 * If this object specifically does not exist, or the 1615 * object can't be found in a know-all-entries 1616 * directory, continue looking. If the object does 1617 * exist determine if an alternative object exists. 1618 */ 1619 if (fobj == 0) { 1620 if (dobj->co_flags & RTC_OBJ_ALLENTS) 1621 return (0); 1622 } else { 1623 if ((fobj->co_flags & (RTC_OBJ_NOEXIST | 1624 RTC_OBJ_ALTER)) == RTC_OBJ_NOEXIST) 1625 return (0); 1626 1627 if ((fobj->co_flags & RTC_OBJ_ALTER) && 1628 (rtld_flags & RT_FL_OBJALT) && 1629 (lml == &lml_main)) { 1630 int ret; 1631 1632 fdesc->fd_flags |= FLG_FD_ALTER; 1633 /* 1634 * Attempt to open the alternative path. 1635 * If this fails, and the alternative is 1636 * flagged as optional, fall through to 1637 * open the original path. 1638 */ 1639 ret = _find_file(lml, oname, alt, clmp, 1640 flags, fdesc, rej, dir, 1, 1641 in_nfavl); 1642 if (ret || ((fobj->co_flags & 1643 RTC_OBJ_OPTINAL) == 0)) 1644 return (ret); 1645 1646 fdesc->fd_flags &= ~FLG_FD_ALTER; 1647 } 1648 } 1649 } 1650 } 1651 1652 /* 1653 * Protect ourselves from building an invalid pathname. 1654 */ 1655 if ((olen + dir->p_len + 1) >= PATH_MAX) { 1656 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), nname, 1657 strerror(ENAMETOOLONG)); 1658 return (0); 1659 } 1660 if ((nname = (LM_GET_SO(clmp)(dir->p_name, nname))) == 0) 1661 return (0); 1662 1663 return (_find_file(lml, oname, nname, clmp, flags, fdesc, rej, 1664 dir, 0, in_nfavl)); 1665 } 1666 1667 /* 1668 * A unique file has been opened. Create a link-map to represent it, and 1669 * process the various names by which it can be referenced. 1670 */ 1671 static Rt_map * 1672 load_file(Lm_list *lml, Aliste lmco, Fdesc *fdesc, int *in_nfavl) 1673 { 1674 const char *oname = fdesc->fd_oname; 1675 const char *nname = fdesc->fd_nname; 1676 Rt_map *nlmp; 1677 1678 /* 1679 * Typically we call fct_map_so() with the full pathname of the opened 1680 * file (nname) and the name that started the search (oname), thus for 1681 * a typical dependency on libc this would be /usr/lib/libc.so.1 and 1682 * libc.so.1 (DT_NEEDED). The original name is maintained on an ALIAS 1683 * list for comparison when bringing in new dependencies. If the user 1684 * specified name as a full path (from a dlopen() for example) then 1685 * there's no need to create an ALIAS. 1686 */ 1687 if (strcmp(oname, nname) == 0) 1688 oname = 0; 1689 1690 /* 1691 * A new file has been opened, now map it into the process. Close the 1692 * original file so as not to accumulate file descriptors. 1693 */ 1694 nlmp = ((fdesc->fd_ftp)->fct_map_so)(lml, lmco, nname, oname, 1695 fdesc->fd_fd, in_nfavl); 1696 (void) close(fdesc->fd_fd); 1697 fdesc->fd_fd = 0; 1698 1699 if (nlmp == 0) 1700 return (0); 1701 1702 /* 1703 * Save the dev/inode information for later comparisons. 1704 */ 1705 STDEV(nlmp) = fdesc->fd_dev; 1706 STINO(nlmp) = fdesc->fd_ino; 1707 1708 /* 1709 * Insert the names of this link-map into the FullpathNode AVL tree. 1710 * Save both the NAME() and PATHNAME() is they differ. 1711 * 1712 * If this is an OBJECT file, don't insert it yet as this is only a 1713 * temporary link-map. During elf_obj_fini() the final link-map is 1714 * created, and its names will be inserted in the FullpathNode AVL 1715 * tree at that time. 1716 */ 1717 if ((FLAGS(nlmp) & FLG_RT_OBJECT) == 0) { 1718 /* 1719 * Update the objects full path information if necessary. 1720 * Note, with pathname expansion in effect, the fd_pname will 1721 * be used as PATHNAME(). This allocated string will be freed 1722 * should this object be deleted. However, without pathname 1723 * expansion, the fd_name should be freed now, as it is no 1724 * longer referenced. 1725 */ 1726 if (FLAGS1(nlmp) & FL1_RT_RELATIVE) 1727 (void) fullpath(nlmp, fdesc->fd_pname); 1728 else if (fdesc->fd_pname != fdesc->fd_nname) 1729 free((void *)fdesc->fd_pname); 1730 fdesc->fd_pname = 0; 1731 1732 if ((NAME(nlmp)[0] == '/') && (fpavl_insert(lml, nlmp, 1733 NAME(nlmp), fdesc->fd_avlwhere) == 0)) { 1734 remove_so(lml, nlmp); 1735 return (0); 1736 } 1737 if (((NAME(nlmp)[0] != '/') || 1738 (NAME(nlmp) != PATHNAME(nlmp))) && 1739 (fpavl_insert(lml, nlmp, PATHNAME(nlmp), 0) == 0)) { 1740 remove_so(lml, nlmp); 1741 return (0); 1742 } 1743 } 1744 1745 /* 1746 * If we're processing an alternative object reset the original name 1747 * for possible $ORIGIN processing. 1748 */ 1749 if (fdesc->fd_flags & FLG_FD_ALTER) { 1750 const char *odir; 1751 char *ndir; 1752 size_t olen; 1753 1754 FLAGS(nlmp) |= FLG_RT_ALTER; 1755 1756 /* 1757 * If we were given a pathname containing a slash then the 1758 * original name is still in oname. Otherwise the original 1759 * directory is in dir->p_name (which is all we need for 1760 * $ORIGIN). 1761 */ 1762 if (fdesc->fd_flags & FLG_FD_SLASH) { 1763 char *ofil; 1764 1765 odir = oname; 1766 ofil = strrchr(oname, '/'); 1767 olen = ofil - odir + 1; 1768 } else { 1769 odir = fdesc->fd_odir; 1770 olen = strlen(odir) + 1; 1771 } 1772 1773 if ((ndir = (char *)malloc(olen)) == 0) { 1774 remove_so(lml, nlmp); 1775 return (0); 1776 } 1777 (void) strncpy(ndir, odir, olen); 1778 ndir[--olen] = '\0'; 1779 1780 ORIGNAME(nlmp) = ndir; 1781 DIRSZ(nlmp) = olen; 1782 } 1783 1784 /* 1785 * Identify this as a new object. 1786 */ 1787 FLAGS(nlmp) |= FLG_RT_NEWLOAD; 1788 1789 return (nlmp); 1790 } 1791 1792 /* 1793 * This function loads the named file and returns a pointer to its link map. 1794 * It is assumed that the caller has already checked that the file is not 1795 * already loaded before calling this function (refer is_so_loaded()). 1796 * Find and open the file, map it into memory, add it to the end of the list 1797 * of link maps and return a pointer to the new link map. Return 0 on error. 1798 */ 1799 static Rt_map * 1800 load_so(Lm_list *lml, Aliste lmco, const char *oname, Rt_map *clmp, 1801 uint_t flags, Fdesc *nfdp, Rej_desc *rej, int *in_nfavl) 1802 { 1803 char *name; 1804 uint_t slash = 0; 1805 size_t olen; 1806 Fdesc fdesc = { 0 }; 1807 Pnode *dir; 1808 1809 /* 1810 * If the file is the run time linker then it's already loaded. 1811 */ 1812 if (interp && (strcmp(oname, NAME(lml_rtld.lm_head)) == 0)) 1813 return (lml_rtld.lm_head); 1814 1815 /* 1816 * If this isn't a hardware capabilities pathname, which is already a 1817 * full, duplicated pathname, determine whether the pathname contains 1818 * a slash, and if not determine the input filename (for max path 1819 * length verification). 1820 */ 1821 if ((flags & FLG_RT_HWCAP) == 0) { 1822 const char *str; 1823 1824 for (str = oname; *str; str++) { 1825 if (*str == '/') { 1826 slash++; 1827 break; 1828 } 1829 } 1830 if (slash == 0) 1831 olen = (str - oname) + 1; 1832 } 1833 1834 /* 1835 * If we are passed a 'null' link-map this means that this is the first 1836 * object to be loaded on this link-map list. In that case we set the 1837 * link-map to ld.so.1's link-map. 1838 * 1839 * This link-map is referenced to determine what lookup rules to use 1840 * when searching for files. By using ld.so.1's we are defaulting to 1841 * ELF look-up rules. 1842 * 1843 * Note: This case happens when loading the first object onto 1844 * the plt_tracing link-map. 1845 */ 1846 if (clmp == 0) 1847 clmp = lml_rtld.lm_head; 1848 1849 /* 1850 * If this path resulted from a $HWCAP specification, then the best 1851 * hardware capability object has already been establish, and is 1852 * available in the calling file descriptor. Perform some minor book- 1853 * keeping so that we can fall through into common code. 1854 */ 1855 if (flags & FLG_RT_HWCAP) { 1856 /* 1857 * If this object is already loaded, we're done. 1858 */ 1859 if (nfdp->fd_lmp) 1860 return (nfdp->fd_lmp); 1861 1862 /* 1863 * Obtain the avl index for this object. 1864 */ 1865 (void) fpavl_recorded(lml, nfdp->fd_nname, 1866 &(nfdp->fd_avlwhere)); 1867 1868 /* 1869 * If the name and resolved pathname differ, duplicate the path 1870 * name once more to provide for generic cleanup by the caller. 1871 */ 1872 if (nfdp->fd_pname && (nfdp->fd_nname != nfdp->fd_pname)) { 1873 char *pname; 1874 1875 if ((pname = strdup(nfdp->fd_pname)) == NULL) 1876 return (0); 1877 nfdp->fd_pname = pname; 1878 } 1879 } else if (slash) { 1880 Rej_desc _rej = { 0 }; 1881 1882 *nfdp = fdesc; 1883 nfdp->fd_flags = FLG_FD_SLASH; 1884 1885 if (find_path(lml, oname, clmp, flags, nfdp, 1886 &_rej, in_nfavl) == 0) { 1887 rejection_inherit(rej, &_rej); 1888 return (0); 1889 } 1890 1891 /* 1892 * If this object is already loaded, we're done. 1893 */ 1894 if (nfdp->fd_lmp) 1895 return (nfdp->fd_lmp); 1896 1897 } else { 1898 /* 1899 * No '/' - for each directory on list, make a pathname using 1900 * that directory and filename and try to open that file. 1901 */ 1902 Pnode *dirlist = (Pnode *)0; 1903 Word strhash = 0; 1904 #if !defined(ISSOLOAD_BASENAME_DISABLED) 1905 Rt_map *nlmp; 1906 #endif 1907 DBG_CALL(Dbg_libs_find(lml, oname)); 1908 1909 #if !defined(ISSOLOAD_BASENAME_DISABLED) 1910 if ((nlmp = is_so_loaded(lml, oname, in_nfavl))) 1911 return (nlmp); 1912 #endif 1913 /* 1914 * Make sure we clear the file descriptor new name in case the 1915 * following directory search doesn't provide any directories 1916 * (odd, but this can be forced with a -znodefaultlib test). 1917 */ 1918 *nfdp = fdesc; 1919 for (dir = get_next_dir(&dirlist, clmp, flags); dir; 1920 dir = get_next_dir(&dirlist, clmp, flags)) { 1921 Rej_desc _rej = { 0 }; 1922 1923 *nfdp = fdesc; 1924 1925 /* 1926 * Under debugging, duplicate path name entries are 1927 * tagged but remain part of the search path list so 1928 * that they can be diagnosed under "unused" processing. 1929 * Skip these entries, as this path would have already 1930 * been attempted. 1931 */ 1932 if (dir->p_orig & PN_FLG_DUPLICAT) 1933 continue; 1934 1935 /* 1936 * Try and locate this file. Make sure to clean up 1937 * any rejection information should the file have 1938 * been found, but not appropriate. 1939 */ 1940 if (find_file(lml, oname, clmp, flags, nfdp, &_rej, 1941 dir, &strhash, olen, in_nfavl) == 0) { 1942 rejection_inherit(rej, &_rej); 1943 continue; 1944 } 1945 1946 /* 1947 * Indicate that this search path has been used. If 1948 * this is an LD_LIBRARY_PATH setting, ignore any use 1949 * by ld.so.1 itself. 1950 */ 1951 if (((dir->p_orig & LA_SER_LIBPATH) == 0) || 1952 ((lml->lm_flags & LML_FLG_RTLDLM) == 0)) 1953 dir->p_orig |= PN_FLG_USED; 1954 1955 /* 1956 * If this object is already loaded, we're done. 1957 */ 1958 if (nfdp->fd_lmp) 1959 return (nfdp->fd_lmp); 1960 1961 nfdp->fd_odir = dir->p_name; 1962 break; 1963 } 1964 1965 /* 1966 * If the file couldn't be loaded, do another comparison of 1967 * loaded files using just the basename. This catches folks 1968 * who may have loaded multiple full pathname files (possibly 1969 * from setxid applications) to satisfy dependency relationships 1970 * (i.e., a file might have a dependency on foo.so.1 which has 1971 * already been opened using its full pathname). 1972 */ 1973 if (nfdp->fd_nname == NULL) 1974 return (is_so_loaded(lml, oname, in_nfavl)); 1975 } 1976 1977 /* 1978 * Duplicate the file name so that NAME() is available in core files. 1979 * Note, that hardware capability names are already duplicated, but 1980 * they get duplicated once more to insure consistent cleanup in the 1981 * event of an error condition. 1982 */ 1983 if ((name = strdup(nfdp->fd_nname)) == NULL) 1984 return (0); 1985 1986 if (nfdp->fd_nname == nfdp->fd_pname) 1987 nfdp->fd_nname = nfdp->fd_pname = name; 1988 else 1989 nfdp->fd_nname = name; 1990 1991 /* 1992 * Finish mapping the file and return the link-map descriptor. Note, 1993 * if this request originated from a HWCAP request, re-establish the 1994 * fdesc information. For single paged objects, such as filters, the 1995 * original mapping may have been sufficient to capture the file, thus 1996 * this mapping needs to be reset to insure it doesn't mistakenly get 1997 * unmapped as part of HWCAP cleanup. 1998 */ 1999 return (load_file(lml, lmco, nfdp, in_nfavl)); 2000 } 2001 2002 /* 2003 * Trace an attempt to load an object. 2004 */ 2005 int 2006 load_trace(Lm_list *lml, const char **oname, Rt_map *clmp) 2007 { 2008 const char *name = *oname; 2009 2010 /* 2011 * First generate any ldd(1) diagnostics. 2012 */ 2013 if ((lml->lm_flags & (LML_FLG_TRC_VERBOSE | LML_FLG_TRC_SEARCH)) && 2014 ((FLAGS1(clmp) & FL1_RT_LDDSTUB) == 0)) 2015 (void) printf(MSG_INTL(MSG_LDD_FIL_FIND), name, NAME(clmp)); 2016 2017 /* 2018 * If we're being audited tell the audit library of the file we're 2019 * about to go search for. 2020 */ 2021 if (((lml->lm_tflags | FLAGS1(clmp)) & LML_TFLG_AUD_ACTIVITY) && 2022 (lml == LIST(clmp))) 2023 audit_activity(clmp, LA_ACT_ADD); 2024 2025 if ((lml->lm_tflags | FLAGS1(clmp)) & LML_TFLG_AUD_OBJSEARCH) { 2026 char *aname = audit_objsearch(clmp, name, LA_SER_ORIG); 2027 2028 /* 2029 * The auditor can indicate that this object should be ignored. 2030 */ 2031 if (aname == NULL) { 2032 DBG_CALL(Dbg_audit_terminate(lml, name)); 2033 return (0); 2034 } 2035 2036 /* 2037 * Protect ourselves from auditor mischief, by duplicating any 2038 * alternative name. The original name has been allocated from 2039 * expand(), so free this allocation before using the audit 2040 * alternative. 2041 */ 2042 if (name != aname) { 2043 if ((aname = strdup(aname)) == NULL) { 2044 eprintf(lml, ERR_FATAL, 2045 MSG_INTL(MSG_GEN_AUDITERM), name); 2046 return (0); 2047 } 2048 free((void *)*oname); 2049 *oname = aname; 2050 } 2051 } 2052 return (1); 2053 } 2054 2055 /* 2056 * Having loaded an object and created a link-map to describe it, finish 2057 * processing this stage, including verifying any versioning requirements, 2058 * updating the objects mode, creating a handle if necessary, and adding this 2059 * object to existing handles if required. 2060 */ 2061 static int 2062 load_finish(Lm_list *lml, const char *name, Rt_map *clmp, int nmode, 2063 uint_t flags, Grp_hdl **hdl, Rt_map *nlmp) 2064 { 2065 Aliste idx; 2066 Grp_hdl *ghp; 2067 int promote; 2068 2069 /* 2070 * If this dependency is associated with a required version insure that 2071 * the version is present in the loaded file. 2072 */ 2073 if (((rtld_flags & RT_FL_NOVERSION) == 0) && 2074 (FCT(clmp) == &elf_fct) && VERNEED(clmp) && 2075 (LM_VERIFY_VERS(clmp)(name, clmp, nlmp) == 0)) 2076 return (0); 2077 2078 /* 2079 * If this object has indicated that it should be isolated as a group 2080 * (DT_FLAGS_1 contains DF_1_GROUP - object was built with -B group), 2081 * or if the callers direct bindings indicate it should be isolated as 2082 * a group (DYNINFO flags contains FLG_DI_GROUP - dependency followed 2083 * -zgroupperm), establish the appropriate mode. 2084 * 2085 * The intent of an object defining itself as a group is to isolate the 2086 * relocation of the group within its own members, however, unless 2087 * opened through dlopen(), in which case we assume dlsym() will be used 2088 * to located symbols in the new object, we still need to associate it 2089 * with the caller for it to be bound with. This is equivalent to a 2090 * dlopen(RTLD_GROUP) and dlsym() using the returned handle. 2091 */ 2092 if ((FLAGS(nlmp) | flags) & FLG_RT_SETGROUP) { 2093 nmode &= ~RTLD_WORLD; 2094 nmode |= RTLD_GROUP; 2095 2096 /* 2097 * If the object wasn't explicitly dlopen()'ed associate it with 2098 * the parent. 2099 */ 2100 if ((flags & FLG_RT_HANDLE) == 0) 2101 nmode |= RTLD_PARENT; 2102 } 2103 2104 /* 2105 * Establish new mode and flags. 2106 * 2107 * For patch backward compatibility, the following use of update_mode() 2108 * is disabled. 2109 */ 2110 #ifdef SIEBEL_DISABLE 2111 if (rtld_flags & RT_FL_DISFIX_1) 2112 promote = MODE(nlmp) |= 2113 (nmode & ~(RTLD_PARENT | RTLD_NOLOAD | RTLD_FIRST)); 2114 else 2115 #endif 2116 promote = update_mode(nlmp, MODE(nlmp), nmode); 2117 2118 FLAGS(nlmp) |= flags; 2119 2120 /* 2121 * If this is a global object, ensure the associated link-map list can 2122 * be rescanned for global, lazy dependencies. 2123 */ 2124 if (MODE(nlmp) & RTLD_GLOBAL) 2125 LIST(nlmp)->lm_flags &= ~LML_FLG_NOPENDGLBLAZY; 2126 2127 /* 2128 * If we've been asked to establish a handle create one for this object. 2129 * Or, if this object has already been analyzed, but this reference 2130 * requires that the mode of the object be promoted, also create a 2131 * handle to propagate the new modes to all this objects dependencies. 2132 */ 2133 if (((FLAGS(nlmp) | flags) & FLG_RT_HANDLE) || (promote && 2134 (FLAGS(nlmp) & FLG_RT_ANALYZED))) { 2135 uint_t oflags, hflags = 0, cdflags; 2136 2137 /* 2138 * Establish any flags for the handle (Grp_hdl). 2139 * 2140 * . Use of the RTLD_FIRST flag indicates that only the first 2141 * dependency on the handle (the new object) can be used 2142 * to satisfy dlsym() requests. 2143 */ 2144 if (nmode & RTLD_FIRST) 2145 hflags = GPH_FIRST; 2146 2147 /* 2148 * Establish the flags for this callers dependency descriptor 2149 * (Grp_desc). 2150 * 2151 * . The creation of a handle associated a descriptor for the 2152 * new object and descriptor for the parent (caller). 2153 * Typically, the handle is created for dlopen() or for 2154 * filtering. A handle may also be created to promote 2155 * the callers modes (RTLD_NOW) to the new object. In this 2156 * latter case, the handle/descriptor are torn down once 2157 * the mode propagation has occurred. 2158 * 2159 * . Use of the RTLD_PARENT flag indicates that the parent 2160 * can be relocated against. 2161 */ 2162 if (((FLAGS(nlmp) | flags) & FLG_RT_HANDLE) == 0) 2163 cdflags = GPD_PROMOTE; 2164 else 2165 cdflags = GPD_PARENT; 2166 if (nmode & RTLD_PARENT) 2167 cdflags |= GPD_RELOC; 2168 2169 /* 2170 * Now that a handle is being created, remove this state from 2171 * the object so that it doesn't mistakenly get inherited by 2172 * a dependency. 2173 */ 2174 oflags = FLAGS(nlmp); 2175 FLAGS(nlmp) &= ~FLG_RT_HANDLE; 2176 2177 DBG_CALL(Dbg_file_hdl_title(DBG_HDL_ADD)); 2178 if ((ghp = hdl_create(lml, nlmp, clmp, hflags, 2179 (GPD_DLSYM | GPD_RELOC | GPD_ADDEPS), cdflags)) == 0) 2180 return (0); 2181 2182 /* 2183 * Add any dependencies that are already loaded, to the handle. 2184 */ 2185 if (hdl_initialize(ghp, nlmp, nmode, promote) == 0) 2186 return (0); 2187 2188 if (hdl) 2189 *hdl = ghp; 2190 2191 /* 2192 * If we were asked to create a handle, we're done. 2193 */ 2194 if ((oflags | flags) & FLG_RT_HANDLE) 2195 return (1); 2196 2197 /* 2198 * If the handle was created to promote modes from the parent 2199 * (caller) to the new object, then this relationship needs to 2200 * be removed to ensure the handle doesn't prevent the new 2201 * objects from being deleted if required. If the parent is 2202 * the only dependency on the handle, then the handle can be 2203 * completely removed. However, the handle may have already 2204 * existed, in which case only the parent descriptor can be 2205 * deleted from the handle, or at least the GPD_PROMOTE flag 2206 * removed from the descriptor. 2207 * 2208 * Fall through to carry out any group processing. 2209 */ 2210 free_hdl(ghp, clmp, GPD_PROMOTE); 2211 } 2212 2213 /* 2214 * If the caller isn't part of a group we're done. 2215 */ 2216 if (GROUPS(clmp) == NULL) 2217 return (1); 2218 2219 /* 2220 * Determine if our caller is already associated with a handle, if so 2221 * we need to add this object to any handles that already exist. 2222 * Traverse the list of groups our caller is a member of and add this 2223 * new link-map to those groups. 2224 */ 2225 DBG_CALL(Dbg_file_hdl_title(DBG_HDL_ADD)); 2226 for (APLIST_TRAVERSE(GROUPS(clmp), idx, ghp)) { 2227 Aliste idx1; 2228 Grp_desc *gdp; 2229 int exist; 2230 Rt_map *dlmp1; 2231 APlist *lmalp = NULL; 2232 2233 /* 2234 * If the caller doesn't indicate that its dependencies should 2235 * be added to a handle, ignore it. This case identifies a 2236 * parent of a dlopen(RTLD_PARENT) request. 2237 */ 2238 for (ALIST_TRAVERSE(ghp->gh_depends, idx1, gdp)) { 2239 if (gdp->gd_depend == clmp) 2240 break; 2241 } 2242 if ((gdp->gd_flags & GPD_ADDEPS) == 0) 2243 continue; 2244 2245 if ((exist = hdl_add(ghp, nlmp, 2246 (GPD_DLSYM | GPD_RELOC | GPD_ADDEPS))) == 0) 2247 return (0); 2248 2249 /* 2250 * If this member already exists then its dependencies will 2251 * have already been processed. 2252 */ 2253 if (exist == ALE_EXISTS) 2254 continue; 2255 2256 /* 2257 * If the object we've added has just been opened, it will not 2258 * yet have been processed for its dependencies, these will be 2259 * added on later calls to load_one(). If it doesn't have any 2260 * dependencies we're also done. 2261 */ 2262 if (((FLAGS(nlmp) & FLG_RT_ANALYZED) == 0) || 2263 (DEPENDS(nlmp) == NULL)) 2264 continue; 2265 2266 /* 2267 * Otherwise, this object exists and has dependencies, so add 2268 * all of its dependencies to the handle were operating on. 2269 */ 2270 if (aplist_append(&lmalp, nlmp, AL_CNT_DEPCLCT) == 0) 2271 return (0); 2272 2273 for (APLIST_TRAVERSE(lmalp, idx1, dlmp1)) { 2274 Aliste idx2; 2275 Bnd_desc *bdp; 2276 2277 /* 2278 * Add any dependencies of this dependency to the 2279 * dynamic dependency list so they can be further 2280 * processed. 2281 */ 2282 for (APLIST_TRAVERSE(DEPENDS(dlmp1), idx2, bdp)) { 2283 Rt_map *dlmp2 = bdp->b_depend; 2284 2285 if ((bdp->b_flags & BND_NEEDED) == 0) 2286 continue; 2287 2288 if (aplist_test(&lmalp, dlmp2, 2289 AL_CNT_DEPCLCT) == 0) { 2290 free(lmalp); 2291 return (0); 2292 } 2293 } 2294 2295 if (nlmp == dlmp1) 2296 continue; 2297 2298 if ((exist = hdl_add(ghp, dlmp1, 2299 (GPD_DLSYM | GPD_RELOC | GPD_ADDEPS))) != 0) { 2300 if (exist == ALE_CREATE) { 2301 (void) update_mode(dlmp1, MODE(dlmp1), 2302 nmode); 2303 } 2304 continue; 2305 } 2306 free(lmalp); 2307 return (0); 2308 } 2309 free(lmalp); 2310 } 2311 return (1); 2312 } 2313 2314 /* 2315 * The central routine for loading shared objects. Insures ldd() diagnostics, 2316 * handles and any other related additions are all done in one place. 2317 */ 2318 static Rt_map * 2319 _load_path(Lm_list *lml, Aliste lmco, const char **oname, Rt_map *clmp, 2320 int nmode, uint_t flags, Grp_hdl ** hdl, Fdesc *nfdp, Rej_desc *rej, 2321 int *in_nfavl) 2322 { 2323 Rt_map *nlmp; 2324 const char *name = *oname; 2325 2326 if ((nmode & RTLD_NOLOAD) == 0) { 2327 /* 2328 * If this isn't a noload request attempt to load the file. 2329 * Note, the name of the file may be changed by an auditor. 2330 */ 2331 if ((load_trace(lml, oname, clmp)) == 0) 2332 return (0); 2333 2334 name = *oname; 2335 2336 if ((nlmp = load_so(lml, lmco, name, clmp, flags, 2337 nfdp, rej, in_nfavl)) == 0) 2338 return (0); 2339 2340 /* 2341 * If we've loaded a library which identifies itself as not 2342 * being dlopen()'able catch it here. Let non-dlopen()'able 2343 * objects through under RTLD_CONFGEN as they're only being 2344 * mapped to be dldump()'ed. 2345 */ 2346 if ((rtld_flags & RT_FL_APPLIC) && ((FLAGS(nlmp) & 2347 (FLG_RT_NOOPEN | FLG_RT_RELOCED)) == FLG_RT_NOOPEN) && 2348 ((nmode & RTLD_CONFGEN) == 0)) { 2349 Rej_desc _rej = { 0 }; 2350 2351 _rej.rej_name = name; 2352 _rej.rej_type = SGS_REJ_STR; 2353 _rej.rej_str = MSG_INTL(MSG_GEN_NOOPEN); 2354 DBG_CALL(Dbg_file_rejected(lml, &_rej, M_MACH)); 2355 rejection_inherit(rej, &_rej); 2356 remove_so(lml, nlmp); 2357 return (0); 2358 } 2359 } else { 2360 /* 2361 * If it's a NOLOAD request - check to see if the object 2362 * has already been loaded. 2363 */ 2364 /* LINTED */ 2365 if (nlmp = is_so_loaded(lml, name, in_nfavl)) { 2366 if ((lml->lm_flags & LML_FLG_TRC_VERBOSE) && 2367 ((FLAGS1(clmp) & FL1_RT_LDDSTUB) == 0)) { 2368 (void) printf(MSG_INTL(MSG_LDD_FIL_FIND), name, 2369 NAME(clmp)); 2370 /* BEGIN CSTYLED */ 2371 if (*name == '/') 2372 (void) printf(MSG_ORIG(MSG_LDD_FIL_PATH), 2373 name, MSG_ORIG(MSG_STR_EMPTY), 2374 MSG_ORIG(MSG_STR_EMPTY)); 2375 else 2376 (void) printf(MSG_ORIG(MSG_LDD_FIL_EQUIV), 2377 name, NAME(nlmp), 2378 MSG_ORIG(MSG_STR_EMPTY), 2379 MSG_ORIG(MSG_STR_EMPTY)); 2380 /* END CSTYLED */ 2381 } 2382 } else { 2383 Rej_desc _rej = { 0 }; 2384 2385 _rej.rej_name = name; 2386 _rej.rej_type = SGS_REJ_STR; 2387 _rej.rej_str = strerror(ENOENT); 2388 DBG_CALL(Dbg_file_rejected(lml, &_rej, M_MACH)); 2389 rejection_inherit(rej, &_rej); 2390 return (0); 2391 } 2392 } 2393 2394 /* 2395 * Finish processing this loaded object. 2396 */ 2397 if (load_finish(lml, name, clmp, nmode, flags, hdl, nlmp) == 0) { 2398 FLAGS(nlmp) &= ~FLG_RT_NEWLOAD; 2399 2400 /* 2401 * If this object has already been analyzed, then it is in use, 2402 * so even though this operation has failed, it should not be 2403 * torn down. 2404 */ 2405 if ((FLAGS(nlmp) & FLG_RT_ANALYZED) == 0) 2406 remove_so(lml, nlmp); 2407 return (0); 2408 } 2409 2410 /* 2411 * If this object is new, and we're being audited, tell the audit 2412 * library of the file we've just opened. Note, if the new link-map 2413 * requires local auditing of its dependencies we also register its 2414 * opening. 2415 */ 2416 if (FLAGS(nlmp) & FLG_RT_NEWLOAD) { 2417 FLAGS(nlmp) &= ~FLG_RT_NEWLOAD; 2418 2419 if (((lml->lm_tflags | FLAGS1(clmp) | FLAGS1(nlmp)) & 2420 LML_TFLG_AUD_MASK) && (((lml->lm_flags | 2421 LIST(clmp)->lm_flags) & LML_FLG_NOAUDIT) == 0)) { 2422 if (audit_objopen(clmp, nlmp) == 0) { 2423 remove_so(lml, nlmp); 2424 return (0); 2425 } 2426 } 2427 } 2428 return (nlmp); 2429 } 2430 2431 Rt_map * 2432 load_path(Lm_list *lml, Aliste lmco, const char **name, Rt_map *clmp, int nmode, 2433 uint_t flags, Grp_hdl **hdl, Fdesc *cfdp, Rej_desc *rej, int *in_nfavl) 2434 { 2435 Rt_map *lmp; 2436 Fdesc nfdp = { 0 }; 2437 2438 /* 2439 * If this path resulted from a $HWCAP specification, then the best 2440 * hardware capability object has already been establish, and is 2441 * available in the calling file descriptor. 2442 */ 2443 if (flags & FLG_RT_HWCAP) { 2444 if (cfdp->fd_lmp == 0) { 2445 /* 2446 * If this object hasn't yet been mapped, re-establish 2447 * the file descriptor structure to reflect this objects 2448 * original initial page mapping. Make sure any present 2449 * file descriptor mapping is removed before overwriting 2450 * the structure. 2451 */ 2452 #if defined(MAP_ALIGN) 2453 if (fmap->fm_maddr && 2454 ((fmap->fm_mflags & MAP_ALIGN) == 0)) 2455 #else 2456 if (fmap->fm_maddr) 2457 #endif 2458 (void) munmap(fmap->fm_maddr, fmap->fm_msize); 2459 2460 *fmap = cfdp->fd_fmap; 2461 } 2462 nfdp = *cfdp; 2463 } 2464 2465 lmp = _load_path(lml, lmco, name, clmp, nmode, flags, hdl, &nfdp, 2466 rej, in_nfavl); 2467 2468 /* 2469 * If this path originated from a $HWCAP specification, re-establish the 2470 * fdesc information. For single paged objects, such as filters, the 2471 * original mapping may have been sufficient to capture the file, thus 2472 * this mapping needs to be reset to insure it doesn't mistakenly get 2473 * unmapped as part of HWCAP cleanup. 2474 */ 2475 if ((flags & FLG_RT_HWCAP) && (cfdp->fd_lmp == 0)) { 2476 cfdp->fd_fmap.fm_maddr = fmap->fm_maddr; 2477 cfdp->fd_fmap.fm_mflags = fmap->fm_mflags; 2478 cfdp->fd_fd = nfdp.fd_fd; 2479 } 2480 2481 return (lmp); 2482 } 2483 2484 /* 2485 * Load one object from a possible list of objects. Typically, for requests 2486 * such as NEEDED's, only one object is specified. However, this object could 2487 * be specified using $ISALIST or $HWCAP, in which case only the first object 2488 * that can be loaded is used (ie. the best). 2489 */ 2490 Rt_map * 2491 load_one(Lm_list *lml, Aliste lmco, Pnode *pnp, Rt_map *clmp, int mode, 2492 uint_t flags, Grp_hdl **hdl, int *in_nfavl) 2493 { 2494 Rej_desc rej = { 0 }; 2495 Pnode *tpnp; 2496 const char *name; 2497 2498 for (tpnp = pnp; tpnp && tpnp->p_name; tpnp = tpnp->p_next) { 2499 Rt_map *tlmp; 2500 2501 /* 2502 * A Hardware capabilities requirement can itself expand into 2503 * a number of candidates. 2504 */ 2505 if (tpnp->p_orig & PN_TKN_HWCAP) { 2506 if ((tlmp = load_hwcap(lml, lmco, tpnp->p_name, clmp, 2507 mode, (flags | FLG_RT_HWCAP), hdl, &rej, 2508 in_nfavl)) != 0) { 2509 remove_rej(&rej); 2510 return (tlmp); 2511 } 2512 } else { 2513 if ((tlmp = load_path(lml, lmco, &tpnp->p_name, clmp, 2514 mode, flags, hdl, 0, &rej, in_nfavl)) != 0) { 2515 remove_rej(&rej); 2516 return (tlmp); 2517 } 2518 } 2519 } 2520 2521 /* 2522 * If this pathname originated from an expanded token, use the original 2523 * for any diagnostic output. 2524 */ 2525 if ((name = pnp->p_oname) == 0) 2526 name = pnp->p_name; 2527 2528 file_notfound(lml, name, clmp, flags, &rej); 2529 remove_rej(&rej); 2530 return (0); 2531 } 2532 2533 /* 2534 * Determine whether a symbol is defined as an interposer. 2535 */ 2536 int 2537 is_sym_interposer(Rt_map *lmp, Sym *sym) 2538 { 2539 Syminfo *sip = SYMINFO(lmp); 2540 2541 if (sip) { 2542 ulong_t ndx; 2543 2544 ndx = (((ulong_t)sym - (ulong_t)SYMTAB(lmp)) / SYMENT(lmp)); 2545 /* LINTED */ 2546 sip = (Syminfo *)((char *)sip + (ndx * SYMINENT(lmp))); 2547 if (sip->si_flags & SYMINFO_FLG_INTERPOSE) 2548 return (1); 2549 } 2550 return (0); 2551 } 2552 2553 /* 2554 * While processing direct or group bindings, determine whether the object to 2555 * which we've bound can be interposed upon. In this context, copy relocations 2556 * are a form of interposition. 2557 */ 2558 static Sym * 2559 lookup_sym_interpose(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Lm_list *lml, 2560 Sym *osym, int *in_nfavl) 2561 { 2562 Rt_map *lmp; 2563 Slookup sl; 2564 2565 /* 2566 * If we've bound to a copy relocation definition then we need to assign 2567 * this binding to the original copy reference. Fabricate an inter- 2568 * position diagnostic, as this is a legitimate form of interposition. 2569 */ 2570 if (FLAGS1(*dlmp) & FL1_RT_COPYTOOK) { 2571 Rel_copy *rcp; 2572 Aliste idx; 2573 2574 for (ALIST_TRAVERSE(COPY_R(*dlmp), idx, rcp)) { 2575 if ((osym == rcp->r_dsym) || (osym->st_value && 2576 (osym->st_value == rcp->r_dsym->st_value))) { 2577 *dlmp = rcp->r_rlmp; 2578 *binfo |= 2579 (DBG_BINFO_INTERPOSE | DBG_BINFO_COPYREF); 2580 return (rcp->r_rsym); 2581 } 2582 } 2583 } 2584 2585 /* 2586 * Prior to Solaris 8, external references from an executable that were 2587 * bound to an uninitialized variable (.bss) within a shared object did 2588 * not establish a copy relocation. This was thought to be an 2589 * optimization, to prevent copying zero's to zero's. Typically, 2590 * interposition took its course, with the shared object binding to the 2591 * executables data definition. 2592 * 2593 * This scenario can be broken when this old executable runs against a 2594 * new shared object that is directly bound. With no copy-relocation 2595 * record, ld.so.1 has no data to trigger the normal vectoring of the 2596 * binding to the executable. 2597 * 2598 * Starting with Solaris 8, a DT_FLAGS entry is written to all objects, 2599 * regardless of there being any DF_ flags entries. Therefore, an 2600 * object without this dynamic tag is susceptible to the copy relocation 2601 * issue. If the executable has no DT_FLAGS tag, and contains the same 2602 * .bss symbol definition as has been directly bound to, redirect the 2603 * binding to the executables data definition. 2604 */ 2605 lmp = lml->lm_head; 2606 sl = *slp; 2607 sl.sl_imap = lmp; 2608 2609 if (((FLAGS2(lmp) & FL2_RT_DTFLAGS) == 0) && (FCT(lmp) == &elf_fct) && 2610 (ELF_ST_TYPE(osym->st_info) != STT_FUNC) && 2611 are_bits_zero(*dlmp, osym, 0)) { 2612 Rt_map *ilmp; 2613 Sym *isym; 2614 2615 /* 2616 * Determine whether the same symbol name exists within the 2617 * executable, that the size and type of symbol are the same, 2618 * and that the symbol is also associated with .bss. 2619 */ 2620 if (((isym = SYMINTP(lmp)(&sl, &ilmp, binfo, 2621 in_nfavl)) != NULL) && (isym->st_size == osym->st_size) && 2622 (isym->st_info == osym->st_info) && 2623 are_bits_zero(lmp, isym, 1)) { 2624 *dlmp = lmp; 2625 *binfo |= (DBG_BINFO_INTERPOSE | DBG_BINFO_COPYREF); 2626 return (isym); 2627 } 2628 } 2629 2630 if ((lml->lm_flags & LML_FLG_INTRPOSE) == 0) 2631 return ((Sym *)0); 2632 2633 /* 2634 * Traverse the list of known interposers to determine whether any 2635 * offer the same symbol. Note, the head of the link-map could be 2636 * identified as an interposer. Otherwise, skip the head of the 2637 * link-map, so that we don't bind to any .plt references, or 2638 * copy-relocation destinations unintentionally. 2639 */ 2640 lmp = lml->lm_head; 2641 sl = *slp; 2642 if (((FLAGS(lmp) & MSK_RT_INTPOSE) == 0) || (sl.sl_flags & LKUP_COPY)) 2643 lmp = (Rt_map *)NEXT(lmp); 2644 2645 for (; lmp; lmp = (Rt_map *)NEXT(lmp)) { 2646 if (FLAGS(lmp) & FLG_RT_DELETE) 2647 continue; 2648 if ((FLAGS(lmp) & MSK_RT_INTPOSE) == 0) 2649 break; 2650 2651 if (callable(lmp, *dlmp, 0, sl.sl_flags)) { 2652 Rt_map *ilmp; 2653 Sym *isym; 2654 2655 sl.sl_imap = lmp; 2656 if (isym = SYMINTP(lmp)(&sl, &ilmp, binfo, in_nfavl)) { 2657 /* 2658 * If this object provides individual symbol 2659 * interposers, make sure that the symbol we 2660 * have found is tagged as an interposer. 2661 */ 2662 if ((FLAGS(ilmp) & FLG_RT_SYMINTPO) && 2663 (is_sym_interposer(ilmp, isym) == 0)) 2664 continue; 2665 2666 /* 2667 * Indicate this binding has occurred to an 2668 * interposer, and return the symbol. 2669 */ 2670 *binfo |= DBG_BINFO_INTERPOSE; 2671 *dlmp = ilmp; 2672 return (isym); 2673 } 2674 } 2675 } 2676 return ((Sym *)0); 2677 } 2678 2679 /* 2680 * If an object specifies direct bindings (it contains a syminfo structure 2681 * describing where each binding was established during link-editing, and the 2682 * object was built -Bdirect), then look for the symbol in the specific object. 2683 */ 2684 static Sym * 2685 lookup_sym_direct(Slookup *slp, Rt_map **dlmp, uint_t *binfo, Syminfo *sip, 2686 Rt_map *lmp, int *in_nfavl) 2687 { 2688 Rt_map *clmp = slp->sl_cmap; 2689 Sym *sym; 2690 Slookup sl; 2691 2692 /* 2693 * If a direct binding resolves to the definition of a copy relocated 2694 * variable, it must be redirected to the copy (in the executable) that 2695 * will eventually be made. Typically, this redirection occurs in 2696 * lookup_sym_interpose(). But, there's an edge condition. If a 2697 * directly bound executable contains pic code, there may be a 2698 * reference to a definition that will eventually have a copy made. 2699 * However, this copy relocation may not yet have occurred, because 2700 * the relocation making this reference comes before the relocation 2701 * that will create the copy. 2702 * Under direct bindings, the syminfo indicates that a copy will be 2703 * taken (SYMINFO_FLG_COPY). This can only be set in an executable. 2704 * Thus, the caller must be the executable, so bind to the destination 2705 * of the copy within the executable. 2706 */ 2707 if (((slp->sl_flags & LKUP_COPY) == 0) && 2708 (sip->si_flags & SYMINFO_FLG_COPY)) { 2709 2710 slp->sl_imap = LIST(clmp)->lm_head; 2711 if (sym = SYMINTP(clmp)(slp, dlmp, binfo, in_nfavl)) 2712 *binfo |= (DBG_BINFO_DIRECT | DBG_BINFO_COPYREF); 2713 return (sym); 2714 } 2715 2716 /* 2717 * If we need to directly bind to our parent, start looking in each 2718 * callers link map. 2719 */ 2720 sl = *slp; 2721 sl.sl_flags |= LKUP_DIRECT; 2722 sym = 0; 2723 2724 if (sip->si_boundto == SYMINFO_BT_PARENT) { 2725 Aliste idx1; 2726 Bnd_desc *bdp; 2727 Grp_hdl *ghp; 2728 2729 /* 2730 * Determine the parent of this explicit dependency from its 2731 * CALLERS()'s list. 2732 */ 2733 for (APLIST_TRAVERSE(CALLERS(clmp), idx1, bdp)) { 2734 sl.sl_imap = lmp = bdp->b_caller; 2735 if ((sym = SYMINTP(lmp)(&sl, dlmp, binfo, 2736 in_nfavl)) != NULL) 2737 goto found; 2738 } 2739 2740 /* 2741 * A caller can also be defined as the parent of a dlopen() 2742 * call. Determine whether this object has any handles. The 2743 * dependencies maintained with the handle represent the 2744 * explicit dependencies of the dlopen()'ed object, and the 2745 * calling parent. 2746 */ 2747 for (APLIST_TRAVERSE(HANDLES(clmp), idx1, ghp)) { 2748 Grp_desc *gdp; 2749 Aliste idx2; 2750 2751 for (ALIST_TRAVERSE(ghp->gh_depends, idx2, gdp)) { 2752 if ((gdp->gd_flags & GPD_PARENT) == 0) 2753 continue; 2754 sl.sl_imap = lmp = gdp->gd_depend; 2755 if ((sym = SYMINTP(lmp)(&sl, dlmp, 2756 binfo, in_nfavl)) != NULL) 2757 goto found; 2758 } 2759 } 2760 } else { 2761 /* 2762 * If we need to direct bind to anything else look in the 2763 * link map associated with this symbol reference. 2764 */ 2765 if (sip->si_boundto == SYMINFO_BT_SELF) 2766 sl.sl_imap = lmp = clmp; 2767 else 2768 sl.sl_imap = lmp; 2769 2770 if (lmp) 2771 sym = SYMINTP(lmp)(&sl, dlmp, binfo, in_nfavl); 2772 } 2773 found: 2774 if (sym) 2775 *binfo |= DBG_BINFO_DIRECT; 2776 2777 /* 2778 * If we've bound to an object, determine whether that object can be 2779 * interposed upon for this symbol. 2780 */ 2781 if (sym && (LIST(*dlmp)->lm_head != *dlmp) && 2782 (LIST(*dlmp) == LIST(clmp))) { 2783 Sym *isym; 2784 2785 if ((isym = lookup_sym_interpose(slp, dlmp, binfo, 2786 LIST(*dlmp), sym, in_nfavl)) != 0) 2787 return (isym); 2788 } 2789 2790 return (sym); 2791 } 2792 2793 static Sym * 2794 core_lookup_sym(Rt_map *ilmp, Slookup *slp, Rt_map **dlmp, uint_t *binfo, 2795 Aliste off, int *in_nfavl) 2796 { 2797 Rt_map *lmp; 2798 2799 /* 2800 * Copy relocations should start their search after the head of the 2801 * main link-map control list. 2802 */ 2803 if ((off == ALIST_OFF_DATA) && (slp->sl_flags & LKUP_COPY) && ilmp) 2804 lmp = (Rt_map *)NEXT(ilmp); 2805 else 2806 lmp = ilmp; 2807 2808 for (; lmp; lmp = (Rt_map *)NEXT(lmp)) { 2809 if (callable(slp->sl_cmap, lmp, 0, slp->sl_flags)) { 2810 Sym *sym; 2811 2812 slp->sl_imap = lmp; 2813 if (((sym = SYMINTP(lmp)(slp, dlmp, binfo, 2814 in_nfavl)) != NULL) || (*binfo & BINFO_REJSINGLE)) 2815 return (sym); 2816 } 2817 } 2818 return (0); 2819 } 2820 2821 static Sym * 2822 _lazy_find_sym(Rt_map *ilmp, Slookup *slp, Rt_map **dlmp, uint_t *binfo, 2823 int *in_nfavl) 2824 { 2825 Rt_map *lmp; 2826 2827 for (lmp = ilmp; lmp; lmp = (Rt_map *)NEXT(lmp)) { 2828 if (LAZY(lmp) == 0) 2829 continue; 2830 if (callable(slp->sl_cmap, lmp, 0, slp->sl_flags)) { 2831 Sym *sym; 2832 2833 slp->sl_imap = lmp; 2834 if ((sym = elf_lazy_find_sym(slp, dlmp, binfo, 2835 in_nfavl)) != 0) 2836 return (sym); 2837 } 2838 } 2839 return (0); 2840 } 2841 2842 static Sym * 2843 _lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo, int *in_nfavl) 2844 { 2845 const char *name = slp->sl_name; 2846 Rt_map *clmp = slp->sl_cmap; 2847 Lm_list *lml = LIST(clmp); 2848 Rt_map *ilmp = slp->sl_imap, *lmp; 2849 ulong_t rsymndx; 2850 Sym *sym; 2851 Syminfo *sip; 2852 Slookup sl; 2853 2854 /* 2855 * Search the initial link map for the required symbol (this category is 2856 * selected by dlsym(), where individual link maps are searched for a 2857 * required symbol. Therefore, we know we have permission to look at 2858 * the link map). 2859 */ 2860 if (slp->sl_flags & LKUP_FIRST) 2861 return (SYMINTP(ilmp)(slp, dlmp, binfo, in_nfavl)); 2862 2863 /* 2864 * Determine whether this lookup can be satisfied by an objects direct, 2865 * or lazy binding information. This is triggered by a relocation from 2866 * the object (hence rsymndx is set). 2867 */ 2868 if (((rsymndx = slp->sl_rsymndx) != 0) && 2869 ((sip = SYMINFO(clmp)) != NULL)) { 2870 uint_t bound; 2871 2872 /* 2873 * Find the corresponding Syminfo entry for the original 2874 * referencing symbol. 2875 */ 2876 /* LINTED */ 2877 sip = (Syminfo *)((char *)sip + (rsymndx * SYMINENT(clmp))); 2878 bound = sip->si_boundto; 2879 2880 /* 2881 * Identify any EXTERN or PARENT references for ldd(1). 2882 */ 2883 if ((lml->lm_flags & LML_FLG_TRC_WARN) && 2884 (bound > SYMINFO_BT_LOWRESERVE)) { 2885 if (bound == SYMINFO_BT_PARENT) 2886 *binfo |= DBG_BINFO_REF_PARENT; 2887 if (bound == SYMINFO_BT_EXTERN) 2888 *binfo |= DBG_BINFO_REF_EXTERN; 2889 } 2890 2891 /* 2892 * If the symbol information indicates a direct binding, 2893 * determine the link map that is required to satisfy the 2894 * binding. Note, if the dependency can not be found, but a 2895 * direct binding isn't required, we will still fall through 2896 * to perform any default symbol search. 2897 */ 2898 if (sip->si_flags & SYMINFO_FLG_DIRECT) { 2899 2900 lmp = 0; 2901 if (bound < SYMINFO_BT_LOWRESERVE) 2902 lmp = elf_lazy_load(clmp, slp, bound, 2903 name, in_nfavl); 2904 2905 /* 2906 * If direct bindings have been disabled, and this isn't 2907 * a translator, skip any direct binding now that we've 2908 * ensured the resolving object has been loaded. 2909 * 2910 * If we need to direct bind to anything, we look in 2911 * ourselves, our parent, or in the link map we've just 2912 * loaded. Otherwise, even though we may have lazily 2913 * loaded an object we still continue to search for 2914 * symbols from the head of the link map list. 2915 */ 2916 if (((FLAGS(clmp) & FLG_RT_TRANS) || 2917 (((lml->lm_tflags & LML_TFLG_NODIRECT) == 0) && 2918 ((slp->sl_flags & LKUP_SINGLETON) == 0))) && 2919 ((FLAGS1(clmp) & FL1_RT_DIRECT) || 2920 (sip->si_flags & SYMINFO_FLG_DIRECTBIND))) { 2921 sym = lookup_sym_direct(slp, dlmp, binfo, 2922 sip, lmp, in_nfavl); 2923 2924 /* 2925 * Determine whether this direct binding has 2926 * been rejected. If we've bound to a singleton 2927 * without following a singleton search, then 2928 * return. The caller detects this condition 2929 * and will trigger a new singleton search. 2930 * 2931 * For any other rejection (such as binding to 2932 * a symbol labeled as nodirect - presumably 2933 * because the symbol definition has been 2934 * changed since the referring object was last 2935 * built), fall through to a standard symbol 2936 * search. 2937 */ 2938 if (((*binfo & BINFO_REJECTED) == 0) || 2939 (*binfo & BINFO_REJSINGLE)) 2940 return (sym); 2941 2942 *binfo &= ~BINFO_REJECTED; 2943 } 2944 } 2945 } 2946 2947 /* 2948 * Duplicate the lookup information, as we'll need to modify this 2949 * information for some of the following searches. 2950 */ 2951 sl = *slp; 2952 2953 /* 2954 * If the referencing object has the DF_SYMBOLIC flag set, look in the 2955 * referencing object for the symbol first. Failing that, fall back to 2956 * our generic search. 2957 */ 2958 if ((FLAGS1(clmp) & FL1_RT_SYMBOLIC) && 2959 ((sl.sl_flags & LKUP_SINGLETON) == 0)) { 2960 sl.sl_imap = clmp; 2961 if (sym = SYMINTP(clmp)(&sl, dlmp, binfo, in_nfavl)) { 2962 ulong_t dsymndx = (((ulong_t)sym - 2963 (ulong_t)SYMTAB(*dlmp)) / SYMENT(*dlmp)); 2964 2965 /* 2966 * Make sure this symbol hasn't explicitly been defined 2967 * as nodirect. 2968 */ 2969 if (((sip = SYMINFO(*dlmp)) == 0) || 2970 /* LINTED */ 2971 ((sip = (Syminfo *)((char *)sip + 2972 (dsymndx * SYMINENT(*dlmp)))) == 0) || 2973 ((sip->si_flags & SYMINFO_FLG_NOEXTDIRECT) == 0)) 2974 return (sym); 2975 } 2976 } 2977 2978 sl.sl_flags |= LKUP_STANDARD; 2979 2980 /* 2981 * If this lookup originates from a standard relocation, then traverse 2982 * all link-map control lists, inspecting any object that is available 2983 * to this caller. Otherwise, traverse the link-map control list 2984 * associated with the caller. 2985 */ 2986 if (sl.sl_flags & LKUP_STDRELOC) { 2987 Aliste off; 2988 Lm_cntl *lmc; 2989 2990 sym = NULL; 2991 2992 for (ALIST_TRAVERSE_BY_OFFSET(lml->lm_lists, off, lmc)) { 2993 if (((sym = core_lookup_sym(lmc->lc_head, &sl, dlmp, 2994 binfo, off, in_nfavl)) != NULL) || 2995 (*binfo & BINFO_REJSINGLE)) 2996 break; 2997 } 2998 } else 2999 sym = core_lookup_sym(ilmp, &sl, dlmp, binfo, ALIST_OFF_DATA, 3000 in_nfavl); 3001 3002 /* 3003 * If a symbol binding was rejected, because a binding occurred to a 3004 * singleton without following the default symbol search, return so 3005 * that the search can be repreated. 3006 */ 3007 if (*binfo & BINFO_REJSINGLE) 3008 return (sym); 3009 3010 /* 3011 * To allow transitioning into a world of lazy loading dependencies see 3012 * if this link map contains objects that have lazy dependencies still 3013 * outstanding. If so, and we haven't been able to locate a non-weak 3014 * symbol reference, start bringing in any lazy dependencies to see if 3015 * the reference can be satisfied. Use of dlsym(RTLD_PROBE) sets the 3016 * LKUP_NOFALLBACK flag, and this flag disables this fall back. 3017 */ 3018 if ((sym == NULL) && ((sl.sl_flags & LKUP_NOFALLBACK) == 0)) { 3019 if ((lmp = ilmp) == 0) 3020 lmp = LIST(clmp)->lm_head; 3021 3022 lml = LIST(lmp); 3023 if ((sl.sl_flags & LKUP_WEAK) || (lml->lm_lazy == 0)) 3024 return ((Sym *)0); 3025 3026 DBG_CALL(Dbg_syms_lazy_rescan(lml, name)); 3027 3028 /* 3029 * If this request originated from a dlsym(RTLD_NEXT) then start 3030 * looking for dependencies from the caller, otherwise use the 3031 * initial link-map. 3032 */ 3033 if (sl.sl_flags & LKUP_NEXT) 3034 sym = _lazy_find_sym(clmp, &sl, dlmp, binfo, in_nfavl); 3035 else { 3036 Aliste idx; 3037 Lm_cntl *lmc; 3038 3039 for (ALIST_TRAVERSE(lml->lm_lists, idx, lmc)) { 3040 sl.sl_flags |= LKUP_NOFALLBACK; 3041 if ((sym = _lazy_find_sym(lmc->lc_head, &sl, 3042 dlmp, binfo, in_nfavl)) != 0) 3043 break; 3044 } 3045 } 3046 } 3047 return (sym); 3048 } 3049 3050 /* 3051 * Symbol lookup routine. Takes an ELF symbol name, and a list of link maps to 3052 * search. If successful, return a pointer to the symbol table entry, a 3053 * pointer to the link map of the enclosing object, and information relating 3054 * to the type of binding. Else return a null pointer. 3055 * 3056 * To improve elf performance, we first compute the elf hash value and pass 3057 * it to each find_sym() routine. The elf function will use this value to 3058 * locate the symbol, the a.out function will simply ignore it. 3059 */ 3060 Sym * 3061 lookup_sym(Slookup *slp, Rt_map **dlmp, uint_t *binfo, int *in_nfavl) 3062 { 3063 Rt_map *clmp = slp->sl_cmap; 3064 Sym *rsym = slp->sl_rsym, *sym = 0; 3065 uchar_t rtype = slp->sl_rtype; 3066 3067 if (slp->sl_hash == 0) 3068 slp->sl_hash = elf_hash(slp->sl_name); 3069 *binfo = 0; 3070 3071 /* 3072 * Establish any state that might be associated with a symbol reference. 3073 */ 3074 if (rsym) { 3075 if ((slp->sl_flags & LKUP_STDRELOC) && 3076 (ELF_ST_BIND(rsym->st_info) == STB_WEAK)) 3077 slp->sl_flags |= LKUP_WEAK; 3078 3079 if (ELF_ST_VISIBILITY(rsym->st_other) == STV_SINGLETON) 3080 slp->sl_flags |= LKUP_SINGLETON; 3081 } 3082 3083 /* 3084 * Establish any lookup state required for this type of relocation. 3085 */ 3086 if ((slp->sl_flags & LKUP_STDRELOC) && rtype) { 3087 if (rtype == M_R_COPY) 3088 slp->sl_flags |= LKUP_COPY; 3089 3090 if (rtype != M_R_JMP_SLOT) 3091 slp->sl_flags |= LKUP_SPEC; 3092 } 3093 3094 /* 3095 * Under ldd -w, any unresolved weak references are diagnosed. Set the 3096 * symbol binding as global to trigger a relocation error if the symbol 3097 * can not be found. 3098 */ 3099 if (rsym) { 3100 if (LIST(slp->sl_cmap)->lm_flags & LML_FLG_TRC_NOUNRESWEAK) 3101 slp->sl_bind = STB_GLOBAL; 3102 else if ((slp->sl_bind = ELF_ST_BIND(rsym->st_info)) == 3103 STB_WEAK) 3104 slp->sl_flags |= LKUP_WEAK; 3105 } 3106 3107 /* 3108 * Carry out an initial symbol search. This search takes into account 3109 * all the modes of the requested search. 3110 */ 3111 if (((sym = _lookup_sym(slp, dlmp, binfo, in_nfavl)) == NULL) && 3112 (*binfo & BINFO_REJSINGLE)) { 3113 Slookup sl = *slp; 3114 3115 /* 3116 * If a binding has been rejected because of binding to a 3117 * singleton without going through a singleton search, then 3118 * reset the lookup data, and try again. 3119 */ 3120 sl.sl_imap = LIST(sl.sl_cmap)->lm_head; 3121 sl.sl_flags &= ~(LKUP_FIRST | LKUP_SELF | LKUP_NEXT); 3122 sl.sl_flags |= LKUP_SINGLETON; 3123 sl.sl_rsymndx = 0; 3124 *binfo &= ~BINFO_REJECTED; 3125 sym = _lookup_sym(&sl, dlmp, binfo, in_nfavl); 3126 } 3127 3128 /* 3129 * If the caller is restricted to a symbol search within its group, 3130 * determine if it is necessary to follow a binding from outside of 3131 * the group. 3132 */ 3133 if (sym && ((MODE(clmp) & (RTLD_GROUP | RTLD_WORLD)) == RTLD_GROUP)) { 3134 Sym *isym; 3135 3136 if ((isym = lookup_sym_interpose(slp, dlmp, binfo, LIST(*dlmp), 3137 sym, in_nfavl)) != 0) 3138 return (isym); 3139 } 3140 return (sym); 3141 } 3142 3143 /* 3144 * Associate a binding descriptor with a caller and its dependency, or update 3145 * an existing descriptor. 3146 */ 3147 int 3148 bind_one(Rt_map *clmp, Rt_map *dlmp, uint_t flags) 3149 { 3150 Bnd_desc *bdp; 3151 Aliste idx; 3152 int found = ALE_CREATE; 3153 3154 /* 3155 * Determine whether a binding descriptor already exists between the 3156 * two objects. 3157 */ 3158 for (APLIST_TRAVERSE(DEPENDS(clmp), idx, bdp)) { 3159 if (bdp->b_depend == dlmp) { 3160 found = ALE_EXISTS; 3161 break; 3162 } 3163 } 3164 3165 if (found == ALE_CREATE) { 3166 /* 3167 * Create a new binding descriptor. 3168 */ 3169 if ((bdp = malloc(sizeof (Bnd_desc))) == 0) 3170 return (0); 3171 3172 bdp->b_caller = clmp; 3173 bdp->b_depend = dlmp; 3174 bdp->b_flags = 0; 3175 3176 /* 3177 * Append the binding descriptor to the caller and the 3178 * dependency. 3179 */ 3180 if (aplist_append(&DEPENDS(clmp), bdp, AL_CNT_DEPENDS) == 0) 3181 return (0); 3182 3183 if (aplist_append(&CALLERS(dlmp), bdp, AL_CNT_CALLERS) == 0) 3184 return (0); 3185 } 3186 3187 if ((found == ALE_CREATE) || ((bdp->b_flags & flags) != flags)) { 3188 bdp->b_flags |= flags; 3189 3190 if (flags & BND_REFER) 3191 FLAGS1(dlmp) |= FL1_RT_USED; 3192 3193 DBG_CALL(Dbg_file_bind_entry(LIST(clmp), bdp)); 3194 } 3195 return (found); 3196 } 3197 3198 /* 3199 * Cleanup after relocation processing. 3200 */ 3201 int 3202 relocate_finish(Rt_map *lmp, APlist *bound, int textrel, int ret) 3203 { 3204 DBG_CALL(Dbg_reloc_run(lmp, 0, ret, DBG_REL_FINISH)); 3205 3206 /* 3207 * Establish bindings to all objects that have been bound to. 3208 */ 3209 if (bound) { 3210 Aliste idx; 3211 Rt_map *_lmp; 3212 Word used; 3213 3214 /* 3215 * Only create bindings if the callers relocation was 3216 * successful (ret != 0), otherwise the object will eventually 3217 * be torn down. Create these bindings if running under ldd(1) 3218 * with the -U/-u options regardless of relocation errors, as 3219 * the unused processing needs to traverse these bindings to 3220 * diagnose unused objects. 3221 */ 3222 used = LIST(lmp)->lm_flags & 3223 (LML_FLG_TRC_UNREF | LML_FLG_TRC_UNUSED); 3224 3225 if (ret || used) { 3226 for (APLIST_TRAVERSE(bound, idx, _lmp)) { 3227 if (bind_one(lmp, _lmp, BND_REFER) || used) 3228 continue; 3229 3230 ret = 0; 3231 break; 3232 } 3233 } 3234 free(bound); 3235 } 3236 3237 /* 3238 * If we write enabled the text segment to perform these relocations 3239 * re-protect by disabling writes. 3240 */ 3241 if (textrel) 3242 (void) LM_SET_PROT(lmp)(lmp, 0); 3243 3244 return (ret); 3245 } 3246