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