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