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