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