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