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