1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 /*
  27  *      Copyright (c) 1988 AT&T
  28  *        All Rights Reserved
  29  */
  30 
  31 #include        <string.h>
  32 #include        <stdio.h>
  33 #include        <unistd.h>
  34 #include        <sys/stat.h>
  35 #include        <sys/mman.h>
  36 #include        <sys/debug.h>
  37 #include        <fcntl.h>
  38 #include        <limits.h>
  39 #include        <dlfcn.h>
  40 #include        <errno.h>
  41 #include        <link.h>
  42 #include        <debug.h>
  43 #include        <conv.h>
  44 #include        "_rtld.h"
  45 #include        "_audit.h"
  46 #include        "_elf.h"
  47 #include        "_a.out.h"
  48 #include        "_inline_gen.h"
  49 #include        "msg.h"
  50 
  51 /*
  52  * If a load filter flag is in effect, and this object is a filter, trigger the
  53  * loading of all its filtees.  The load filter flag is in effect when creating
  54  * configuration files, or when under the control of ldd(1), or the LD_LOADFLTR
  55  * environment variable is set, or this object was built with the -zloadfltr
  56  * flag.  Otherwise, filtee loading is deferred until triggered by a relocation.
  57  */
  58 static void
  59 load_filtees(Rt_map *lmp, int *in_nfavl)
  60 {
  61         if ((FLAGS1(lmp) & MSK_RT_FILTER) &&
  62             ((FLAGS(lmp) & FLG_RT_LOADFLTR) ||
  63             (LIST(lmp)->lm_tflags & LML_TFLG_LOADFLTR))) {
  64                 Dyninfo         *dip =  DYNINFO(lmp);
  65                 uint_t          cnt, max = DYNINFOCNT(lmp);
  66                 Slookup         sl;
  67 
  68                 /*
  69                  * Initialize the symbol lookup data structure.  Note, no symbol
  70                  * name is supplied.  This NULL name causes filters to be loaded
  71                  * but no symbol to be searched for.
  72                  */
  73                 SLOOKUP_INIT(sl, 0, lmp, lmp, ld_entry_cnt, 0, 0, 0, 0, 0);
  74 
  75                 for (cnt = 0; cnt < max; cnt++, dip++) {
  76                         uint_t  binfo;
  77                         Sresult sr;
  78 
  79                         SRESULT_INIT(sr, NULL);
  80 
  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, &sr, &binfo, cnt,
  86                             in_nfavl);
  87                 }
  88         }
  89 }
  90 
  91 /*
  92  * Analyze one or more link-maps of a link map control list.  This routine is
  93  * called at startup to continue the processing of the main executable.  It is
  94  * also called each time a new set of objects are loaded, ie. from filters,
  95  * lazy-loaded objects, or dlopen().
  96  *
  97  * In each instance we traverse the link-map control list starting with the
  98  * initial object.  As dependencies are analyzed they are added to the link-map
  99  * control list.  Thus the list grows as we traverse it - this results in the
 100  * breadth first ordering of all needed objects.
 101  *
 102  * Return the initial link-map from which analysis starts for relocate_lmc().
 103  */
 104 Rt_map *
 105 analyze_lmc(Lm_list *lml, Aliste nlmco, Rt_map *nlmp, Rt_map *clmp,
 106     int *in_nfavl)
 107 {
 108         Rt_map  *lmp;
 109         Lm_cntl *nlmc;
 110 
 111         /*
 112          * If this link-map control list is being analyzed, return.  The object
 113          * that has just been added will be picked up by the existing analysis
 114          * thread.  Note, this is only really meaningful during process init-
 115          * ialization, as objects are added to the main link-map control list.
 116          * Following this initialization, each family of objects that are loaded
 117          * are added to a new link-map control list.
 118          */
 119         /* LINTED */
 120         nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco);
 121         if (nlmc->lc_flags & LMC_FLG_ANALYZING)
 122                 return (nlmp);
 123 
 124         /*
 125          * If this object doesn't belong to the present link-map control list
 126          * then it must already have been analyzed, or it is in the process of
 127          * being analyzed prior to us recursing into this analysis.  In either
 128          * case, ignore the object as it's already being taken care of.
 129          */
 130         if (nlmco != CNTL(nlmp))
 131                 return (nlmp);
 132 
 133         nlmc->lc_flags |= LMC_FLG_ANALYZING;
 134 
 135         for (lmp = nlmp; lmp; lmp = NEXT_RT_MAP(lmp)) {
 136                 if (FLAGS(lmp) &
 137                     (FLG_RT_ANALZING | FLG_RT_ANALYZED | FLG_RT_DELETE))
 138                         continue;
 139 
 140                 /*
 141                  * Indicate that analyzing is under way.
 142                  */
 143                 FLAGS(lmp) |= FLG_RT_ANALZING;
 144 
 145                 /*
 146                  * If this link map represents a relocatable object, then we
 147                  * need to finish the link-editing of the object at this point.
 148                  */
 149                 if (FLAGS(lmp) & FLG_RT_OBJECT) {
 150                         Rt_map  *olmp;
 151 
 152                         if ((olmp = elf_obj_fini(lml, lmp, clmp,
 153                             in_nfavl)) == NULL) {
 154                                 if (lml->lm_flags & LML_FLG_TRC_ENABLE)
 155                                         continue;
 156                                 nlmp = NULL;
 157                                 break;
 158                         }
 159 
 160                         /*
 161                          * The original link-map that captured a relocatable
 162                          * object is a temporary link-map, that basically acts
 163                          * as a place holder in the link-map list.  On
 164                          * completion of relocatable object processing, a new
 165                          * link-map is created, and switched with the place
 166                          * holder.  Therefore, reassign both the present
 167                          * link-map pointer and the return link-map pointer.
 168                          * The former resets this routines link-map processing,
 169                          * while the latter provides for later functions, like
 170                          * relocate_lmc(), to start processing from this new
 171                          * link-map.
 172                          */
 173                         if (nlmp == lmp)
 174                                 nlmp = olmp;
 175                         lmp = olmp;
 176                 }
 177 
 178                 DBG_CALL(Dbg_file_analyze(lmp));
 179 
 180                 /*
 181                  * Establish any dependencies this object requires.
 182                  */
 183                 if (LM_NEEDED(lmp)(lml, nlmco, lmp, in_nfavl) == 0) {
 184                         if (lml->lm_flags & LML_FLG_TRC_ENABLE)
 185                                 continue;
 186                         nlmp = NULL;
 187                         break;
 188                 }
 189 
 190                 FLAGS(lmp) &= ~FLG_RT_ANALZING;
 191                 FLAGS(lmp) |= FLG_RT_ANALYZED;
 192 
 193                 /*
 194                  * If we're building a configuration file, determine if this
 195                  * object is a filter and if so load its filtees.  This
 196                  * traversal is only necessary for crle(1), as typical use of
 197                  * an object will load filters as part of relocation processing.
 198                  */
 199                 if (MODE(nlmp) & RTLD_CONFGEN)
 200                         load_filtees(lmp, in_nfavl);
 201 
 202                 /*
 203                  * If an interposer has been added, it will have been inserted
 204                  * in the link-map before the link we're presently analyzing.
 205                  * Break out of this analysis loop and return to the head of
 206                  * the link-map control list to analyze the interposer.  Note
 207                  * that this rescan preserves the breadth first loading of
 208                  * dependencies.
 209                  */
 210                 /* LINTED */
 211                 nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco);
 212                 if (nlmc->lc_flags & LMC_FLG_REANALYZE) {
 213                         nlmc->lc_flags &= ~LMC_FLG_REANALYZE;
 214                         lmp = nlmc->lc_head;
 215                 }
 216         }
 217 
 218         /* LINTED */
 219         nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco);
 220         nlmc->lc_flags &= ~LMC_FLG_ANALYZING;
 221 
 222         return (nlmp);
 223 }
 224 
 225 /*
 226  * Determine whether a symbol represents zero, .bss, bits.  Most commonly this
 227  * function is used to determine whether the data for a copy relocation refers
 228  * to initialized data or .bss.  If the data definition is within .bss, then the
 229  * data is zero filled, and as the copy destination within the executable is
 230  * .bss, we can skip copying zero's to zero's.
 231  *
 232  * However, if the defining object has MOVE data, it's .bss might contain
 233  * non-zero data, in which case copy the definition regardless.
 234  *
 235  * For backward compatibility copy relocation processing, this routine can be
 236  * used to determine precisely if a copy destination is a move record recipient.
 237  */
 238 static int
 239 are_bits_zero(Rt_map *dlmp, Sym *dsym, int dest)
 240 {
 241         mmapobj_result_t        *mpp;
 242         caddr_t                 daddr = (caddr_t)dsym->st_value;
 243 
 244         if ((FLAGS(dlmp) & FLG_RT_FIXED) == 0)
 245                 daddr += ADDR(dlmp);
 246 
 247         /*
 248          * Determine the segment that contains the copy definition.  Given that
 249          * the copy relocation records have already been captured and verified,
 250          * a segment must be found (but we add an escape clause never the less).
 251          */
 252         if ((mpp = find_segment(daddr, dlmp)) == NULL)
 253                 return (1);
 254 
 255         /*
 256          * If the definition is not within .bss, indicate this is not zero data.
 257          */
 258         if (daddr < (mpp->mr_addr + mpp->mr_offset + mpp->mr_fsize))
 259                 return (0);
 260 
 261         /*
 262          * If the definition is within .bss, make sure the definition isn't the
 263          * recipient of a move record.  Note, we don't precisely analyze whether
 264          * the address is a move record recipient, as the infrastructure to
 265          * prepare for, and carry out this analysis, is probably more costly
 266          * than just copying the bytes regardless.
 267          */
 268         if ((FLAGS(dlmp) & FLG_RT_MOVE) == 0)
 269                 return (1);
 270 
 271         /*
 272          * However, for backward compatibility copy relocation processing, we
 273          * can afford to work a little harder.  Here, determine precisely
 274          * whether the destination in the executable is a move record recipient.
 275          * See comments in lookup_sym_interpose(), below.
 276          */
 277         if (dest && is_move_data(daddr))
 278                 return (0);
 279 
 280         return (1);
 281 }
 282 
 283 /*
 284  * Relocate an individual object.
 285  */
 286 static int
 287 relocate_so(Lm_list *lml, Rt_map *lmp, int *relocated, int now, int *in_nfavl)
 288 {
 289         APlist  *textrel = NULL;
 290         int     ret = 1;
 291 
 292         /*
 293          * If we're running under ldd(1), and haven't been asked to trace any
 294          * warnings, skip any actual relocation processing.
 295          */
 296         if (((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0) ||
 297             (lml->lm_flags & LML_FLG_TRC_WARN)) {
 298 
 299                 if (relocated)
 300                         (*relocated)++;
 301 
 302                 if ((LM_RELOC(lmp)(lmp, now, in_nfavl, &textrel) == 0) &&
 303                     ((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0))
 304                         ret = 0;
 305 
 306                 /*
 307                  * Finally process any move data.  Note, this is carried out
 308                  * with ldd(1) under relocation processing too, as it can flush
 309                  * out move errors, and enables lari(1) to provide a true
 310                  * representation of the runtime bindings.
 311                  */
 312                 if ((FLAGS(lmp) & FLG_RT_MOVE) &&
 313                     (move_data(lmp, &textrel) == 0) &&
 314                     ((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0))
 315                         ret = 0;
 316         }
 317 
 318         /*
 319          * If a text segment was write enabled to perform any relocations or
 320          * move records, then re-protect the segment by disabling writes.
 321          */
 322         if (textrel) {
 323                 mmapobj_result_t        *mpp;
 324                 Aliste                  idx;
 325 
 326                 for (APLIST_TRAVERSE(textrel, idx, mpp))
 327                         (void) set_prot(lmp, mpp, 0);
 328                 free(textrel);
 329         }
 330 
 331         return (ret);
 332 }
 333 
 334 /*
 335  * Relocate the objects on a link-map control list.
 336  */
 337 static int
 338 _relocate_lmc(Lm_list *lml, Aliste lmco, Rt_map *nlmp, int *relocated,
 339     int *in_nfavl)
 340 {
 341         Rt_map  *lmp;
 342 
 343         for (lmp = nlmp; lmp; lmp = NEXT_RT_MAP(lmp)) {
 344                 /*
 345                  * If this object has already been relocated, we're done.  If
 346                  * this object is being deleted, skip it, there's probably a
 347                  * relocation error somewhere that's causing this deletion.
 348                  */
 349                 if (FLAGS(lmp) &
 350                     (FLG_RT_RELOCING | FLG_RT_RELOCED | FLG_RT_DELETE))
 351                         continue;
 352 
 353                 /*
 354                  * Indicate that relocation processing is under way.
 355                  */
 356                 FLAGS(lmp) |= FLG_RT_RELOCING;
 357 
 358                 /*
 359                  * Relocate the object.
 360                  */
 361                 if (relocate_so(lml, lmp, relocated, 0, in_nfavl) == 0)
 362                         return (0);
 363 
 364                 /*
 365                  * Indicate that the objects relocation is complete.
 366                  */
 367                 FLAGS(lmp) &= ~FLG_RT_RELOCING;
 368                 FLAGS(lmp) |= FLG_RT_RELOCED;
 369 
 370                 /*
 371                  * If this object is being relocated on the main link-map list
 372                  * indicate that this object's init is available for harvesting.
 373                  * Objects that are being collected on other link-map lists
 374                  * will have there init availability tagged when the objects
 375                  * are move to the main link-map list (ie, after we know they,
 376                  * and their dependencies, are fully relocated and ready for
 377                  * use).
 378                  *
 379                  * Note, even under ldd(1) this init identification is necessary
 380                  * for -i (tsort) gathering.
 381                  */
 382                 if (lmco == ALIST_OFF_DATA) {
 383                         lml->lm_init++;
 384                         lml->lm_flags |= LML_FLG_OBJADDED;
 385                 }
 386 
 387                 /*
 388                  * Determine if this object is a filter, and if a load filter
 389                  * flag is in effect, trigger the loading of all its filtees.
 390                  */
 391                 load_filtees(lmp, in_nfavl);
 392         }
 393 
 394         /*
 395          * Perform special copy relocations.  These are only meaningful for
 396          * dynamic executables (fixed and head of their link-map list).  If
 397          * this ever has to change then the infrastructure of COPY() has to
 398          * change. Presently, a given link map can only have a receiver or
 399          * supplier of copy data, so a union is used to overlap the storage
 400          * for the COPY_R() and COPY_S() lists. These lists would need to
 401          * be separated.
 402          */
 403         if ((FLAGS(nlmp) & FLG_RT_FIXED) && (nlmp == LIST(nlmp)->lm_head) &&
 404             (((lml->lm_flags & LML_FLG_TRC_ENABLE) == 0) ||
 405             (lml->lm_flags & LML_FLG_TRC_WARN))) {
 406                 Rt_map          *lmp;
 407                 Aliste          idx1;
 408                 Word            tracing;
 409 
 410 #if     defined(__i386)
 411                 if (elf_copy_gen(nlmp) == 0)
 412                         return (0);
 413 #endif
 414                 if (COPY_S(nlmp) == NULL)
 415                         return (1);
 416 
 417                 if ((LIST(nlmp)->lm_flags & LML_FLG_TRC_ENABLE) &&
 418                     (((rtld_flags & RT_FL_SILENCERR) == 0) ||
 419                     (LIST(nlmp)->lm_flags & LML_FLG_TRC_VERBOSE)))
 420                         tracing = 1;
 421                 else
 422                         tracing = 0;
 423 
 424                 DBG_CALL(Dbg_util_nl(lml, DBG_NL_STD));
 425 
 426                 for (APLIST_TRAVERSE(COPY_S(nlmp), idx1, lmp)) {
 427                         Rel_copy        *rcp;
 428                         Aliste          idx2;
 429 
 430                         for (ALIST_TRAVERSE(COPY_R(lmp), idx2, rcp)) {
 431                                 int zero;
 432 
 433                                 /*
 434                                  * Only copy the data if the data is from
 435                                  * a non-zero definition (ie. not .bss).
 436                                  */
 437                                 zero = are_bits_zero(rcp->r_dlmp,
 438                                     rcp->r_dsym, 0);
 439                                 DBG_CALL(Dbg_reloc_copy(rcp->r_dlmp, nlmp,
 440                                     rcp->r_name, zero));
 441                                 if (zero)
 442                                         continue;
 443 
 444                                 (void) memcpy(rcp->r_radd, rcp->r_dadd,
 445                                     rcp->r_size);
 446 
 447                                 if ((tracing == 0) || ((FLAGS1(rcp->r_dlmp) &
 448                                     FL1_RT_DISPREL) == 0))
 449                                         continue;
 450 
 451                                 (void) printf(MSG_INTL(MSG_LDD_REL_CPYDISP),
 452                                     demangle(rcp->r_name), NAME(rcp->r_dlmp));
 453                         }
 454                 }
 455 
 456                 DBG_CALL(Dbg_util_nl(lml, DBG_NL_STD));
 457 
 458                 free(COPY_S(nlmp));
 459                 COPY_S(nlmp) = NULL;
 460         }
 461         return (1);
 462 }
 463 
 464 int
 465 relocate_lmc(Lm_list *lml, Aliste nlmco, Rt_map *clmp, Rt_map *nlmp,
 466     int *in_nfavl)
 467 {
 468         int     lret = 1, pret = 1;
 469         APlist  *alp;
 470         Aliste  plmco;
 471         Lm_cntl *plmc, *nlmc;
 472 
 473         /*
 474          * If this link-map control list is being relocated, return.  The object
 475          * that has just been added will be picked up by the existing relocation
 476          * thread.  Note, this is only really meaningful during process init-
 477          * ialization, as objects are added to the main link-map control list.
 478          * Following this initialization, each family of objects that are loaded
 479          * are added to a new link-map control list.
 480          */
 481         /* LINTED */
 482         nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco);
 483 
 484         if (nlmc->lc_flags & LMC_FLG_RELOCATING)
 485                 return (1);
 486 
 487         nlmc->lc_flags |= LMC_FLG_RELOCATING;
 488 
 489         /*
 490          * Relocate one or more link-maps of a link map control list.  If this
 491          * object doesn't belong to the present link-map control list then it
 492          * must already have been relocated, or it is in the process of being
 493          * relocated prior to us recursing into this relocation.  In either
 494          * case, ignore the object as it's already being taken care of, however,
 495          * fall through and capture any relocation promotions that might have
 496          * been established from the reference mode of this object.
 497          *
 498          * If we're generating a configuration file using crle(1), two passes
 499          * may be involved.  Under the first pass, RTLD_CONFGEN is set.  Under
 500          * this pass, crle() loads objects into the process address space.  No
 501          * relocation is necessary at this point, we simply need to analyze the
 502          * objects to ensure any directly bound dependencies, filtees, etc.
 503          * get loaded.  Although we skip the relocation, fall through to ensure
 504          * any control lists are maintained appropriately.
 505          *
 506          * If objects are to be dldump(3c)'ed, crle(1) makes a second pass,
 507          * using RTLD_NOW and RTLD_CONFGEN.  The RTLD_NOW effectively carries
 508          * out the relocations of all loaded objects.
 509          */
 510         if ((nlmco == CNTL(nlmp)) &&
 511             ((MODE(nlmp) & (RTLD_NOW | RTLD_CONFGEN)) != RTLD_CONFGEN)) {
 512                 int     relocated = 0;
 513 
 514                 /*
 515                  * Determine whether the initial link-map control list has
 516                  * started relocation.  From this point, should any interposing
 517                  * objects be added to this link-map control list, the objects
 518                  * are demoted to standard objects.  Their interposition can't
 519                  * be guaranteed once relocations have been carried out.
 520                  */
 521                 if (nlmco == ALIST_OFF_DATA)
 522                         lml->lm_flags |= LML_FLG_STARTREL;
 523 
 524                 /*
 525                  * Relocate the link-map control list.  Should this relocation
 526                  * fail, clean up this link-map list.  Relocations within this
 527                  * list may have required relocation promotions on other lists,
 528                  * so before acting upon these, and possibly adding more objects
 529                  * to the present link-map control list, try and clean up any
 530                  * failed objects now.
 531                  */
 532                 lret = _relocate_lmc(lml, nlmco, nlmp, &relocated, in_nfavl);
 533                 if ((lret == 0) && (nlmco != ALIST_OFF_DATA))
 534                         remove_lmc(lml, clmp, nlmco, NAME(nlmp));
 535         }
 536 
 537         /*
 538          * Determine the new, and previous link-map control lists.
 539          */
 540         /* LINTED */
 541         nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco);
 542         if (nlmco == ALIST_OFF_DATA) {
 543                 plmco = nlmco;
 544                 plmc = nlmc;
 545         } else {
 546                 plmco = nlmco - lml->lm_lists->al_size;
 547                 /* LINTED */
 548                 plmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, plmco);
 549         }
 550 
 551         /*
 552          * Having completed this control list of objects, they can now be bound
 553          * to from other objects.  Move this control list to the control list
 554          * that precedes it.  Although this control list may have only bound to
 555          * controls lists much higher up the control list stack, it must only
 556          * be moved up one control list so as to preserve the link-map order
 557          * that may have already been traversed in search of symbols.
 558          */
 559         if (lret && (nlmco != ALIST_OFF_DATA) && nlmc->lc_head)
 560                 lm_move(lml, nlmco, plmco, nlmc, plmc);
 561 
 562         /*
 563          * Determine whether existing objects that have already been relocated,
 564          * need any additional relocations performed.  This can occur when new
 565          * objects are loaded with RTLD_NOW, and these new objects have
 566          * dependencies on objects that are already loaded.  Note, that we peel
 567          * any relocation promotions off of one control list at a time.  This
 568          * prevents relocations from being bound to objects that might yet fail
 569          * to relocate themselves.
 570          */
 571         while ((alp = plmc->lc_now) != NULL) {
 572                 Aliste  idx;
 573                 Rt_map  *lmp;
 574 
 575                 /*
 576                  * Remove the relocation promotion list, as performing more
 577                  * relocations may result in discovering more objects that need
 578                  * promotion.
 579                  */
 580                 plmc->lc_now = NULL;
 581 
 582                 for (APLIST_TRAVERSE(alp, idx, lmp)) {
 583                         /*
 584                          * If the original relocation of the link-map control
 585                          * list failed, or one of the relocation promotions of
 586                          * this loop has failed, demote any pending objects
 587                          * relocation mode.
 588                          */
 589                         if ((lret == 0) || (pret == 0)) {
 590                                 MODE(lmp) &= ~RTLD_NOW;
 591                                 MODE(lmp) |= RTLD_LAZY;
 592                                 continue;
 593                         }
 594 
 595                         /*
 596                          * If a relocation fails, save the error condition.
 597                          * It's possible that all new objects on the original
 598                          * link-map control list have been relocated
 599                          * successfully, but if the user request requires
 600                          * promoting objects that have already been loaded, we
 601                          * have to indicate that this operation couldn't be
 602                          * performed.  The unrelocated objects are in use on
 603                          * another control list, and may continue to be used.
 604                          * If the .plt that resulted in the error is called,
 605                          * then the process will receive a fatal error at that
 606                          * time.  But, the .plt may never be called.
 607                          */
 608                         if (relocate_so(lml, lmp, 0, 1, in_nfavl) == 0)
 609                                 pret = 0;
 610                 }
 611 
 612                 /*
 613                  * Having promoted any objects, determine whether additional
 614                  * dependencies were added, and if so move them to the previous
 615                  * link-map control list.
 616                  */
 617                 /* LINTED */
 618                 nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco);
 619                 /* LINTED */
 620                 plmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, plmco);
 621                 if ((nlmco != ALIST_OFF_DATA) && nlmc->lc_head)
 622                         lm_move(lml, nlmco, plmco, nlmc, plmc);
 623                 free(alp);
 624         }
 625 
 626         /*
 627          * If relocations have been successful, indicate that relocations are
 628          * no longer active for this control list.  Otherwise, leave the
 629          * relocation flag, as this flag is used to determine the style of
 630          * cleanup (see remove_lmc()).
 631          */
 632         if (lret && pret) {
 633                 /* LINTED */
 634                 nlmc = (Lm_cntl *)alist_item_by_offset(lml->lm_lists, nlmco);
 635                 nlmc->lc_flags &= ~LMC_FLG_RELOCATING;
 636 
 637                 return (1);
 638         }
 639 
 640         return (0);
 641 }
 642 
 643 /*
 644  * Inherit the first rejection message for possible later diagnostics.
 645  *
 646  * Any attempt to process a file that is unsuccessful, should be accompanied
 647  * with an error diagnostic.  However, some operations like searching for a
 648  * simple filename, involve trying numerous paths, and an error message for each
 649  * lookup is not required.  Although a multiple search can fail, it's possible
 650  * that a file was found, but was rejected because it was the wrong type.
 651  * To satisfy these possibilities, the first failure is recorded as a rejection
 652  * message, and this message is used later for a more specific diagnostic.
 653  *
 654  * File searches are focused at load_one(), and from here a rejection descriptor
 655  * is passed down to various child routines.  If these child routines can
 656  * process multiple files, then they will maintain their own rejection desc-
 657  * riptor.  This is filled in for any failures, and a diagnostic produced to
 658  * reflect the failure.  The child routines then employ rejection_inherit() to
 659  * pass the first rejection message back to load_one().
 660  *
 661  * Note that the name, and rejection string must be duplicated, as the name
 662  * buffer and error string buffer (see conv_ routines) may be reused for
 663  * additional processing or rejection messages.
 664  */
 665 void
 666 rejection_inherit(Rej_desc *rej1, Rej_desc *rej2)
 667 {
 668         if (rej2->rej_type && (rej1->rej_type == 0)) {
 669                 rej1->rej_type = rej2->rej_type;
 670                 rej1->rej_info = rej2->rej_info;
 671                 rej1->rej_flags = rej2->rej_flags;
 672                 if (rej2->rej_name)
 673                         rej1->rej_name = stravl_insert(rej2->rej_name, 0, 0, 0);
 674                 if ((rej2->rej_str) && ((rej1->rej_str =
 675                     stravl_insert(rej2->rej_str, 0, 0, 0)) == NULL))
 676                         rej1->rej_str = MSG_ORIG(MSG_EMG_ENOMEM);
 677         }
 678 }
 679 
 680 /*
 681  * Helper routine for is_so_matched() that consolidates matching a path name,
 682  * or file name component of a link-map name.
 683  */
 684 inline static int
 685 _is_so_matched(const char *name, const char *str, int path)
 686 {
 687         const char      *_str;
 688 
 689         if ((path == 0) && ((_str = strrchr(str, '/')) != NULL))
 690                 _str++;
 691         else
 692                 _str = str;
 693 
 694         return (strcmp(name, _str));
 695 }
 696 
 697 /*
 698  * Determine whether a search name matches one of the names associated with a
 699  * link-map.  A link-map contains several names:
 700  *
 701  *  -   a NAME() - this is the basename of the dynamic executable that started
 702  *      the process, and the path name of any dependencies used by the process.
 703  *      Most executables are received as full path names, as exec() prepends a
 704  *      search $PATH to locate the executable.  However, simple file names can
 705  *      be received from exec() if the file is executed from the present working
 706  *      directory.  Regardless, ld.so.1 maintains NAME() as the basename, as
 707  *      this has always been the name used in diagnostics and error messages.
 708  *      Most dependencies are full path names, as the typical search for a
 709  *      dependency, say "libx.so.1", results in search paths being prepended to
 710  *      the name, which eventually open "/lib/libx.so.1".  However, relative
 711  *      path names can be supplied as dependencies, e.g. dlopen("../libx.so.1").
 712  *
 713  *  -   a PATHNAME() - this is the fully resolved path name of the object.  This
 714  *      name will differ from NAME() for all dynamic executables, and may differ
 715  *      from the NAME() of dependencies, if the dependency is not a full path
 716  *      name, or the dependency resolves to a symbolic link.
 717  *
 718  *  -   an ALIAS() name - these are alternative names by which the object has
 719  *      been found, ie. when dependencies are loaded through a variety of
 720  *      different symbolic links.
 721  *
 722  * The name pattern matching can differ depending on whether we are looking
 723  * for a full path name (path != 0), or a simple file name (path == 0).  Full
 724  * path names typically match NAME() or PATHNAME() entries.
 725  *
 726  * For all full path name searches, the link-map names are taken as is.  For
 727  * simple file name searches, only the file name component of any link-map
 728  * names are used for comparison.
 729  */
 730 inline static Rt_map *
 731 is_so_matched(Rt_map *lmp, const char *name, int path)
 732 {
 733         Aliste          idx;
 734         const char      *cp;
 735 
 736         if (_is_so_matched(name, NAME(lmp), path) == 0)
 737                 return (lmp);
 738 
 739         if (PATHNAME(lmp) != NAME(lmp)) {
 740                 if (_is_so_matched(name, PATHNAME(lmp), path) == 0)
 741                         return (lmp);
 742         }
 743 
 744         for (APLIST_TRAVERSE(ALIAS(lmp), idx, cp)) {
 745                 if (_is_so_matched(name, cp, path) == 0)
 746                         return (lmp);
 747         }
 748 
 749         return (NULL);
 750 }
 751 
 752 /*
 753  * Files are opened by ld.so.1 to satisfy dependencies, filtees and dlopen()
 754  * requests.  Each request investigates the file based upon the callers
 755  * environment.  Once a full path name has been established, the following
 756  * checks are made:
 757  *
 758  *  -   does the path exist in the link-map lists FullPathNode AVL tree?  if
 759  *      so, the file is already loaded, and its associated link-map pointer
 760  *      is returned.
 761  *  -   does the path exist in the not-found AVL tree?  if so, this path has
 762  *      already been determined to not exist, and a failure is returned.
 763  *  -   a device/inode check, to ensure the same file isn't mapped multiple
 764  *      times through different paths.  See file_open().
 765  *
 766  * However, there are cases where a test for an existing file name needs to be
 767  * carried out, such as dlopen(NOLOAD) requests, dldump() requests, and as a
 768  * final fallback to dependency loading.  These requests are handled by
 769  * is_so_loaded().
 770  *
 771  * A traversal through the callers link-map list is carried out, and from each
 772  * link-map, a comparison is made against all of the various names by which the
 773  * object has been referenced.  is_so_matched() is used to compare the link-map
 774  * names against the name being searched for.  Whether the search name is a full
 775  * path name or a simple file name, governs what comparisons are made.
 776  *
 777  * A full path name, which is a fully resolved path name that starts with a "/"
 778  * character, or a relative path name that includes a "/" character, must match
 779  * the link-map names exactly.  A simple file name, which is any name *not*
 780  * containing a "/" character, are matched against the file name component of
 781  * any link-map names.
 782  */
 783 Rt_map *
 784 is_so_loaded(Lm_list *lml, const char *name, int *in_nfavl)
 785 {
 786         Rt_map          *lmp;
 787         avl_index_t     where;
 788         Lm_cntl         *lmc;
 789         Aliste          idx;
 790         int             path = 0;
 791 
 792         /*
 793          * If the name is a full path name, first determine if the path name is
 794          * registered on the FullPathNode AVL, or not-found AVL trees.
 795          */
 796         if (name[0] == '/') {
 797                 uint_t  hash = sgs_str_hash(name);
 798 
 799                 if (((lmp = fpavl_recorded(lml, name, hash, &where)) != NULL) &&
 800                     ((FLAGS(lmp) & (FLG_RT_OBJECT | FLG_RT_DELETE)) == 0))
 801                         return (lmp);
 802 
 803                 if (pnavl_recorded(&nfavl, name, hash, NULL)) {
 804                         /*
 805                          * For dlopen() and dlsym() fall backs, indicate that
 806                          * a registered not-found path has indicated that this
 807                          * object does not exist.
 808                          */
 809                         if (in_nfavl)
 810                                 (*in_nfavl)++;
 811                         return (NULL);
 812                 }
 813         }
 814 
 815         /*
 816          * Determine whether the name is a simple file name, or a path name.
 817          */
 818         if (strchr(name, '/'))
 819                 path++;
 820 
 821         /*
 822          * Loop through the callers link-map lists.
 823          */
 824         for (ALIST_TRAVERSE(lml->lm_lists, idx, lmc)) {
 825                 for (lmp = lmc->lc_head; lmp; lmp = NEXT_RT_MAP(lmp)) {
 826                         if (FLAGS(lmp) & (FLG_RT_OBJECT | FLG_RT_DELETE))
 827                                 continue;
 828 
 829                         if (is_so_matched(lmp, name, path))
 830                                 return (lmp);
 831                 }
 832         }
 833         return (NULL);
 834 }
 835 
 836 /*
 837  * Tracing is enabled by the LD_TRACE_LOADED_OPTIONS environment variable which
 838  * is normally set from ldd(1).  For each link map we load, print the load name
 839  * and the full pathname of the associated object.
 840  */
 841 /* ARGSUSED4 */
 842 static void
 843 trace_so(Rt_map *clmp, Rej_desc *rej, const char *name, const char *path,
 844     int alter, const char *nfound)
 845 {
 846         const char      *str = MSG_ORIG(MSG_STR_EMPTY);
 847         const char      *reject = MSG_ORIG(MSG_STR_EMPTY);
 848         char            _reject[PATH_MAX];
 849 
 850         /*
 851          * The first time through trace_so() will only have lddstub on the
 852          * link-map list and the preloaded shared object is supplied as "path".
 853          * As we don't want to print this shared object as a dependency, but
 854          * instead inspect *its* dependencies, return.
 855          */
 856         if (FLAGS1(clmp) & FL1_RT_LDDSTUB)
 857                 return;
 858 
 859         /*
 860          * Without any rejection info, this is a supplied not-found condition.
 861          */
 862         if (rej && (rej->rej_type == 0)) {
 863                 (void) printf(nfound, name);
 864                 return;
 865         }
 866 
 867         /*
 868          * If rejection information exists then establish what object was
 869          * found and the reason for its rejection.
 870          */
 871         if (rej) {
 872                 Conv_reject_desc_buf_t rej_buf;
 873 
 874                 /* LINTED */
 875                 (void) snprintf(_reject, PATH_MAX,
 876                     MSG_INTL(ldd_reject[rej->rej_type]),
 877                     conv_reject_desc(rej, &rej_buf, M_MACH));
 878                 if (rej->rej_name)
 879                         path = rej->rej_name;
 880                 reject = (char *)_reject;
 881 
 882                 /*
 883                  * Was an alternative pathname defined (from a configuration
 884                  * file).
 885                  */
 886                 if (rej->rej_flags & FLG_REJ_ALTER)
 887                         str = MSG_INTL(MSG_LDD_FIL_ALTER);
 888         } else {
 889                 if (alter)
 890                         str = MSG_INTL(MSG_LDD_FIL_ALTER);
 891         }
 892 
 893         /*
 894          * If the load name isn't a full pathname print its associated pathname
 895          * together with all the other information we've gathered.
 896          */
 897         if (*name == '/')
 898                 (void) printf(MSG_ORIG(MSG_LDD_FIL_PATH), path, str, reject);
 899         else
 900                 (void) printf(MSG_ORIG(MSG_LDD_FIL_EQUIV), name, path, str,
 901                     reject);
 902 }
 903 
 904 /*
 905  * Establish a link-map mode, initializing it if it has just been loaded, or
 906  * potentially updating it if it already exists.
 907  */
 908 int
 909 update_mode(Rt_map *lmp, int omode, int nmode)
 910 {
 911         Lm_list *lml = LIST(lmp);
 912         int     pmode = 0;
 913 
 914         /*
 915          * A newly loaded object hasn't had its mode set yet.  Modes are used to
 916          * load dependencies, so don't propagate any parent or no-load flags, as
 917          * these would adversely affect this objects ability to load any of its
 918          * dependencies that aren't already loaded.  RTLD_FIRST is applicable to
 919          * this objects handle creation only, and should not be propagated.
 920          */
 921         if ((FLAGS(lmp) & FLG_RT_MODESET) == 0) {
 922                 MODE(lmp) |= nmode & ~(RTLD_PARENT | RTLD_NOLOAD | RTLD_FIRST);
 923                 FLAGS(lmp) |= FLG_RT_MODESET;
 924                 return (1);
 925         }
 926 
 927         /*
 928          * Establish any new overriding modes.  RTLD_LAZY and RTLD_NOW should be
 929          * represented individually (this is historic, as these two flags were
 930          * the only flags originally available to dlopen()).  Other flags are
 931          * accumulative, but have a hierarchy of preference.
 932          */
 933         if ((omode & RTLD_LAZY) && (nmode & RTLD_NOW)) {
 934                 MODE(lmp) &= ~RTLD_LAZY;
 935                 pmode |= RTLD_NOW;
 936         }
 937 
 938         pmode |= ((~omode & nmode) &
 939             (RTLD_GLOBAL | RTLD_WORLD | RTLD_NODELETE));
 940         if (pmode) {
 941                 DBG_CALL(Dbg_file_mode_promote(lmp, pmode));
 942                 MODE(lmp) |= pmode;
 943         }
 944 
 945         /*
 946          * If this load is an RTLD_NOW request and the object has already been
 947          * loaded non-RTLD_NOW, append this object to the relocation-now list
 948          * of the objects associated control list.  Note, if the object hasn't
 949          * yet been relocated, setting its MODE() to RTLD_NOW will establish
 950          * full relocation processing when it eventually gets relocated.
 951          */
 952         if ((pmode & RTLD_NOW) &&
 953             (FLAGS(lmp) & (FLG_RT_RELOCED | FLG_RT_RELOCING))) {
 954                 Lm_cntl *lmc;
 955 
 956                 /* LINTED */
 957                 lmc = (Lm_cntl *)alist_item_by_offset(LIST(lmp)->lm_lists,
 958                     CNTL(lmp));
 959                 (void) aplist_append(&lmc->lc_now, lmp, AL_CNT_LMNOW);
 960         }
 961 
 962         /*
 963          * If this objects .init has been collected but has not yet been called,
 964          * it may be necessary to reevaluate the object using tsort().  For
 965          * example, a new dlopen() hierarchy may bind to uninitialized objects
 966          * that are already loaded, or a dlopen(RTLD_NOW) can establish new
 967          * bindings between already loaded objects that require the tsort()
 968          * information be recomputed.  If however, no new objects have been
 969          * added to the process, and this object hasn't been promoted, don't
 970          * bother reevaluating the .init.  The present tsort() information is
 971          * probably as accurate as necessary, and by not establishing a parallel
 972          * tsort() we can help reduce the amount of recursion possible between
 973          * .inits.
 974          */
 975         if (((FLAGS(lmp) &
 976             (FLG_RT_INITCLCT | FLG_RT_INITCALL)) == FLG_RT_INITCLCT) &&
 977             ((lml->lm_flags & LML_FLG_OBJADDED) || ((pmode & RTLD_NOW) &&
 978             (FLAGS(lmp) & (FLG_RT_RELOCED | FLG_RT_RELOCING))))) {
 979                 FLAGS(lmp) &= ~FLG_RT_INITCLCT;
 980                 LIST(lmp)->lm_init++;
 981                 LIST(lmp)->lm_flags |= LML_FLG_OBJREEVAL;
 982         }
 983 
 984         return (pmode);
 985 }
 986 
 987 /*
 988  * Determine whether an alias name already exists, and if not create one.  This
 989  * is typically used to retain dependency names, such as "libc.so.1", which
 990  * would have been expanded to full path names when they were loaded.  The
 991  * full path names (NAME() and possibly PATHNAME()) are maintained on the
 992  * FullPathNode AVL tree, and thus would have been matched by fpavl_loaded()
 993  * during file_open().
 994  */
 995 int
 996 append_alias(Rt_map *lmp, const char *str, int *added)
 997 {
 998         const char      *cp;
 999         Aliste          idx;
1000 
1001         /*
1002          * Determine if this filename is already on the alias list.
1003          */
1004         for (APLIST_TRAVERSE(ALIAS(lmp), idx, cp)) {
1005                 if (strcmp(cp, str) == 0)
1006                         return (1);
1007         }
1008 
1009         /*
1010          * This is a new alias, append it to the alias list.
1011          */
1012         if (((cp = stravl_insert(str, 0, 0, 0)) == NULL) ||
1013             (aplist_append(&ALIAS(lmp), cp, AL_CNT_ALIAS) == NULL))
1014                 return (0);
1015 
1016         if (added)
1017                 *added = 1;
1018         return (1);
1019 }
1020 
1021 /*
1022  * Determine whether a file is already loaded by comparing device and inode
1023  * values.
1024  */
1025 static Rt_map *
1026 is_devinode_loaded(rtld_stat_t *status, Lm_list *lml, const char *name,
1027     uint_t flags)
1028 {
1029         Lm_cntl *lmc;
1030         Aliste  idx;
1031 
1032         /*
1033          * If this is an auditor, it will have been opened on a new link-map.
1034          * To prevent multiple occurrences of the same auditor on multiple
1035          * link-maps, search the head of each link-map list and see if this
1036          * object is already loaded as an auditor.
1037          */
1038         if (flags & FLG_RT_AUDIT) {
1039                 Lm_list *lml;
1040 
1041                 for (APLIST_TRAVERSE(dynlm_list, idx, lml)) {
1042                         Rt_map  *nlmp = lml->lm_head;
1043 
1044                         if (nlmp && ((FLAGS(nlmp) &
1045                             (FLG_RT_AUDIT | FLG_RT_DELETE)) == FLG_RT_AUDIT) &&
1046                             (STDEV(nlmp) == status->st_dev) &&
1047                             (STINO(nlmp) == status->st_ino))
1048                                 return (nlmp);
1049                 }
1050                 return (NULL);
1051         }
1052 
1053         /*
1054          * If the file has been found determine from the new files status
1055          * information if this file is actually linked to one we already have
1056          * mapped.  This catches symlink names not caught by is_so_loaded().
1057          */
1058         for (ALIST_TRAVERSE(lml->lm_lists, idx, lmc)) {
1059                 Rt_map  *nlmp;
1060 
1061                 for (nlmp = lmc->lc_head; nlmp; nlmp = NEXT_RT_MAP(nlmp)) {
1062                         if ((FLAGS(nlmp) & FLG_RT_DELETE) ||
1063                             (FLAGS1(nlmp) & FL1_RT_LDDSTUB))
1064                                 continue;
1065 
1066                         if ((STDEV(nlmp) != status->st_dev) ||
1067                             (STINO(nlmp) != status->st_ino))
1068                                 continue;
1069 
1070                         if (lml->lm_flags & LML_FLG_TRC_VERBOSE) {
1071                                 /* BEGIN CSTYLED */
1072                                 if (*name == '/')
1073                                     (void) printf(MSG_ORIG(MSG_LDD_FIL_PATH),
1074                                         name, MSG_ORIG(MSG_STR_EMPTY),
1075                                         MSG_ORIG(MSG_STR_EMPTY));
1076                                 else
1077                                     (void) printf(MSG_ORIG(MSG_LDD_FIL_EQUIV),
1078                                         name, NAME(nlmp),
1079                                         MSG_ORIG(MSG_STR_EMPTY),
1080                                         MSG_ORIG(MSG_STR_EMPTY));
1081                                 /* END CSTYLED */
1082                         }
1083                         return (nlmp);
1084                 }
1085         }
1086         return (NULL);
1087 }
1088 
1089 /*
1090  * Generate any error messages indicating a file could not be found.  When
1091  * preloading or auditing a secure application, it can be a little more helpful
1092  * to indicate that a search of secure directories has failed, so adjust the
1093  * messages accordingly.
1094  */
1095 void
1096 file_notfound(Lm_list *lml, const char *name, Rt_map *clmp, uint_t flags,
1097     Rej_desc *rej)
1098 {
1099         int     secure = 0;
1100 
1101         if ((rtld_flags & RT_FL_SECURE) &&
1102             (flags & (FLG_RT_PRELOAD | FLG_RT_AUDIT)))
1103                 secure++;
1104 
1105         if (lml->lm_flags & LML_FLG_TRC_ENABLE) {
1106                 /*
1107                  * Under ldd(1), auxiliary filtees that can't be loaded are
1108                  * ignored, unless verbose errors are requested.
1109                  */
1110                 if ((rtld_flags & RT_FL_SILENCERR) &&
1111                     ((lml->lm_flags & LML_FLG_TRC_VERBOSE) == 0))
1112                         return;
1113 
1114                 if (secure)
1115                         trace_so(clmp, rej, name, 0, 0,
1116                             MSG_INTL(MSG_LDD_SEC_NFOUND));
1117                 else
1118                         trace_so(clmp, rej, name, 0, 0,
1119                             MSG_INTL(MSG_LDD_FIL_NFOUND));
1120                 return;
1121         }
1122 
1123         if (rej->rej_type) {
1124                 Conv_reject_desc_buf_t rej_buf;
1125 
1126                 eprintf(lml, ERR_FATAL, MSG_INTL(err_reject[rej->rej_type]),
1127                     rej->rej_name ? rej->rej_name : MSG_INTL(MSG_STR_UNKNOWN),
1128                     conv_reject_desc(rej, &rej_buf, M_MACH));
1129                 return;
1130         }
1131 
1132         if (secure)
1133                 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SEC_OPEN), name);
1134         else
1135                 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), name,
1136                     strerror(ENOENT));
1137 }
1138 
1139 static int
1140 file_open(int err, Lm_list *lml, Rt_map *clmp, uint_t flags, Fdesc *fdp,
1141     Rej_desc *rej, int *in_nfavl)
1142 {
1143         rtld_stat_t     status;
1144         Rt_map          *nlmp;
1145         avl_index_t     nfavlwhere = 0;
1146         const char      *oname = fdp->fd_oname, *nname = fdp->fd_nname;
1147         uint_t          hash = sgs_str_hash(nname);
1148 
1149 
1150         if ((nname = stravl_insert(fdp->fd_nname, hash, 0, 0)) == NULL)
1151                 return (0);
1152         fdp->fd_nname = nname;
1153 
1154         if ((err == 0) && (fdp->fd_flags & FLG_FD_ALTER))
1155                 DBG_CALL(Dbg_file_config_obj(lml, oname, 0, nname));
1156 
1157         /*
1158          * If we're dealing with a full pathname, determine whether this
1159          * pathname is already known.  Other pathnames fall through to the
1160          * dev/inode check, as even though the pathname may look the same as
1161          * one previously used, the process may have changed directory.
1162          */
1163         if ((err == 0) && (nname[0] == '/')) {
1164                 if ((nlmp = fpavl_recorded(lml, nname, hash,
1165                     &(fdp->fd_avlwhere))) != NULL) {
1166                         fdp->fd_lmp = nlmp;
1167                         return (1);
1168                 }
1169                 if (pnavl_recorded(&nfavl, nname, hash, &nfavlwhere)) {
1170                         /*
1171                          * For dlopen() and dlsym() fall backs, indicate that
1172                          * a registered not-found path has indicated that this
1173                          * object does not exist.  If this path has been
1174                          * constructed as part of expanding a CAPABILITY
1175                          * directory, this is a silent failure, where no
1176                          * rejection message is created.
1177                          */
1178                         if (in_nfavl)
1179                                 (*in_nfavl)++;
1180                         return (0);
1181                 }
1182         }
1183 
1184         if ((err == 0) && ((rtld_stat(nname, &status)) != -1)) {
1185                 char    path[PATH_MAX];
1186                 int     fd, size, added;
1187 
1188                 /*
1189                  * If this path has been constructed as part of expanding a
1190                  * CAPABILITY directory, ignore any subdirectories.  As this
1191                  * is a silent failure, no rejection message is created.  For
1192                  * any other reference that expands to a directory, fall
1193                  * through to construct a meaningful rejection message.
1194                  */
1195                 if ((flags & FLG_RT_CAP) &&
1196                     ((status.st_mode & S_IFMT) == S_IFDIR))
1197                         return (0);
1198 
1199                 /*
1200                  * If this is a directory (which can't be mmap()'ed) generate a
1201                  * precise error message.
1202                  */
1203                 if ((status.st_mode & S_IFMT) == S_IFDIR) {
1204                         rej->rej_name = nname;
1205                         if (fdp->fd_flags & FLG_FD_ALTER)
1206                                 rej->rej_flags = FLG_REJ_ALTER;
1207                         rej->rej_type = SGS_REJ_STR;
1208                         rej->rej_str = strerror(EISDIR);
1209                         DBG_CALL(Dbg_file_rejected(lml, rej, M_MACH));
1210                         return (0);
1211                 }
1212 
1213                 /*
1214                  * Resolve the filename and determine whether the resolved name
1215                  * is already known.  Typically, the previous fpavl_loaded()
1216                  * will have caught this, as both NAME() and PATHNAME() for a
1217                  * link-map are recorded in the FullPathNode AVL tree.  However,
1218                  * instances exist where a file can be replaced (loop-back
1219                  * mounts, bfu, etc.), and reference is made to the original
1220                  * file through a symbolic link.  By checking the pathname here,
1221                  * we don't fall through to the dev/inode check and conclude
1222                  * that a new file should be loaded.
1223                  */
1224                 if ((nname[0] == '/') &&
1225                     ((size = resolvepath(nname, path, (PATH_MAX - 1))) > 0)) {
1226                         path[size] = '\0';
1227 
1228                         fdp->fd_flags |= FLG_FD_RESOLVED;
1229 
1230                         if (strcmp(nname, path)) {
1231                                 if ((nlmp =
1232                                     fpavl_recorded(lml, path, 0, 0)) != NULL) {
1233                                         added = 0;
1234 
1235                                         if (append_alias(nlmp, nname,
1236                                             &added) == 0)
1237                                                 return (0);
1238                                         /* BEGIN CSTYLED */
1239                                         if (added)
1240                                             DBG_CALL(Dbg_file_skip(LIST(clmp),
1241                                                 NAME(nlmp), nname));
1242                                         /* END CSTYLED */
1243                                         fdp->fd_lmp = nlmp;
1244                                         return (1);
1245                                 }
1246 
1247                                 /*
1248                                  * If this pathname hasn't been loaded, save
1249                                  * the resolved pathname so that it doesn't
1250                                  * have to be recomputed as part of fullpath()
1251                                  * processing.
1252                                  */
1253                                 if ((fdp->fd_pname = stravl_insert(path, 0,
1254                                     (size + 1), 0)) == NULL)
1255                                         return (0);
1256                         }
1257                 }
1258 
1259                 if (nlmp = is_devinode_loaded(&status, lml, nname, flags)) {
1260                         if (flags & FLG_RT_AUDIT) {
1261                                 /*
1262                                  * If we've been requested to load an auditor,
1263                                  * and an auditor of the same name already
1264                                  * exists, then the original auditor is used.
1265                                  */
1266                                 DBG_CALL(Dbg_audit_skip(LIST(clmp),
1267                                     NAME(nlmp), LIST(nlmp)->lm_lmidstr));
1268                         } else {
1269                                 /*
1270                                  * Otherwise, if an alternatively named file
1271                                  * has been found for the same dev/inode, add
1272                                  * a new name alias.  Insert any alias full path
1273                                  * name in the FullPathNode AVL tree.
1274                                  */
1275                                 added = 0;
1276 
1277                                 if (append_alias(nlmp, nname, &added) == 0)
1278                                         return (0);
1279                                 if (added) {
1280                                         if ((nname[0] == '/') &&
1281                                             (fpavl_insert(lml, nlmp,
1282                                             nname, 0) == 0))
1283                                                 return (0);
1284                                         DBG_CALL(Dbg_file_skip(LIST(clmp),
1285                                             NAME(nlmp), nname));
1286                                 }
1287                         }
1288 
1289                         /*
1290                          * Record in the file descriptor the existing object
1291                          * that satisfies this open request.
1292                          */
1293                         fdp->fd_lmp = nlmp;
1294                         return (1);
1295                 }
1296 
1297                 if ((fd = open(nname, O_RDONLY, 0)) == -1) {
1298                         /*
1299                          * As the file must exist for the previous stat() to
1300                          * have succeeded, record the error condition.
1301                          */
1302                         rej->rej_type = SGS_REJ_STR;
1303                         rej->rej_str = strerror(errno);
1304                 } else {
1305                         /*
1306                          * Map the object.  A successful return indicates that
1307                          * the object is appropriate for ld.so.1 processing.
1308                          */
1309                         fdp->fd_ftp = map_obj(lml, fdp, status.st_size, nname,
1310                             fd, rej);
1311                         (void) close(fd);
1312 
1313                         if (fdp->fd_ftp != NULL) {
1314                                 fdp->fd_dev = status.st_dev;
1315                                 fdp->fd_ino = status.st_ino;
1316                                 return (1);
1317                         }
1318                 }
1319 
1320         } else if (errno != ENOENT) {
1321                 /*
1322                  * If the open() failed for anything other than the file not
1323                  * existing, record the error condition.
1324                  */
1325                 rej->rej_type = SGS_REJ_STR;
1326                 rej->rej_str = strerror(errno);
1327         }
1328 
1329         /*
1330          * Regardless of error, duplicate and record any full path names that
1331          * can't be used on the "not-found" AVL tree.
1332          */
1333         if (nname[0] == '/')
1334                 nfavl_insert(nname, nfavlwhere);
1335 
1336         /*
1337          * Indicate any rejection.
1338          */
1339         if (rej->rej_type) {
1340                 rej->rej_name = nname;
1341                 if (fdp->fd_flags & FLG_FD_ALTER)
1342                         rej->rej_flags = FLG_REJ_ALTER;
1343                 DBG_CALL(Dbg_file_rejected(lml, rej, M_MACH));
1344         }
1345         return (0);
1346 }
1347 
1348 /*
1349  * Find a full pathname (it contains a "/").
1350  */
1351 int
1352 find_path(Lm_list *lml, Rt_map *clmp, uint_t flags, Fdesc *fdp, Rej_desc *rej,
1353     int *in_nfavl)
1354 {
1355         const char      *oname = fdp->fd_oname;
1356         int             err = 0;
1357 
1358         /*
1359          * If directory configuration exists determine if this path is known.
1360          */
1361         if (rtld_flags & RT_FL_DIRCFG) {
1362                 Rtc_obj         *obj;
1363                 const char      *aname;
1364 
1365                 if ((obj = elf_config_ent(oname, (Word)elf_hash(oname),
1366                     0, &aname)) != 0) {
1367                         /*
1368                          * If the configuration file states that this path is a
1369                          * directory, or the path is explicitly defined as
1370                          * non-existent (ie. a unused platform specific
1371                          * library), then go no further.
1372                          */
1373                         if (obj->co_flags & RTC_OBJ_DIRENT) {
1374                                 err = EISDIR;
1375                         } else if ((obj->co_flags &
1376                             (RTC_OBJ_NOEXIST | RTC_OBJ_ALTER)) ==
1377                             RTC_OBJ_NOEXIST) {
1378                                 err = ENOENT;
1379                         } else if ((obj->co_flags & RTC_OBJ_ALTER) &&
1380                             (rtld_flags & RT_FL_OBJALT) && (lml == &lml_main)) {
1381                                 int     ret;
1382 
1383                                 fdp->fd_flags |= FLG_FD_ALTER;
1384                                 fdp->fd_nname = aname;
1385 
1386                                 /*
1387                                  * Attempt to open the alternative path.  If
1388                                  * this fails, and the alternative is flagged
1389                                  * as optional, fall through to open the
1390                                  * original path.
1391                                  */
1392                                 DBG_CALL(Dbg_libs_found(lml, aname,
1393                                     FLG_FD_ALTER));
1394                                 ret = file_open(0, lml, clmp, flags, fdp,
1395                                     rej, in_nfavl);
1396                                 if (ret || ((obj->co_flags &
1397                                     RTC_OBJ_OPTINAL) == 0))
1398                                         return (ret);
1399 
1400                                 fdp->fd_flags &= ~FLG_FD_ALTER;
1401                         }
1402                 }
1403         }
1404         DBG_CALL(Dbg_libs_found(lml, oname, 0));
1405         fdp->fd_nname = oname;
1406         return (file_open(err, lml, clmp, flags, fdp, rej, in_nfavl));
1407 }
1408 
1409 /*
1410  * Find a simple filename (it doesn't contain a "/").
1411  */
1412 static int
1413 _find_file(Lm_list *lml, Rt_map *clmp, uint_t flags, Fdesc *fdp, Rej_desc *rej,
1414     Pdesc *pdp, int aflag, int *in_nfavl)
1415 {
1416         const char      *nname = fdp->fd_nname;
1417 
1418         DBG_CALL(Dbg_libs_found(lml, nname, aflag));
1419         if ((lml->lm_flags & LML_FLG_TRC_SEARCH) &&
1420             ((FLAGS1(clmp) & FL1_RT_LDDSTUB) == 0)) {
1421                 (void) printf(MSG_INTL(MSG_LDD_PTH_TRYING), nname, aflag ?
1422                     MSG_INTL(MSG_LDD_FIL_ALTER) : MSG_ORIG(MSG_STR_EMPTY));
1423         }
1424 
1425         /*
1426          * If we're being audited tell the audit library of the file we're about
1427          * to go search for.  The audit library may offer an alternative
1428          * dependency, or indicate that this dependency should be ignored.
1429          */
1430         if ((lml->lm_tflags | AFLAGS(clmp)) & LML_TFLG_AUD_OBJSEARCH) {
1431                 char    *aname;
1432 
1433                 if ((aname = audit_objsearch(clmp, nname,
1434                     (pdp->pd_flags & LA_SER_MASK))) == NULL) {
1435                         DBG_CALL(Dbg_audit_terminate(lml, nname));
1436                         return (0);
1437                 }
1438 
1439                 if (aname != nname) {
1440                         fdp->fd_flags &= ~FLG_FD_SLASH;
1441                         fdp->fd_nname = aname;
1442                 }
1443         }
1444         return (file_open(0, lml, clmp, flags, fdp, rej, in_nfavl));
1445 }
1446 
1447 static int
1448 find_file(Lm_list *lml, Rt_map *clmp, uint_t flags, Fdesc *fdp, Rej_desc *rej,
1449     Pdesc *pdp, Word *strhash, int *in_nfavl)
1450 {
1451         static Rtc_obj  Obj = { 0 };
1452         Rtc_obj         *dobj;
1453         const char      *oname = fdp->fd_oname;
1454         size_t          olen = strlen(oname);
1455 
1456         if (pdp->pd_pname == NULL)
1457                 return (0);
1458         if (pdp->pd_info) {
1459                 dobj = (Rtc_obj *)pdp->pd_info;
1460                 if ((dobj->co_flags &
1461                     (RTC_OBJ_NOEXIST | RTC_OBJ_ALTER)) == RTC_OBJ_NOEXIST)
1462                         return (0);
1463         } else
1464                 dobj = NULL;
1465 
1466         /*
1467          * If configuration information exists see if this directory/file
1468          * combination exists.
1469          */
1470         if ((rtld_flags & RT_FL_DIRCFG) &&
1471             ((dobj == NULL) || (dobj->co_id != 0))) {
1472                 Rtc_obj         *fobj;
1473                 const char      *aname = NULL;
1474 
1475                 /*
1476                  * If this object descriptor has not yet been searched for in
1477                  * the configuration file go find it.
1478                  */
1479                 if (dobj == NULL) {
1480                         dobj = elf_config_ent(pdp->pd_pname,
1481                             (Word)elf_hash(pdp->pd_pname), 0, 0);
1482                         if (dobj == NULL)
1483                                 dobj = &Obj;
1484                         pdp->pd_info = (void *)dobj;
1485 
1486                         if ((dobj->co_flags & (RTC_OBJ_NOEXIST |
1487                             RTC_OBJ_ALTER)) == RTC_OBJ_NOEXIST)
1488                                 return (0);
1489                 }
1490 
1491                 /*
1492                  * If we found a directory search for the file.
1493                  */
1494                 if (dobj->co_id != 0) {
1495                         if (*strhash == NULL)
1496                                 *strhash = (Word)elf_hash(oname);
1497                         fobj = elf_config_ent(oname, *strhash,
1498                             dobj->co_id, &aname);
1499 
1500                         /*
1501                          * If this object specifically does not exist, or the
1502                          * object can't be found in a know-all-entries
1503                          * directory, continue looking.  If the object does
1504                          * exist determine if an alternative object exists.
1505                          */
1506                         if (fobj == NULL) {
1507                                 if (dobj->co_flags & RTC_OBJ_ALLENTS)
1508                                         return (0);
1509                         } else {
1510                                 if ((fobj->co_flags & (RTC_OBJ_NOEXIST |
1511                                     RTC_OBJ_ALTER)) == RTC_OBJ_NOEXIST)
1512                                         return (0);
1513 
1514                                 if ((fobj->co_flags & RTC_OBJ_ALTER) &&
1515                                     (rtld_flags & RT_FL_OBJALT) &&
1516                                     (lml == &lml_main)) {
1517                                         int     ret;
1518 
1519                                         fdp->fd_flags |= FLG_FD_ALTER;
1520                                         fdp->fd_nname = aname;
1521 
1522                                         /*
1523                                          * Attempt to open the alternative path.
1524                                          * If this fails, and the alternative is
1525                                          * flagged as optional, fall through to
1526                                          * open the original path.
1527                                          */
1528                                         ret = _find_file(lml, clmp, flags, fdp,
1529                                             rej, pdp, 1, in_nfavl);
1530                                         if (ret || ((fobj->co_flags &
1531                                             RTC_OBJ_OPTINAL) == 0))
1532                                                 return (ret);
1533 
1534                                         fdp->fd_flags &= ~FLG_FD_ALTER;
1535                                 }
1536                         }
1537                 }
1538         }
1539 
1540         /*
1541          * Protect ourselves from building an invalid pathname.
1542          */
1543         if ((olen + pdp->pd_plen + 1) >= PATH_MAX) {
1544                 eprintf(lml, ERR_FATAL, MSG_INTL(MSG_SYS_OPEN), oname,
1545                     strerror(ENAMETOOLONG));
1546                         return (0);
1547         }
1548         if ((fdp->fd_nname = (LM_GET_SO(clmp)(pdp->pd_pname, oname,
1549             pdp->pd_plen, olen))) == NULL)
1550                 return (0);
1551 
1552         return (_find_file(lml, clmp, flags, fdp, rej, pdp, 0, in_nfavl));
1553 }
1554 
1555 static Fct      *Vector[] = {
1556         &elf_fct,
1557 #ifdef  A_OUT
1558         &aout_fct,
1559 #endif
1560         0
1561 };
1562 
1563 /*
1564  * Remap the first page of a file to provide a better diagnostic as to why
1565  * an mmapobj(2) operation on this file failed.  Sadly, mmapobj(), and all
1566  * system calls for that matter, only pass back a generic failure in errno.
1567  * Hopefully one day this will be improved, but in the mean time we repeat
1568  * the kernels ELF verification to try and provide more detailed information.
1569  */
1570 static int
1571 map_fail(Fdesc *fdp, size_t fsize, const char *name, int fd, Rej_desc *rej)
1572 {
1573         caddr_t addr;
1574         int     vnum;
1575         size_t  size;
1576 
1577         /*
1578          * Use the original file size to determine what to map, and catch the
1579          * obvious error of a zero sized file.
1580          */
1581         if (fsize == 0) {
1582                 rej->rej_type = SGS_REJ_UNKFILE;
1583                 return (1);
1584         } else if (fsize < syspagsz)
1585                 size = fsize;
1586         else
1587                 size = syspagsz;
1588 
1589         if ((addr = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED)
1590                 return (0);
1591 
1592         rej->rej_type = 0;
1593 
1594         /*
1595          * Validate the file against each supported file type.  Should a
1596          * characteristic of the file be found invalid for this platform, a
1597          * rejection message will have been recorded.
1598          */
1599         for (vnum = 0; Vector[vnum]; vnum++) {
1600                 if (((Vector[vnum]->fct_verify_file)(addr, size,
1601                     fdp, name, rej) == 0) && rej->rej_type)
1602                         break;
1603         }
1604 
1605         /*
1606          * If no rejection message has been recorded, then this is simply an
1607          * unknown file type.
1608          */
1609         if (rej->rej_type == 0)
1610                 rej->rej_type = SGS_REJ_UNKFILE;
1611 
1612         (void) munmap(addr, size);
1613         return (1);
1614 }
1615 
1616 /*
1617  * Unmap a file.
1618  */
1619 void
1620 unmap_obj(mmapobj_result_t *mpp, uint_t mapnum)
1621 {
1622         uint_t  num;
1623 
1624         for (num = 0; num < mapnum; num++) {
1625                 /* LINTED */
1626                 (void) munmap((void *)(uintptr_t)mpp[num].mr_addr,
1627                     mpp[num].mr_msize);
1628         }
1629         cnt_unmap++;
1630 }
1631 
1632 /*
1633  * Map a file.
1634  */
1635 Fct *
1636 map_obj(Lm_list *lml, Fdesc *fdp, size_t fsize, const char *name, int fd,
1637     Rej_desc *rej)
1638 {
1639         static mmapobj_result_t *smpp = NULL;
1640         static uint_t           smapnum;
1641         mmapobj_result_t        *mpp;
1642         uint_t                  mnum, mapnum, mflags;
1643         void                    *padding;
1644 
1645         /*
1646          * Allocate an initial mapping array.  The initial size should be large
1647          * enough to handle the normal ELF objects we come across.
1648          */
1649         if (smpp == NULL) {
1650                 smpp = malloc(sizeof (mmapobj_result_t) * MMAPFD_NUM);
1651                 if (smpp == NULL)
1652                         return (NULL);
1653                 smapnum = MMAPFD_NUM;
1654         }
1655 
1656         /*
1657          * If object padding is required, set the necessary flags.
1658          */
1659         if (r_debug.rtd_objpad) {
1660                 mflags = MMOBJ_INTERPRET | MMOBJ_PADDING;
1661                 padding = &r_debug.rtd_objpad;
1662         } else {
1663                 mflags = MMOBJ_INTERPRET;
1664                 padding = NULL;
1665         }
1666 
1667         /*
1668          * Map the file.  If the number of mappings required by this file
1669          * exceeds the present mapping structure, an error indicating the
1670          * return data is too big is returned.  Bail on any other error.
1671          */
1672         mapnum = smapnum;
1673         if (mmapobj(fd, mflags, smpp, &mapnum, padding) == -1) {
1674                 if (errno != E2BIG) {
1675                         int     err = errno;
1676 
1677                         /*
1678                          * An unsupported error indicates that there's something
1679                          * incompatible with this ELF file, and the process that
1680                          * is already running.  Map the first page of the file
1681                          * and see if we can generate a better error message.
1682                          */
1683                         if ((errno == ENOTSUP) && map_fail(fdp, fsize, name,
1684                             fd, rej))
1685                                 return (NULL);
1686 
1687                         rej->rej_type = SGS_REJ_STR;
1688                         rej->rej_str = strerror(err);
1689                         return (NULL);
1690                 }
1691 
1692                 /*
1693                  * The mapping requirement exceeds the present mapping
1694                  * structure, however the number of mapping required is
1695                  * available in the mapping number.
1696                  */
1697                 free((void *)smpp);
1698                 if ((smpp = malloc(sizeof (mmapobj_result_t) * mapnum)) == NULL)
1699                         return (NULL);
1700                 smapnum = mapnum;
1701 
1702                 /*
1703                  * With the appropriate mapping structure, try the mapping
1704                  * request again.
1705                  */
1706                 if (mmapobj(fd, mflags, smpp, &mapnum, padding) == -1) {
1707                         rej->rej_type = SGS_REJ_STR;
1708                         rej->rej_str = strerror(errno);
1709                         return (NULL);
1710                 }
1711         }
1712         ASSERT(mapnum != 0);
1713 
1714         /*
1715          * Traverse the mappings in search of a file type ld.so.1 can process.
1716          * If the file type is verified as one ld.so.1 can process, retain the
1717          * mapping information, and the number of mappings this object uses,
1718          * and clear the static mapping pointer for the next map_obj() use of
1719          * mmapobj().
1720          */
1721         DBG_CALL(Dbg_file_mmapobj(lml, name, smpp, mapnum));
1722         cnt_map++;
1723 
1724         for (mnum = 0, mpp = smpp; mnum < mapnum; mnum++, mpp++) {
1725                 uint_t  flags = (mpp->mr_flags & MR_TYPE_MASK);
1726                 Fct     *fptr = NULL;
1727 
1728                 if (flags == MR_HDR_ELF) {
1729                         fptr = elf_verify((mpp->mr_addr + mpp->mr_offset),
1730                             mpp->mr_fsize, fdp, name, rej);
1731                 }
1732 #ifdef  A_OUT
1733                 if (flags == MR_HDR_AOUT) {
1734                         fptr = aout_verify((mpp->mr_addr + mpp->mr_offset),
1735                             mpp->mr_fsize, fdp, name, rej);
1736                 }
1737 #endif
1738                 if (fptr) {
1739                         fdp->fd_mapn = mapnum;
1740                         fdp->fd_mapp = smpp;
1741 
1742                         smpp = NULL;
1743 
1744                         return (fptr);
1745                 }
1746         }
1747 
1748         /*
1749          * If the mapped file is inappropriate, indicate that the file type is
1750          * unknown, and free the mapping.
1751          */
1752         if (rej->rej_type == 0)
1753                 rej->rej_type = SGS_REJ_UNKFILE;
1754         unmap_obj(smpp, mapnum);
1755 
1756         return (NULL);
1757 }
1758 
1759 /*
1760  * A unique file has been opened.  Create a link-map to represent it, and
1761  * process the various names by which it can be referenced.
1762  */
1763 Rt_map *
1764 load_file(Lm_list *lml, Aliste lmco, Rt_map *clmp, Fdesc *fdp, int *in_nfavl)
1765 {
1766         mmapobj_result_t        *fpmpp = NULL, *fmpp = NULL, *lpmpp, *lmpp;
1767         mmapobj_result_t        *hmpp, *mpp, *ompp = fdp->fd_mapp;
1768         uint_t                  mnum, omapnum = fdp->fd_mapn;
1769         const char              *nname = fdp->fd_nname;
1770         Rt_map                  *nlmp;
1771         Ehdr                    *ehdr = NULL;
1772 
1773         /*
1774          * Traverse the mappings for the input file to capture generic mapping
1775          * information, and create a link-map to represent the file.
1776          */
1777         for (mnum = 0, mpp = ompp; mnum < omapnum; mnum++, mpp++) {
1778                 uint_t  flags = (mpp->mr_flags & MR_TYPE_MASK);
1779 
1780                 /*
1781                  * Keep track of the first and last mappings that may include
1782                  * padding.
1783                  */
1784                 if (fpmpp == NULL)
1785                         fpmpp = mpp;
1786                 lpmpp = mpp;
1787 
1788                 /*
1789                  * Keep track of the first and last mappings that do not include
1790                  * padding.
1791                  */
1792                 if (flags != MR_PADDING) {
1793                         if (fmpp == NULL)
1794                                 fmpp = mpp;
1795                         lmpp = mpp;
1796                 }
1797                 if (flags == MR_HDR_ELF) {
1798                         /* LINTED */
1799                         ehdr = (Ehdr *)(mpp->mr_addr + mpp->mr_offset);
1800                         hmpp = mpp;
1801                 } else if (flags == MR_HDR_AOUT)
1802                         hmpp = mpp;
1803         }
1804 
1805         /*
1806          * The only ELF files we can handle are ET_EXEC, ET_DYN, and ET_REL.
1807          *
1808          * ET_REL must be processed by ld(1) to create an in-memory ET_DYN.
1809          * The initial processing carried out by elf_obj_file() creates a
1810          * temporary link-map, that acts as a place holder, until the objects
1811          * processing is finished with elf_obj_fini().
1812          */
1813         if (ehdr && (ehdr->e_type == ET_REL)) {
1814                 if ((nlmp = elf_obj_file(lml, lmco, clmp, nname, hmpp, ompp,
1815                     omapnum)) == NULL)
1816                         return (nlmp);
1817         } else {
1818                 Addr    addr;
1819                 size_t  msize;
1820 
1821                 /*
1822                  * The size of the total reservation, and the padding range,
1823                  * are a historic artifact required by debuggers.  Although
1824                  * these values express the range of the associated mappings,
1825                  * there can be holes between segments (in which small objects
1826                  * could be mapped).  Anyone who needs to verify offsets
1827                  * against segments should analyze all the object mappings,
1828                  * rather than relying on these address ranges.
1829                  */
1830                 addr = (Addr)(hmpp->mr_addr + hmpp->mr_offset);
1831                 msize = lmpp->mr_addr + lmpp->mr_msize - fmpp->mr_addr;
1832 
1833                 if ((nlmp = ((fdp->fd_ftp)->fct_new_lmp)(lml, lmco, fdp, addr,
1834                     msize, NULL, clmp, in_nfavl)) == NULL)
1835                         return (NULL);
1836 
1837                 /*
1838                  * Save generic mapping information.
1839                  */
1840                 MMAPS(nlmp) = ompp;
1841                 MMAPCNT(nlmp) = omapnum;
1842                 PADSTART(nlmp) = (ulong_t)fpmpp->mr_addr;
1843                 PADIMLEN(nlmp) = lpmpp->mr_addr + lpmpp->mr_msize -
1844                     fpmpp->mr_addr;
1845         }
1846 
1847         /*
1848          * Save the dev/inode information for later comparisons, and identify
1849          * this as a new object.
1850          */
1851         STDEV(nlmp) = fdp->fd_dev;
1852         STINO(nlmp) = fdp->fd_ino;
1853         FLAGS(nlmp) |= FLG_RT_NEWLOAD;
1854 
1855         /*
1856          * If this is ELF relocatable object, we're done for now.
1857          */
1858         if (ehdr && (ehdr->e_type == ET_REL))
1859                 return (nlmp);
1860 
1861         /*
1862          * Insert the names of this link-map into the FullPathNode AVL tree.
1863          * Save both the NAME() and PATHNAME() if the names differ.
1864          */
1865         (void) fullpath(nlmp, fdp);
1866 
1867         if ((NAME(nlmp)[0] == '/') && (fpavl_insert(lml, nlmp, NAME(nlmp),
1868             fdp->fd_avlwhere) == 0)) {
1869                 remove_so(lml, nlmp, clmp);
1870                 return (NULL);
1871         }
1872         if (((NAME(nlmp)[0] != '/') || (NAME(nlmp) != PATHNAME(nlmp))) &&
1873             (fpavl_insert(lml, nlmp, PATHNAME(nlmp), 0) == 0)) {
1874                 remove_so(lml, nlmp, clmp);
1875                 return (NULL);
1876         }
1877 
1878         /*
1879          * If this is a secure application, record any full path name directory
1880          * in which this dependency has been found.  This directory can be
1881          * deemed safe (as we've already found a dependency here).  This
1882          * recording provides a fall-back should another objects $ORIGIN
1883          * definition expands to this directory, an expansion that would
1884          * ordinarily be deemed insecure.
1885          */
1886         if (rtld_flags & RT_FL_SECURE) {
1887                 if (NAME(nlmp)[0] == '/')
1888                         spavl_insert(NAME(nlmp));
1889                 if ((NAME(nlmp) != PATHNAME(nlmp)) &&
1890                     (PATHNAME(nlmp)[0] == '/'))
1891                         spavl_insert(PATHNAME(nlmp));
1892         }
1893 
1894         /*
1895          * If we're processing an alternative object reset the original name
1896          * for possible $ORIGIN processing.
1897          */
1898         if (fdp->fd_flags & FLG_FD_ALTER) {
1899                 const char      *odir, *ndir;
1900                 size_t          olen;
1901 
1902                 FLAGS(nlmp) |= FLG_RT_ALTER;
1903 
1904                 /*
1905                  * If we were given a pathname containing a slash then the
1906                  * original name is still in oname.  Otherwise the original
1907                  * directory is in dir->p_name (which is all we need for
1908                  * $ORIGIN).
1909                  */
1910                 if (fdp->fd_flags & FLG_FD_SLASH) {
1911                         char    *ofil;
1912 
1913                         odir = fdp->fd_oname;
1914                         ofil = strrchr(fdp->fd_oname, '/');
1915                         olen = ofil - odir + 1;
1916                 } else {
1917                         odir = fdp->fd_odir;
1918                         olen = strlen(odir) + 1;
1919                 }
1920                 if ((ndir = stravl_insert(odir, 0, olen, 1)) == NULL) {
1921                         remove_so(lml, nlmp, clmp);
1922                         return (NULL);
1923                 }
1924                 ORIGNAME(nlmp) = ndir;
1925                 DIRSZ(nlmp) = --olen;
1926         }
1927 
1928         return (nlmp);
1929 }
1930 
1931 /*
1932  * This function loads the named file and returns a pointer to its link map.
1933  * It is assumed that the caller has already checked that the file is not
1934  * already loaded before calling this function (refer is_so_loaded()).
1935  * Find and open the file, map it into memory, add it to the end of the list
1936  * of link maps and return a pointer to the new link map.  Return 0 on error.
1937  */
1938 static Rt_map *
1939 load_so(Lm_list *lml, Aliste lmco, Rt_map *clmp, uint_t flags,
1940     Fdesc *fdp, Rej_desc *rej, int *in_nfavl)
1941 {
1942         const char      *oname = fdp->fd_oname;
1943         Pdesc           *pdp;
1944 
1945         /*
1946          * If this path name hasn't already been identified as containing a
1947          * slash, check the path name.  Most paths have been constructed
1948          * through appending a file name to a search path, and/or have been
1949          * inspected by expand(), and thus have a slash.  However, we can
1950          * receive path names via auditors or configuration files, and thus
1951          * an evaluation here catches these instances.
1952          */
1953         if ((fdp->fd_flags & FLG_FD_SLASH) == 0) {
1954                 const char      *str;
1955 
1956                 for (str = oname; *str; str++) {
1957                         if (*str == '/') {
1958                                 fdp->fd_flags |= FLG_FD_SLASH;
1959                                 break;
1960                         }
1961                 }
1962         }
1963 
1964         /*
1965          * If we are passed a 'null' link-map this means that this is the first
1966          * object to be loaded on this link-map list.  In that case we set the
1967          * link-map to ld.so.1's link-map.
1968          *
1969          * This link-map is referenced to determine what lookup rules to use
1970          * when searching for files.  By using ld.so.1's we are defaulting to
1971          * ELF look-up rules.
1972          *
1973          * Note: This case happens when loading the first object onto
1974          *       the plt_tracing link-map.
1975          */
1976         if (clmp == 0)
1977                 clmp = lml_rtld.lm_head;
1978 
1979         /*
1980          * If this path resulted from a $CAPABILITY specification, then the
1981          * best capability object has already been establish, and is available
1982          * in the calling file descriptor.  Perform some minor book-keeping so
1983          * that we can fall through into common code.
1984          */
1985         if (flags & FLG_RT_CAP) {
1986                 /*
1987                  * If this object is already loaded, we're done.
1988                  */
1989                 if (fdp->fd_lmp)
1990                         return (fdp->fd_lmp);
1991 
1992                 /*
1993                  * Obtain the avl index for this object.
1994                  */
1995                 (void) fpavl_recorded(lml, fdp->fd_nname, 0,
1996                     &(fdp->fd_avlwhere));
1997 
1998         } else if (fdp->fd_flags & FLG_FD_SLASH) {
1999                 Rej_desc        _rej = { 0 };
2000 
2001                 if (find_path(lml, clmp, flags, fdp, &_rej, in_nfavl) == 0) {
2002                         rejection_inherit(rej, &_rej);
2003                         return (NULL);
2004                 }
2005 
2006                 /*
2007                  * If this object is already loaded, we're done.
2008                  */
2009                 if (fdp->fd_lmp)
2010                         return (fdp->fd_lmp);
2011 
2012         } else {
2013                 /*
2014                  * No '/' - for each directory on list, make a pathname using
2015                  * that directory and filename and try to open that file.
2016                  */
2017                 Spath_desc      sd = { search_rules, NULL, 0 };
2018                 Word            strhash = 0;
2019                 int             found = 0;
2020 
2021                 /*
2022                  * Traverse the search path lists, creating full pathnames and
2023                  * attempt to load each path.
2024                  */
2025                 for (pdp = get_next_dir(&sd, clmp, flags); pdp;
2026                     pdp = get_next_dir(&sd, clmp, flags)) {
2027                         Rej_desc        _rej = { 0 };
2028                         Fdesc           fd = { 0 };
2029 
2030                         /*
2031                          * Under debugging, duplicate path name entries are
2032                          * tagged but remain part of the search path list so
2033                          * that they can be diagnosed under "unused" processing.
2034                          * Skip these entries, as this path would have already
2035                          * been attempted.
2036                          */
2037                         if (pdp->pd_flags & PD_FLG_DUPLICAT)
2038                                 continue;
2039 
2040                         fd = *fdp;
2041 
2042                         /*
2043                          * Try and locate this file.  Make sure to clean up
2044                          * any rejection information should the file have
2045                          * been found, but not appropriate.
2046                          */
2047                         if (find_file(lml, clmp, flags, &fd, &_rej, pdp,
2048                             &strhash, in_nfavl) == 0) {
2049                                 rejection_inherit(rej, &_rej);
2050                                 continue;
2051                         }
2052 
2053                         /*
2054                          * Indicate that this search path has been used.  If
2055                          * this is an LD_LIBRARY_PATH setting, ignore any use
2056                          * by ld.so.1 itself.
2057                          */
2058                         if (((pdp->pd_flags & LA_SER_LIBPATH) == 0) ||
2059                             ((lml->lm_flags & LML_FLG_RTLDLM) == 0))
2060                                 pdp->pd_flags |= PD_FLG_USED;
2061 
2062                         /*
2063                          * If this object is already loaded, we're done.
2064                          */
2065                         *fdp = fd;
2066                         if (fdp->fd_lmp)
2067                                 return (fdp->fd_lmp);
2068 
2069                         fdp->fd_odir = pdp->pd_pname;
2070                         found = 1;
2071                         break;
2072                 }
2073 
2074                 /*
2075                  * If the file couldn't be loaded, do another comparison of
2076                  * loaded files using just the basename.  This catches folks
2077                  * who may have loaded multiple full pathname files (possibly
2078                  * from setxid applications) to satisfy dependency relationships
2079                  * (i.e., a file might have a dependency on foo.so.1 which has
2080                  * already been opened using its full pathname).
2081                  */
2082                 if (found == 0)
2083                         return (is_so_loaded(lml, oname, in_nfavl));
2084         }
2085 
2086         /*
2087          * Trace that this successfully opened file is about to be processed.
2088          * Note, as part of processing a family of hardware capabilities filtees
2089          * a number of candidates may have been opened and mapped to determine
2090          * their capability requirements.  At this point we've decided which
2091          * of the candidates to use.
2092          */
2093         if (lml->lm_flags & LML_FLG_TRC_ENABLE) {
2094                 trace_so(clmp, 0, fdp->fd_oname, fdp->fd_nname,
2095                     (fdp->fd_flags & FLG_FD_ALTER), 0);
2096         }
2097 
2098         /*
2099          * Finish mapping the file and return the link-map descriptor.
2100          */
2101         return (load_file(lml, lmco, clmp, fdp, in_nfavl));
2102 }
2103 
2104 /*
2105  * Trace an attempt to load an object, and seed the originating name.
2106  */
2107 const char *
2108 load_trace(Lm_list *lml, Pdesc *pdp, Rt_map *clmp, Fdesc *fdp)
2109 {
2110         const char      *name = pdp->pd_pname;
2111 
2112         DBG_CALL(Dbg_libs_find(lml, name));
2113 
2114         /*
2115          * First generate any ldd(1) diagnostics.
2116          */
2117         if ((lml->lm_flags & (LML_FLG_TRC_VERBOSE | LML_FLG_TRC_SEARCH)) &&
2118             ((FLAGS1(clmp) & FL1_RT_LDDSTUB) == 0))
2119                 (void) printf(MSG_INTL(MSG_LDD_FIL_FIND), name, NAME(clmp));
2120 
2121         /*
2122          * Propagate any knowledge of a slash within the path name.
2123          */
2124         if (pdp->pd_flags & PD_FLG_PNSLASH)
2125                 fdp->fd_flags |= FLG_FD_SLASH;
2126 
2127         /*
2128          * If we're being audited tell any audit libraries of the file we're
2129          * about to go search for.
2130          */
2131         if (aud_activity ||
2132             ((lml->lm_tflags | AFLAGS(clmp)) & LML_TFLG_AUD_ACTIVITY))
2133                 audit_activity(clmp, LA_ACT_ADD);
2134 
2135         if ((lml->lm_tflags | AFLAGS(clmp)) & LML_TFLG_AUD_OBJSEARCH) {
2136                 char    *aname;
2137 
2138                 /*
2139                  * The auditor can indicate that this object should be ignored.
2140                  */
2141                 if ((aname =
2142                     audit_objsearch(clmp, name, LA_SER_ORIG)) == NULL) {
2143                         DBG_CALL(Dbg_audit_terminate(lml, name));
2144                         return (NULL);
2145                 }
2146 
2147                 if (name != aname) {
2148                         fdp->fd_flags &= ~FLG_FD_SLASH;
2149                         name = aname;
2150                 }
2151         }
2152         fdp->fd_oname = name;
2153         return (name);
2154 }
2155 
2156 /*
2157  * Having loaded an object and created a link-map to describe it, finish
2158  * processing this stage, including verifying any versioning requirements,
2159  * updating the objects mode, creating a handle if necessary, and adding this
2160  * object to existing handles if required.
2161  */
2162 static int
2163 load_finish(Lm_list *lml, const char *name, Rt_map *clmp, int nmode,
2164     uint_t flags, Grp_hdl **hdl, Rt_map *nlmp)
2165 {
2166         Aliste          idx1;
2167         Grp_hdl         *ghp;
2168         int             promote;
2169         uint_t          rdflags;
2170 
2171         /*
2172          * If this dependency is associated with a required version ensure that
2173          * the version is present in the loaded file.
2174          */
2175         if (((rtld_flags & RT_FL_NOVERSION) == 0) && THIS_IS_ELF(clmp) &&
2176             VERNEED(clmp) && (elf_verify_vers(name, clmp, nlmp) == 0))
2177                 return (0);
2178 
2179         /*
2180          * If this object has indicated that it should be isolated as a group
2181          * (DT_FLAGS_1 contains DF_1_GROUP - object was built with -B group),
2182          * or if the callers direct bindings indicate it should be isolated as
2183          * a group (DYNINFO flags contains FLG_DI_GROUP - dependency following
2184          * -zgroupperm), establish the appropriate mode.
2185          *
2186          * The intent of an object defining itself as a group is to isolate the
2187          * relocation of the group within its own members, however, unless
2188          * opened through dlopen(), in which case we assume dlsym() will be used
2189          * to locate symbols in the new object, we still need to associate the
2190          * new object with the caller so that the caller can bind to this new
2191          * object.  This is equivalent to a dlopen(RTLD_GROUP) and dlsym()
2192          * using the returned handle.
2193          */
2194         if ((FLAGS(nlmp) | flags) & FLG_RT_SETGROUP) {
2195                 nmode &= ~RTLD_WORLD;
2196                 nmode |= RTLD_GROUP;
2197 
2198                 /*
2199                  * If the object wasn't explicitly dlopen()'ed, in which case a
2200                  * handle would have been requested, associate the object with
2201                  * the parent.
2202                  */
2203                 if ((flags & FLG_RT_PUBHDL) == 0)
2204                         nmode |= RTLD_PARENT;
2205         }
2206 
2207         /*
2208          * Establish new mode and flags.
2209          */
2210         promote = update_mode(nlmp, MODE(nlmp), nmode);
2211         FLAGS(nlmp) |= flags;
2212 
2213         /*
2214          * Establish the flags for any referenced dependency descriptors
2215          * (Grp_desc).
2216          *
2217          *  -   The referenced object is available for dlsym().
2218          *  -   The referenced object is available to relocate against.
2219          *  -   The referenced object should have it's dependencies
2220          *      added to this handle
2221          */
2222         rdflags = (GPD_DLSYM | GPD_RELOC | GPD_ADDEPS);
2223 
2224         /*
2225          * If we've been asked to establish a handle create one for this object.
2226          * Or, if this object has already been analyzed, but this reference
2227          * requires that the mode of the object be promoted, create a private
2228          * handle to propagate the new modes to all this objects dependencies.
2229          */
2230         if ((FLAGS(nlmp) & (FLG_RT_PUBHDL | FLG_RT_PRIHDL)) ||
2231             (promote && (FLAGS(nlmp) & FLG_RT_ANALYZED))) {
2232                 uint_t  oflags, hflags, cdflags = 0;
2233 
2234                 /*
2235                  * Establish any flags for the handle (Grp_hdl).
2236                  *
2237                  *  -   Public handles establish dependencies between objects
2238                  *      that must be taken into account when dlclose()'ing
2239                  *      objects.  Private handles provide for collecting
2240                  *      dependencies, but do not affect dlclose().  Note that
2241                  *      a handle may already exist, but the public/private
2242                  *      state is set to trigger the required propagation of the
2243                  *      handle's flags and any dependency gathering.
2244                  *  -   Use of the RTLD_FIRST flag indicates that only the first
2245                  *      dependency on the handle (the new object) can be used
2246                  *      to satisfy dlsym() requests.
2247                  */
2248                 if (FLAGS(nlmp) & FLG_RT_PUBHDL)
2249                         hflags = GPH_PUBLIC;
2250                 else
2251                         hflags = GPH_PRIVATE;
2252 
2253                 if (nmode & RTLD_FIRST)
2254                         hflags |= GPH_FIRST;
2255 
2256                 /*
2257                  * Establish the flags for this callers dependency descriptor
2258                  * (Grp_desc).
2259                  *
2260                  *  -   The creation of a public handle creates a descriptor
2261                  *      for the referenced object and the caller (parent).
2262                  *      Typically, the handle is created for dlopen() or for
2263                  *      filtering.  A private handle does not need to maintain
2264                  *      a descriptor to the parent.
2265                  *  -   Use of the RTLD_PARENT flag indicates that the parent
2266                  *      can be relocated against.
2267                  */
2268                 if (FLAGS(nlmp) & FLG_RT_PUBHDL) {
2269                         cdflags |= GPD_PARENT;
2270                         if (nmode & RTLD_PARENT)
2271                                 cdflags |= GPD_RELOC;
2272                 }
2273 
2274                 /*
2275                  * Now that the handle flags have been established, remove any
2276                  * handle definition from the referenced object so that the
2277                  * definitions don't mistakenly get inherited by a dependency.
2278                  */
2279                 oflags = FLAGS(nlmp);
2280                 FLAGS(nlmp) &= ~(FLG_RT_PUBHDL | FLG_RT_PRIHDL);
2281 
2282                 DBG_CALL(Dbg_file_hdl_title(DBG_HDL_ADD));
2283                 if ((ghp = hdl_create(lml, nlmp, clmp, hflags, rdflags,
2284                     cdflags)) == NULL)
2285                         return (0);
2286 
2287                 /*
2288                  * Add any dependencies that are already loaded, to the handle.
2289                  */
2290                 if (hdl_initialize(ghp, nlmp, nmode, promote) == 0)
2291                         return (0);
2292 
2293                 if (hdl)
2294                         *hdl = ghp;
2295 
2296                 /*
2297                  * If we were asked to create a public handle, we're done.
2298                  *
2299                  * If this is a private handle request, then the handle is left
2300                  * intact with a GPH_PRIVATE identifier.  This handle is a
2301                  * convenience for processing the dependencies of this object,
2302                  * but does not affect how this object might be dlclose()'d.
2303                  * For a private handle, fall through to carry out any group
2304                  * processing.
2305                  */
2306                 if (oflags & FLG_RT_PUBHDL)
2307                         return (1);
2308         }
2309 
2310         /*
2311          * If the caller isn't part of a group we're done.
2312          */
2313         if (GROUPS(clmp) == NULL)
2314                 return (1);
2315 
2316         /*
2317          * Determine if our caller is already associated with a handle, if so
2318          * we need to add this object to any handles that already exist.
2319          * Traverse the list of groups our caller is a member of and add this
2320          * new link-map to those groups.
2321          */
2322         for (APLIST_TRAVERSE(GROUPS(clmp), idx1, ghp)) {
2323                 Aliste          idx2;
2324                 Grp_desc        *gdp;
2325                 int             ale;
2326                 Rt_map          *dlmp1;
2327                 APlist          *lmalp = NULL;
2328 
2329                 DBG_CALL(Dbg_file_hdl_title(DBG_HDL_ADD));
2330 
2331                 /*
2332                  * If the caller doesn't indicate that its dependencies should
2333                  * be added to a handle, ignore it.  This case identifies a
2334                  * parent of a dlopen(RTLD_PARENT) request.
2335                  */
2336                 for (ALIST_TRAVERSE(ghp->gh_depends, idx2, gdp)) {
2337                         if (gdp->gd_depend == clmp)
2338                                 break;
2339                 }
2340                 if ((gdp->gd_flags & GPD_ADDEPS) == 0)
2341                         continue;
2342 
2343                 if ((gdp = hdl_add(ghp, nlmp, rdflags, &ale)) == NULL)
2344                         return (0);
2345 
2346                 /*
2347                  * If this member already exists then its dependencies will
2348                  * have already been processed.
2349                  */
2350                 if (ale == ALE_EXISTS)
2351                         continue;
2352 
2353                 /*
2354                  * If the object we've added has just been opened, it will not
2355                  * yet have been processed for its dependencies, these will be
2356                  * added on later calls to load_one().  If it doesn't have any
2357                  * dependencies we're also done.
2358                  */
2359                 if (((FLAGS(nlmp) & FLG_RT_ANALYZED) == 0) ||
2360                     (DEPENDS(nlmp) == NULL))
2361                         continue;
2362 
2363                 /*
2364                  * Otherwise, this object exists and has dependencies, so add
2365                  * all of its dependencies to the handle were operating on.
2366                  */
2367                 if (aplist_append(&lmalp, nlmp, AL_CNT_DEPCLCT) == NULL)
2368                         return (0);
2369 
2370                 for (APLIST_TRAVERSE(lmalp, idx2, dlmp1)) {
2371                         Aliste          idx3;
2372                         Bnd_desc        *bdp;
2373 
2374                         /*
2375                          * Add any dependencies of this dependency to the
2376                          * dynamic dependency list so they can be further
2377                          * processed.
2378                          */
2379                         for (APLIST_TRAVERSE(DEPENDS(dlmp1), idx3, bdp)) {
2380                                 Rt_map  *dlmp2 = bdp->b_depend;
2381 
2382                                 if ((bdp->b_flags & BND_NEEDED) == 0)
2383                                         continue;
2384 
2385                                 if (aplist_test(&lmalp, dlmp2,
2386                                     AL_CNT_DEPCLCT) == 0) {
2387                                         free(lmalp);
2388                                         return (0);
2389                                 }
2390                         }
2391 
2392                         if (nlmp == dlmp1)
2393                                 continue;
2394 
2395                         if ((gdp =
2396                             hdl_add(ghp, dlmp1, rdflags, &ale)) == NULL) {
2397                                 free(lmalp);
2398                                 return (0);
2399                         }
2400 
2401                         if (ale == ALE_CREATE)
2402                                 (void) update_mode(dlmp1, MODE(dlmp1), nmode);
2403                 }
2404                 free(lmalp);
2405         }
2406         return (1);
2407 }
2408 
2409 /*
2410  * The central routine for loading shared objects.  Insures ldd() diagnostics,
2411  * handle creation, and any other related additions are all done in one place.
2412  */
2413 Rt_map *
2414 load_path(Lm_list *lml, Aliste lmco, Rt_map *clmp, int nmode, uint_t flags,
2415     Grp_hdl **hdl, Fdesc *fdp, Rej_desc *rej, int *in_nfavl)
2416 {
2417         const char      *name = fdp->fd_oname;
2418         Rt_map          *nlmp;
2419 
2420         if ((nmode & RTLD_NOLOAD) == 0) {
2421                 int     oin_nfavl;
2422 
2423                 /*
2424                  * Keep track of the number of not-found loads.
2425                  */
2426                 if (in_nfavl)
2427                         oin_nfavl = *in_nfavl;
2428 
2429                 /*
2430                  * If this isn't a noload request attempt to load the file.
2431                  */
2432                 if ((nlmp = load_so(lml, lmco, clmp, flags, fdp, rej,
2433                     in_nfavl)) == NULL)
2434                         return (NULL);
2435 
2436                 /*
2437                  * If this file has been found, reset the not-found load count.
2438                  * Although a search for this file might have inspected a number
2439                  * of non-existent path names, the file has been found so there
2440                  * is no need to accumulate a non-found count, as this may
2441                  * trigger unnecessary fall back (retry) processing.
2442                  */
2443                 if (in_nfavl)
2444                         *in_nfavl = oin_nfavl;
2445 
2446                 /*
2447                  * If we've loaded a library which identifies itself as not
2448                  * being dlopen()'able catch it here.  Let non-dlopen()'able
2449                  * objects through under RTLD_CONFGEN as they're only being
2450                  * mapped to be dldump()'ed.
2451                  */
2452                 if ((rtld_flags & RT_FL_APPLIC) && ((FLAGS(nlmp) &
2453                     (FLG_RT_NOOPEN | FLG_RT_RELOCED)) == FLG_RT_NOOPEN) &&
2454                     ((nmode & RTLD_CONFGEN) == 0)) {
2455                         Rej_desc        _rej = { 0 };
2456 
2457                         _rej.rej_name = name;
2458                         _rej.rej_type = SGS_REJ_STR;
2459                         _rej.rej_str = MSG_INTL(MSG_GEN_NOOPEN);
2460                         DBG_CALL(Dbg_file_rejected(lml, &_rej, M_MACH));
2461                         rejection_inherit(rej, &_rej);
2462                         remove_so(lml, nlmp, clmp);
2463                         return (NULL);
2464                 }
2465         } else {
2466                 /*
2467                  * If it's a NOLOAD request - check to see if the object
2468                  * has already been loaded.
2469                  */
2470                 /* LINTED */
2471                 if (nlmp = is_so_loaded(lml, name, in_nfavl)) {
2472                         if ((lml->lm_flags & LML_FLG_TRC_VERBOSE) &&
2473                             ((FLAGS1(clmp) & FL1_RT_LDDSTUB) == 0)) {
2474                                 (void) printf(MSG_INTL(MSG_LDD_FIL_FIND), name,
2475                                     NAME(clmp));
2476                                 /* BEGIN CSTYLED */
2477                                 if (*name == '/')
2478                                     (void) printf(MSG_ORIG(MSG_LDD_FIL_PATH),
2479                                         name, MSG_ORIG(MSG_STR_EMPTY),
2480                                         MSG_ORIG(MSG_STR_EMPTY));
2481                                 else
2482                                     (void) printf(MSG_ORIG(MSG_LDD_FIL_EQUIV),
2483                                         name, NAME(nlmp),
2484                                         MSG_ORIG(MSG_STR_EMPTY),
2485                                         MSG_ORIG(MSG_STR_EMPTY));
2486                                 /* END CSTYLED */
2487                         }
2488                 } else {
2489                         Rej_desc        _rej = { 0 };
2490 
2491                         _rej.rej_name = name;
2492                         _rej.rej_type = SGS_REJ_STR;
2493                         _rej.rej_str = strerror(ENOENT);
2494                         DBG_CALL(Dbg_file_rejected(lml, &_rej, M_MACH));
2495                         rejection_inherit(rej, &_rej);
2496                         return (NULL);
2497                 }
2498         }
2499 
2500         /*
2501          * Finish processing this loaded object.
2502          */
2503         if (load_finish(lml, name, clmp, nmode, flags, hdl, nlmp) == 0) {
2504                 FLAGS(nlmp) &= ~FLG_RT_NEWLOAD;
2505 
2506                 /*
2507                  * If this object has already been analyzed, then it is in use,
2508                  * so even though this operation has failed, it should not be
2509                  * torn down.
2510                  */
2511                 if ((FLAGS(nlmp) & FLG_RT_ANALYZED) == 0)
2512                         remove_so(lml, nlmp, clmp);
2513                 return (NULL);
2514         }
2515 
2516         /*
2517          * If this object is new, and we're being audited, tell the audit
2518          * libraries of the file we've just opened.  Note, if the new link-map
2519          * requires local auditing of its dependencies we also register its
2520          * opening.
2521          */
2522         if (FLAGS(nlmp) & FLG_RT_NEWLOAD) {
2523                 FLAGS(nlmp) &= ~FLG_RT_NEWLOAD;
2524 
2525                 if ((lml->lm_tflags | AFLAGS(clmp) | AFLAGS(nlmp)) &
2526                     LML_TFLG_AUD_MASK) {
2527                         if (audit_objopen(clmp, nlmp) == 0) {
2528                                 remove_so(lml, nlmp, clmp);
2529                                 return (NULL);
2530                         }
2531                 }
2532         }
2533         return (nlmp);
2534 }
2535 
2536 /*
2537  * Load one object from a possible list of objects.  Typically, for requests
2538  * such as NEEDED's, only one object is specified.  However, this object could
2539  * be specified using $ISALIST or $CAPABILITY, in which case only the first
2540  * object that can be loaded is used (ie. the best).
2541  */
2542 Rt_map *
2543 load_one(Lm_list *lml, Aliste lmco, Alist *palp, Rt_map *clmp, int mode,
2544     uint_t flags, Grp_hdl **hdl, int *in_nfavl)
2545 {
2546         Rej_desc        rej = { 0 };
2547         Aliste          idx;
2548         Pdesc           *pdp;
2549         const char      *name;
2550 
2551         for (ALIST_TRAVERSE(palp, idx, pdp)) {
2552                 Rt_map  *lmp = NULL;
2553 
2554                 /*
2555                  * A $CAPABILITY/$HWCAP requirement can expand into a number of
2556                  * candidates.
2557                  */
2558                 if (pdp->pd_flags & PD_TKN_CAP) {
2559                         lmp = load_cap(lml, lmco, pdp->pd_pname, clmp,
2560                             mode, (flags | FLG_RT_CAP), hdl, &rej, in_nfavl);
2561                 } else {
2562                         Fdesc   fd = { 0 };
2563 
2564                         /*
2565                          * Trace the inspection of this file, determine any
2566                          * auditor substitution, and seed the file descriptor
2567                          * with the originating name.
2568                          */
2569                         if (load_trace(lml, pdp, clmp, &fd) == NULL)
2570                                 continue;
2571 
2572                         /*
2573                          * Locate and load the file.
2574                          */
2575                         lmp = load_path(lml, lmco, clmp, mode, flags, hdl, &fd,
2576                             &rej, in_nfavl);
2577                 }
2578                 if (lmp)
2579                         return (lmp);
2580         }
2581 
2582         /*
2583          * If no objects can be found, use the first path name from the Alist
2584          * to provide a diagnostic.  If this pathname originated from an
2585          * expanded token, use the original name for any diagnostic output.
2586          */
2587         pdp = alist_item(palp, 0);
2588 
2589         if ((name = pdp->pd_oname) == 0)
2590                 name = pdp->pd_pname;
2591 
2592         file_notfound(lml, name, clmp, flags, &rej);
2593         return (NULL);
2594 }
2595 
2596 /*
2597  * Determine whether a symbol is defined as an interposer.
2598  */
2599 int
2600 is_sym_interposer(Rt_map *lmp, Sym *sym)
2601 {
2602         Syminfo *sip = SYMINFO(lmp);
2603 
2604         if (sip) {
2605                 ulong_t ndx;
2606 
2607                 ndx = (((ulong_t)sym - (ulong_t)SYMTAB(lmp)) / SYMENT(lmp));
2608                 /* LINTED */
2609                 sip = (Syminfo *)((char *)sip + (ndx * SYMINENT(lmp)));
2610                 if (sip->si_flags & SYMINFO_FLG_INTERPOSE)
2611                         return (1);
2612         }
2613         return (0);
2614 }
2615 
2616 /*
2617  * While processing direct or group bindings, determine whether the object to
2618  * which we've bound can be interposed upon.  In this context, copy relocations
2619  * are a form of interposition.
2620  */
2621 static int
2622 lookup_sym_interpose(Slookup *slp, Sresult *srp, uint_t *binfo, int *in_nfavl)
2623 {
2624         Rt_map          *lmp, *clmp, *dlmp = srp->sr_dmap;
2625         Sym             *osym = srp->sr_sym;
2626         Slookup         sl;
2627         Lm_list         *lml;
2628 
2629         /*
2630          * If we've bound to a copy relocation definition then we need to assign
2631          * this binding to the original copy reference.  Fabricate an inter-
2632          * position diagnostic, as this is a legitimate form of interposition.
2633          */
2634         if (osym && (FLAGS1(dlmp) & FL1_RT_COPYTOOK)) {
2635                 Rel_copy        *rcp;
2636                 Aliste          idx;
2637 
2638                 for (ALIST_TRAVERSE(COPY_R(dlmp), idx, rcp)) {
2639                         if ((osym == rcp->r_dsym) || (osym->st_value &&
2640                             (osym->st_value == rcp->r_dsym->st_value))) {
2641                                 srp->sr_dmap = rcp->r_rlmp;
2642                                 srp->sr_sym = rcp->r_rsym;
2643                                 *binfo |=
2644                                     (DBG_BINFO_INTERPOSE | DBG_BINFO_COPYREF);
2645                                 return (1);
2646                         }
2647                 }
2648         }
2649 
2650         /*
2651          * If a symbol binding has been established, inspect the link-map list
2652          * of the destination object, otherwise use the link-map list of the
2653          * original caller.
2654          */
2655         if (osym)
2656                 clmp = dlmp;
2657         else
2658                 clmp = slp->sl_cmap;
2659 
2660         lml = LIST(clmp);
2661         lmp = lml->lm_head;
2662 
2663         /*
2664          * Prior to Solaris 8, external references from an executable that were
2665          * bound to an uninitialized variable (.bss) within a shared object did
2666          * not establish a copy relocation.  This was thought to be an
2667          * optimization, to prevent copying zero's to zero's.  Typically,
2668          * interposition took its course, with the shared object binding to the
2669          * executables data definition.
2670          *
2671          * This scenario can be broken when this old executable runs against a
2672          * new shared object that is directly bound.  With no copy-relocation
2673          * record, ld.so.1 has no data to trigger the normal vectoring of the
2674          * binding to the executable.
2675          *
2676          * Starting with Solaris 8, a DT_FLAGS entry is written to all objects,
2677          * regardless of there being any DF_ flags entries.  Therefore, an
2678          * object without this dynamic tag is susceptible to the copy relocation
2679          * issue.  If the executable has no DT_FLAGS tag, and contains the same
2680          * .bss symbol definition as has been directly bound to, redirect the
2681          * binding to the executables data definition.
2682          */
2683         if (osym && ((FLAGS1(lmp) & FL1_RT_DTFLAGS) == 0) &&
2684             (FCT(lmp) == &elf_fct) &&
2685             (ELF_ST_TYPE(osym->st_info) != STT_FUNC) &&
2686             are_bits_zero(dlmp, osym, 0)) {
2687                 Sresult sr;
2688 
2689                 /*
2690                  * Initialize a local symbol result descriptor, using the
2691                  * original symbol name.  Initialize a local symbol lookup
2692                  * descriptor, using the original lookup information, and a
2693                  * new initial link-map.
2694                  */
2695                 SRESULT_INIT(sr, slp->sl_name);
2696                 sl = *slp;
2697                 sl.sl_imap = lmp;
2698 
2699                 /*
2700                  * Determine whether the same symbol name exists within the
2701                  * executable, that the size and type of symbol are the same,
2702                  * and that the symbol is also associated with .bss.
2703                  */
2704                 if (SYMINTP(lmp)(&sl, &sr, binfo, in_nfavl)) {
2705                         Sym     *isym = sr.sr_sym;
2706 
2707                         if ((isym->st_size == osym->st_size) &&
2708                             (isym->st_info == osym->st_info) &&
2709                             are_bits_zero(lmp, isym, 1)) {
2710                                 *srp = sr;
2711                                 *binfo |=
2712                                     (DBG_BINFO_INTERPOSE | DBG_BINFO_COPYREF);
2713                                 return (1);
2714                         }
2715                 }
2716         }
2717 
2718         if ((lml->lm_flags & LML_FLG_INTRPOSE) == 0)
2719                 return (NULL);
2720 
2721         /*
2722          * Traverse the list of known interposers to determine whether any
2723          * offer the same symbol.  Note, the head of the link-map could be
2724          * identified as an interposer.  Otherwise, skip the head of the
2725          * link-map, so that we don't bind to any .plt references, or
2726          * copy-relocation destinations unintentionally.
2727          */
2728         lmp = lml->lm_head;
2729         sl = *slp;
2730 
2731         if (((FLAGS(lmp) & MSK_RT_INTPOSE) == 0) || (sl.sl_flags & LKUP_COPY))
2732                 lmp = NEXT_RT_MAP(lmp);
2733 
2734         for (; lmp; lmp = NEXT_RT_MAP(lmp)) {
2735                 if (FLAGS(lmp) & FLG_RT_DELETE)
2736                         continue;
2737                 if ((FLAGS(lmp) & MSK_RT_INTPOSE) == 0)
2738                         break;
2739 
2740                 /*
2741                  * If we had already bound to this object, there's no point in
2742                  * searching it again, we're done.
2743                  */
2744                 if (lmp == dlmp)
2745                         break;
2746 
2747                 /*
2748                  * If this interposer can be inspected by the caller, look for
2749                  * the symbol within the interposer.
2750                  */
2751                 if (callable(clmp, lmp, 0, sl.sl_flags)) {
2752                         Sresult         sr;
2753 
2754                         /*
2755                          * Initialize a local symbol result descriptor, using
2756                          * the original symbol name.  Initialize a local symbol
2757                          * lookup descriptor, using the original lookup
2758                          * information, and a new initial link-map.
2759                          */
2760                         SRESULT_INIT(sr, slp->sl_name);
2761                         sl.sl_imap = lmp;
2762 
2763                         if (SYMINTP(lmp)(&sl, &sr, binfo, in_nfavl)) {
2764                                 Sym     *isym = sr.sr_sym;
2765                                 Rt_map  *ilmp = sr.sr_dmap;
2766 
2767                                 /*
2768                                  * If this object provides individual symbol
2769                                  * interposers, make sure that the symbol we
2770                                  * have found is tagged as an interposer.
2771                                  */
2772                                 if ((FLAGS(ilmp) & FLG_RT_SYMINTPO) &&
2773                                     (is_sym_interposer(ilmp, isym) == 0))
2774                                         continue;
2775 
2776                                 /*
2777                                  * Indicate this binding has occurred to an
2778                                  * interposer, and return the symbol.
2779                                  */
2780                                 *srp = sr;
2781                                 *binfo |= DBG_BINFO_INTERPOSE;
2782                                 return (1);
2783                         }
2784                 }
2785         }
2786         return (0);
2787 }
2788 
2789 /*
2790  * If an object specifies direct bindings (it contains a syminfo structure
2791  * describing where each binding was established during link-editing, and the
2792  * object was built -Bdirect), then look for the symbol in the specific object.
2793  */
2794 static int
2795 lookup_sym_direct(Slookup *slp, Sresult *srp, uint_t *binfo, Syminfo *sip,
2796     Rt_map *lmp, int *in_nfavl)
2797 {
2798         Rt_map  *dlmp, *clmp = slp->sl_cmap;
2799         int     ret;
2800         Slookup sl;
2801 
2802         /*
2803          * If a direct binding resolves to the definition of a copy relocated
2804          * variable, it must be redirected to the copy (in the executable) that
2805          * will eventually be made.  Typically, this redirection occurs in
2806          * lookup_sym_interpose().  But, there's an edge condition.  If a
2807          * directly bound executable contains pic code, there may be a
2808          * reference to a definition that will eventually have a copy made.
2809          * However, this copy relocation may not yet have occurred, because
2810          * the relocation making this reference comes before the relocation
2811          * that will create the copy.
2812          * Under direct bindings, the syminfo indicates that a copy will be
2813          * taken (SYMINFO_FLG_COPY).  This can only be set in an executable.
2814          * Thus, the caller must be the executable, so bind to the destination
2815          * of the copy within the executable.
2816          */
2817         if (((slp->sl_flags & LKUP_COPY) == 0) &&
2818             (sip->si_flags & SYMINFO_FLG_COPY)) {
2819                 slp->sl_imap = LIST(clmp)->lm_head;
2820 
2821                 if (ret = SYMINTP(clmp)(slp, srp, binfo, in_nfavl))
2822                         *binfo |= (DBG_BINFO_DIRECT | DBG_BINFO_COPYREF);
2823                 return (ret);
2824         }
2825 
2826         /*
2827          * If we need to directly bind to our parent, start looking in each
2828          * callers link map.
2829          */
2830         sl = *slp;
2831         sl.sl_flags |= LKUP_DIRECT;
2832         ret = 0;
2833 
2834         if (sip->si_boundto == SYMINFO_BT_PARENT) {
2835                 Aliste          idx1;
2836                 Bnd_desc        *bdp;
2837                 Grp_hdl         *ghp;
2838 
2839                 /*
2840                  * Determine the parent of this explicit dependency from its
2841                  * CALLERS()'s list.
2842                  */
2843                 for (APLIST_TRAVERSE(CALLERS(clmp), idx1, bdp)) {
2844                         sl.sl_imap = lmp = bdp->b_caller;
2845                         if (ret = SYMINTP(lmp)(&sl, srp, binfo, in_nfavl))
2846                                 goto found;
2847                 }
2848 
2849                 /*
2850                  * A caller can also be defined as the parent of a dlopen()
2851                  * call.  Determine whether this object has any handles.  The
2852                  * dependencies maintained with the handle represent the
2853                  * explicit dependencies of the dlopen()'ed object, and the
2854                  * calling parent.
2855                  */
2856                 for (APLIST_TRAVERSE(HANDLES(clmp), idx1, ghp)) {
2857                         Grp_desc        *gdp;
2858                         Aliste          idx2;
2859 
2860                         for (ALIST_TRAVERSE(ghp->gh_depends, idx2, gdp)) {
2861                                 if ((gdp->gd_flags & GPD_PARENT) == 0)
2862                                         continue;
2863                                 sl.sl_imap = lmp = gdp->gd_depend;
2864                                 if (ret = SYMINTP(lmp)(&sl, srp, binfo,
2865                                     in_nfavl))
2866                                         goto found;
2867                         }
2868                 }
2869         } else {
2870                 /*
2871                  * If we need to direct bind to anything else look in the
2872                  * link map associated with this symbol reference.
2873                  */
2874                 if (sip->si_boundto == SYMINFO_BT_SELF)
2875                         sl.sl_imap = lmp = clmp;
2876                 else
2877                         sl.sl_imap = lmp;
2878 
2879                 if (lmp)
2880                         ret = SYMINTP(lmp)(&sl, srp, binfo, in_nfavl);
2881         }
2882 found:
2883         if (ret)
2884                 *binfo |= DBG_BINFO_DIRECT;
2885 
2886         /*
2887          * If a reference to a directly bound symbol can't be satisfied, then
2888          * determine whether an interposer can provide the missing symbol.  If
2889          * a reference to a directly bound symbol is satisfied, then determine
2890          * whether that object can be interposed upon for this symbol.
2891          */
2892         dlmp = srp->sr_dmap;
2893         if ((ret == 0) || (dlmp && (LIST(dlmp)->lm_head != dlmp) &&
2894             (LIST(dlmp) == LIST(clmp)))) {
2895                 if (lookup_sym_interpose(slp, srp, binfo, in_nfavl))
2896                         return (1);
2897         }
2898 
2899         return (ret);
2900 }
2901 
2902 static int
2903 core_lookup_sym(Rt_map *ilmp, Slookup *slp, Sresult *srp, uint_t *binfo,
2904     Aliste off, int *in_nfavl)
2905 {
2906         Rt_map  *lmp;
2907 
2908         /*
2909          * Copy relocations should start their search after the head of the
2910          * main link-map control list.
2911          */
2912         if ((off == ALIST_OFF_DATA) && (slp->sl_flags & LKUP_COPY) && ilmp)
2913                 lmp = NEXT_RT_MAP(ilmp);
2914         else
2915                 lmp = ilmp;
2916 
2917         for (; lmp; lmp = NEXT_RT_MAP(lmp)) {
2918                 if (callable(slp->sl_cmap, lmp, 0, slp->sl_flags)) {
2919 
2920                         slp->sl_imap = lmp;
2921                         if ((SYMINTP(lmp)(slp, srp, binfo, in_nfavl)) ||
2922                             (*binfo & BINFO_MSK_TRYAGAIN))
2923                                 return (1);
2924                 }
2925         }
2926         return (0);
2927 }
2928 
2929 static int
2930 rescan_lazy_find_sym(Rt_map *ilmp, Slookup *slp, Sresult *srp, uint_t *binfo,
2931     int *in_nfavl)
2932 {
2933         Rt_map  *lmp;
2934 
2935         for (lmp = ilmp; lmp; lmp = NEXT_RT_MAP(lmp)) {
2936                 if (LAZY(lmp) == 0)
2937                         continue;
2938                 if (callable(slp->sl_cmap, lmp, 0, slp->sl_flags)) {
2939 
2940                         slp->sl_imap = lmp;
2941                         if (elf_lazy_find_sym(slp, srp, binfo, in_nfavl))
2942                                 return (1);
2943                 }
2944         }
2945         return (0);
2946 }
2947 
2948 static int
2949 _lookup_sym(Slookup *slp, Sresult *srp, uint_t *binfo, int *in_nfavl)
2950 {
2951         const char      *name = slp->sl_name;
2952         Rt_map          *clmp = slp->sl_cmap;
2953         Lm_list         *lml = LIST(clmp);
2954         Rt_map          *ilmp = slp->sl_imap, *lmp;
2955         ulong_t         rsymndx;
2956         int             ret;
2957         Syminfo         *sip;
2958         Slookup         sl;
2959 
2960         /*
2961          * Search the initial link map for the required symbol (this category is
2962          * selected by dlsym(), where individual link maps are searched for a
2963          * required symbol.  Therefore, we know we have permission to look at
2964          * the link map).
2965          */
2966         if (slp->sl_flags & LKUP_FIRST)
2967                 return (SYMINTP(ilmp)(slp, srp, binfo, in_nfavl));
2968 
2969         /*
2970          * Determine whether this lookup can be satisfied by an objects direct,
2971          * or lazy binding information.  This is triggered by a relocation from
2972          * the object (hence rsymndx is set).
2973          */
2974         if (((rsymndx = slp->sl_rsymndx) != 0) &&
2975             ((sip = SYMINFO(clmp)) != NULL)) {
2976                 uint_t  bound;
2977 
2978                 /*
2979                  * Find the corresponding Syminfo entry for the original
2980                  * referencing symbol.
2981                  */
2982                 /* LINTED */
2983                 sip = (Syminfo *)((char *)sip + (rsymndx * SYMINENT(clmp)));
2984                 bound = sip->si_boundto;
2985 
2986                 /*
2987                  * Identify any EXTERN or PARENT references for ldd(1).
2988                  */
2989                 if ((lml->lm_flags & LML_FLG_TRC_WARN) &&
2990                     (bound > SYMINFO_BT_LOWRESERVE)) {
2991                         if (bound == SYMINFO_BT_PARENT)
2992                                 *binfo |= DBG_BINFO_REF_PARENT;
2993                         if (bound == SYMINFO_BT_EXTERN)
2994                                 *binfo |= DBG_BINFO_REF_EXTERN;
2995                 }
2996 
2997                 /*
2998                  * If the symbol information indicates a direct binding,
2999                  * determine the link map that is required to satisfy the
3000                  * binding.  Note, if the dependency can not be found, but a
3001                  * direct binding isn't required, we will still fall through
3002                  * to perform any default symbol search.
3003                  */
3004                 if (sip->si_flags & SYMINFO_FLG_DIRECT) {
3005 
3006                         lmp = 0;
3007                         if (bound < SYMINFO_BT_LOWRESERVE)
3008                                 lmp = elf_lazy_load(clmp, slp, bound,
3009                                     name, 0, NULL, in_nfavl);
3010 
3011                         /*
3012                          * If direct bindings have been disabled, and this isn't
3013                          * a translator, skip any direct binding now that we've
3014                          * ensured the resolving object has been loaded.
3015                          *
3016                          * If we need to direct bind to anything, we look in
3017                          * ourselves, our parent, or in the link map we've just
3018                          * loaded.  Otherwise, even though we may have lazily
3019                          * loaded an object we still continue to search for
3020                          * symbols from the head of the link map list.
3021                          */
3022                         if (((FLAGS(clmp) & FLG_RT_TRANS) ||
3023                             (((lml->lm_tflags & LML_TFLG_NODIRECT) == 0) &&
3024                             ((slp->sl_flags & LKUP_SINGLETON) == 0))) &&
3025                             ((FLAGS1(clmp) & FL1_RT_DIRECT) ||
3026                             (sip->si_flags & SYMINFO_FLG_DIRECTBIND))) {
3027                                 ret = lookup_sym_direct(slp, srp, binfo,
3028                                     sip, lmp, in_nfavl);
3029 
3030                                 /*
3031                                  * Determine whether this direct binding has
3032                                  * been rejected.  If we've bound to a singleton
3033                                  * without following a singleton search, then
3034                                  * return.  The caller detects this condition
3035                                  * and will trigger a new singleton search.
3036                                  *
3037                                  * For any other rejection (such as binding to
3038                                  * a symbol labeled as nodirect - presumably
3039                                  * because the symbol definition has been
3040                                  * changed since the referring object was last
3041                                  * built), fall through to a standard symbol
3042                                  * search.
3043                                  */
3044                                 if (((*binfo & BINFO_MSK_REJECTED) == 0) ||
3045                                     (*binfo & BINFO_MSK_TRYAGAIN))
3046                                         return (ret);
3047 
3048                                 *binfo &= ~BINFO_MSK_REJECTED;
3049                         }
3050                 }
3051         }
3052 
3053         /*
3054          * Duplicate the lookup information, as we'll need to modify this
3055          * information for some of the following searches.
3056          */
3057         sl = *slp;
3058 
3059         /*
3060          * If the referencing object has the DF_SYMBOLIC flag set, look in the
3061          * referencing object for the symbol first.  Failing that, fall back to
3062          * our generic search.
3063          */
3064         if ((FLAGS1(clmp) & FL1_RT_SYMBOLIC) &&
3065             ((sl.sl_flags & LKUP_SINGLETON) == 0)) {
3066 
3067                 sl.sl_imap = clmp;
3068                 if (SYMINTP(clmp)(&sl, srp, binfo, in_nfavl)) {
3069                         Rt_map  *dlmp = srp->sr_dmap;
3070                         ulong_t dsymndx = (((ulong_t)srp->sr_sym -
3071                             (ulong_t)SYMTAB(dlmp)) / SYMENT(dlmp));
3072 
3073                         /*
3074                          * Make sure this symbol hasn't explicitly been defined
3075                          * as nodirect.
3076                          */
3077                         if (((sip = SYMINFO(dlmp)) == 0) ||
3078                             /* LINTED */
3079                             ((sip = (Syminfo *)((char *)sip +
3080                             (dsymndx * SYMINENT(dlmp)))) == 0) ||
3081                             ((sip->si_flags & SYMINFO_FLG_NOEXTDIRECT) == 0))
3082                                 return (1);
3083                 }
3084         }
3085 
3086         sl.sl_flags |= LKUP_STANDARD;
3087 
3088         /*
3089          * If this lookup originates from a standard relocation, then traverse
3090          * all link-map control lists, inspecting any object that is available
3091          * to this caller.  Otherwise, traverse the link-map control list
3092          * associated with the caller.
3093          */
3094         if (sl.sl_flags & LKUP_STDRELOC) {
3095                 Aliste  off;
3096                 Lm_cntl *lmc;
3097 
3098                 ret = 0;
3099 
3100                 for (ALIST_TRAVERSE_BY_OFFSET(lml->lm_lists, off, lmc)) {
3101                         if (((ret = core_lookup_sym(lmc->lc_head, &sl, srp,
3102                             binfo, off, in_nfavl)) != 0) ||
3103                             (*binfo & BINFO_MSK_TRYAGAIN))
3104                                 break;
3105                 }
3106         } else
3107                 ret = core_lookup_sym(ilmp, &sl, srp, binfo, ALIST_OFF_DATA,
3108                     in_nfavl);
3109 
3110         /*
3111          * If a symbol binding should be retried, return so that the search can
3112          * be repeated.
3113          */
3114         if (*binfo & BINFO_MSK_TRYAGAIN)
3115                 return (0);
3116 
3117         /*
3118          * To allow transitioning into a world of lazy loading dependencies see
3119          * if this link map contains objects that have lazy dependencies still
3120          * outstanding.  If so, and we haven't been able to locate a non-weak
3121          * symbol reference, start bringing in any lazy dependencies to see if
3122          * the reference can be satisfied.  Use of dlsym(RTLD_PROBE) sets the
3123          * LKUP_NOFALLBACK flag, and this flag disables this fall back.
3124          */
3125         if ((ret == 0) && ((sl.sl_flags & LKUP_NOFALLBACK) == 0)) {
3126                 if ((lmp = ilmp) == 0)
3127                         lmp = LIST(clmp)->lm_head;
3128 
3129                 lml = LIST(lmp);
3130                 if ((sl.sl_flags & LKUP_WEAK) || (lml->lm_lazy == 0))
3131                         return (NULL);
3132 
3133                 DBG_CALL(Dbg_syms_lazy_rescan(lml, name));
3134 
3135                 /*
3136                  * If this request originated from a dlsym(RTLD_NEXT) then start
3137                  * looking for dependencies from the caller, otherwise use the
3138                  * initial link-map.
3139                  */
3140                 if (sl.sl_flags & LKUP_NEXT)
3141                         ret = rescan_lazy_find_sym(clmp, &sl, srp, binfo,
3142                             in_nfavl);
3143                 else {
3144                         Aliste  idx;
3145                         Lm_cntl *lmc;
3146 
3147                         for (ALIST_TRAVERSE(lml->lm_lists, idx, lmc)) {
3148                                 sl.sl_flags |= LKUP_NOFALLBACK;
3149                                 if (ret = rescan_lazy_find_sym(lmc->lc_head,
3150                                     &sl, srp, binfo, in_nfavl))
3151                                         break;
3152                         }
3153                 }
3154         }
3155         return (ret);
3156 }
3157 
3158 /*
3159  * Symbol lookup routine.  Takes an ELF symbol name, and a list of link maps to
3160  * search.  If successful, return a pointer to the symbol table entry, a
3161  * pointer to the link map of the enclosing object, and information relating
3162  * to the type of binding.  Else return a null pointer.
3163  *
3164  * To improve ELF performance, we first compute the ELF hash value and pass
3165  * it to each _lookup_sym() routine.  The ELF function will use this value to
3166  * locate the symbol, the a.out function will simply ignore it.
3167  */
3168 int
3169 lookup_sym(Slookup *slp, Sresult *srp, uint_t *binfo, int *in_nfavl)
3170 {
3171         Rt_map          *clmp = slp->sl_cmap;
3172         Sym             *rsym = slp->sl_rsym;
3173         uchar_t         rtype = slp->sl_rtype, vis;
3174         int             ret, mode;
3175 
3176         if (slp->sl_hash == 0)
3177                 slp->sl_hash = elf_hash(slp->sl_name);
3178         *binfo = 0;
3179 
3180         if (rsym) {
3181                 vis = ELF_ST_VISIBILITY(rsym->st_other);
3182 
3183                 /*
3184                  * Symbols that are defined as protected, or hidden, within an
3185                  * object usually have any relocation references from within
3186                  * the same object bound at link-edit time.  Therefore, ld.so.1
3187                  * is not involved.  However, if a reference is to a
3188                  * capabilities symbol, this reference must be resolved at
3189                  * runtime.  In this case look directly within the calling
3190                  * object, and only within the calling object, for these
3191                  * symbols.  Note, an object may still use dlsym() to search
3192                  * externally for a symbol which is defined as protected within
3193                  * the same object.
3194                  */
3195                 if ((rsym->st_shndx != SHN_UNDEF) &&
3196                     ((slp->sl_flags & LKUP_DLSYM) == 0) &&
3197                     ((vis == STV_PROTECTED) || (vis == STV_HIDDEN))) {
3198                         slp->sl_imap = clmp;
3199                         return (SYMINTP(clmp)(slp, srp, binfo, in_nfavl));
3200                 }
3201 
3202                 /*
3203                  * Establish any state that might be associated with a symbol
3204                  * reference.
3205                  */
3206                 if ((slp->sl_flags & LKUP_STDRELOC) &&
3207                     (ELF_ST_BIND(rsym->st_info) == STB_WEAK))
3208                         slp->sl_flags |= LKUP_WEAK;
3209 
3210                 if (vis == STV_SINGLETON)
3211                         slp->sl_flags |= LKUP_SINGLETON;
3212         }
3213 
3214         /*
3215          * Establish any lookup state required for this type of relocation.
3216          */
3217         if ((slp->sl_flags & LKUP_STDRELOC) && rtype) {
3218                 if (rtype == M_R_COPY)
3219                         slp->sl_flags |= LKUP_COPY;
3220 
3221                 if (rtype != M_R_JMP_SLOT)
3222                         slp->sl_flags |= LKUP_SPEC;
3223         }
3224 
3225         /*
3226          * Under ldd -w, any unresolved weak references are diagnosed.  Set the
3227          * symbol binding as global to trigger a relocation error if the symbol
3228          * can not be found.
3229          */
3230         if (rsym) {
3231                 if (LIST(slp->sl_cmap)->lm_flags & LML_FLG_TRC_NOUNRESWEAK)
3232                         slp->sl_bind = STB_GLOBAL;
3233                 else if ((slp->sl_bind = ELF_ST_BIND(rsym->st_info)) ==
3234                     STB_WEAK)
3235                         slp->sl_flags |= LKUP_WEAK;
3236         }
3237 
3238         /*
3239          * Save the callers MODE().
3240          */
3241         mode = MODE(clmp);
3242 
3243         /*
3244          * Carry out an initial symbol search.  This search takes into account
3245          * all the modes of the requested search.
3246          */
3247         if (((ret = _lookup_sym(slp, srp, binfo, in_nfavl)) == 0) &&
3248             (*binfo & BINFO_MSK_TRYAGAIN)) {
3249                 Slookup sl = *slp;
3250 
3251                 /*
3252                  * Try the symbol search again.  This retry can be necessary if:
3253                  *
3254                  *  -   a binding has been rejected because of binding to a
3255                  *      singleton without going through a singleton search.
3256                  *  -   a group binding has resulted in binding to a symbol
3257                  *      that indicates no-direct binding.
3258                  *
3259                  * Reset the lookup data, and try again.
3260                  */
3261                 sl.sl_imap = LIST(sl.sl_cmap)->lm_head;
3262                 sl.sl_flags &= ~(LKUP_FIRST | LKUP_SELF | LKUP_NEXT);
3263                 sl.sl_rsymndx = 0;
3264 
3265                 if (*binfo & BINFO_REJSINGLE)
3266                         sl.sl_flags |= LKUP_SINGLETON;
3267                 if (*binfo & BINFO_REJGROUP) {
3268                         sl.sl_flags |= LKUP_WORLD;
3269                         mode |= RTLD_WORLD;
3270                 }
3271                 *binfo &= ~BINFO_MSK_REJECTED;
3272 
3273                 ret = _lookup_sym(&sl, srp, binfo, in_nfavl);
3274         }
3275 
3276         /*
3277          * If the caller is restricted to a symbol search within its group,
3278          * determine if it is necessary to follow a binding from outside of
3279          * the group.
3280          */
3281         if (((mode & (RTLD_GROUP | RTLD_WORLD)) == RTLD_GROUP) &&
3282             (lookup_sym_interpose(slp, srp, binfo, in_nfavl)))
3283                 return (1);
3284 
3285         return (ret);
3286 }
3287 
3288 /*
3289  * Associate a binding descriptor with a caller and its dependency, or update
3290  * an existing descriptor.
3291  */
3292 int
3293 bind_one(Rt_map *clmp, Rt_map *dlmp, uint_t flags)
3294 {
3295         Bnd_desc        *bdp;
3296         Aliste          idx;
3297         int             found = ALE_CREATE;
3298 
3299         /*
3300          * Determine whether a binding descriptor already exists between the
3301          * two objects.
3302          */
3303         for (APLIST_TRAVERSE(DEPENDS(clmp), idx, bdp)) {
3304                 if (bdp->b_depend == dlmp) {
3305                         found = ALE_EXISTS;
3306                         break;
3307                 }
3308         }
3309 
3310         if (found == ALE_CREATE) {
3311                 /*
3312                  * Create a new binding descriptor.
3313                  */
3314                 if ((bdp = malloc(sizeof (Bnd_desc))) == NULL)
3315                         return (0);
3316 
3317                 bdp->b_caller = clmp;
3318                 bdp->b_depend = dlmp;
3319                 bdp->b_flags = 0;
3320 
3321                 /*
3322                  * Append the binding descriptor to the caller and the
3323                  * dependency.
3324                  */
3325                 if (aplist_append(&DEPENDS(clmp), bdp, AL_CNT_DEPENDS) == NULL)
3326                         return (0);
3327 
3328                 if (aplist_append(&CALLERS(dlmp), bdp, AL_CNT_CALLERS) == NULL)
3329                         return (0);
3330         }
3331 
3332         if ((found == ALE_CREATE) || ((bdp->b_flags & flags) != flags)) {
3333                 bdp->b_flags |= flags;
3334 
3335                 if (flags & BND_REFER)
3336                         FLAGS1(dlmp) |= FL1_RT_USED;
3337 
3338                 DBG_CALL(Dbg_file_bind_entry(LIST(clmp), bdp));
3339         }
3340         return (found);
3341 }
3342 
3343 /*
3344  * Cleanup after relocation processing.
3345  */
3346 int
3347 relocate_finish(Rt_map *lmp, APlist *bound, int ret)
3348 {
3349         DBG_CALL(Dbg_reloc_run(lmp, 0, ret, DBG_REL_FINISH));
3350 
3351         /*
3352          * Establish bindings to all objects that have been bound to.
3353          */
3354         if (bound) {
3355                 Rt_map  *_lmp;
3356                 Word    used;
3357 
3358                 /*
3359                  * Only create bindings if the callers relocation was
3360                  * successful (ret != 0), otherwise the object will eventually
3361                  * be torn down.  Create these bindings if running under ldd(1)
3362                  * with the -U/-u options regardless of relocation errors, as
3363                  * the unused processing needs to traverse these bindings to
3364                  * diagnose unused objects.
3365                  */
3366                 used = LIST(lmp)->lm_flags &
3367                     (LML_FLG_TRC_UNREF | LML_FLG_TRC_UNUSED);
3368 
3369                 if (ret || used) {
3370                         Aliste  idx;
3371 
3372                         for (APLIST_TRAVERSE(bound, idx, _lmp)) {
3373                                 if (bind_one(lmp, _lmp, BND_REFER) || used)
3374                                         continue;
3375 
3376                                 ret = 0;
3377                                 break;
3378                         }
3379                 }
3380                 free(bound);
3381         }
3382 
3383         return (ret);
3384 }
3385 
3386 /*
3387  * Function to correct protection settings.  Segments are all mapped initially
3388  * with permissions as given in the segment header.  We need to turn on write
3389  * permissions on a text segment if there are any relocations against that
3390  * segment, and then turn write permission back off again before returning
3391  * control to the caller.  This function turns the permission on or off
3392  * depending on the value of the permission argument.
3393  */
3394 int
3395 set_prot(Rt_map *lmp, mmapobj_result_t *mpp, int perm)
3396 {
3397         int     prot;
3398 
3399         /*
3400          * If this is an allocated image (ie. a relocatable object) we can't
3401          * mprotect() anything.
3402          */
3403         if (FLAGS(lmp) & FLG_RT_IMGALLOC)
3404                 return (1);
3405 
3406         DBG_CALL(Dbg_file_prot(lmp, perm));
3407 
3408         if (perm)
3409                 prot = mpp->mr_prot | PROT_WRITE;
3410         else
3411                 prot = mpp->mr_prot & ~PROT_WRITE;
3412 
3413         if (mprotect((void *)(uintptr_t)mpp->mr_addr,
3414             mpp->mr_msize, prot) == -1) {
3415                 int     err = errno;
3416                 eprintf(LIST(lmp), ERR_FATAL, MSG_INTL(MSG_SYS_MPROT),
3417                     NAME(lmp), strerror(err));
3418                 return (0);
3419         }
3420         mpp->mr_prot = prot;
3421         return (1);
3422 }