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