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