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