1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  *      Copyright (c) 1988 AT&T
  24  *        All Rights Reserved
  25  *
  26  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  27  * Use is subject to license terms.
  28  */
  29 
  30 /*
  31  * Copyright 2019 Joyent, Inc.
  32  */
  33 
  34 /*
  35  * Map file parsing (Shared Support Code).
  36  */
  37 #include        <stdio.h>
  38 #include        <errno.h>
  39 #include        "msg.h"
  40 #include        "_libld.h"
  41 #include        "_map.h"
  42 
  43 /*
  44  * Given a NULL terminated array of structures of arbitrary type, where
  45  * each struct contains (among other fields) a character pointer field
  46  * giving that struct a unique name, return the address of the struct
  47  * that matches the given name.
  48  *
  49  * entry:
  50  *      name - "Keyword" name to be found.
  51  *      array - Base address of array
  52  *      name_offset - Offset of the name field within the struct
  53  *              type used by this array, as generated via
  54  *              SGSOFFSETOF().
  55  *      elt_size - sizeof the basic array element type
  56  *
  57  * exit:
  58  *      Using a case insensitive comparison, name is compared to the
  59  *      name of each element of the array. The address of the first
  60  *      match found is returned. If the desired name is not found,
  61  *      NULL is returned.
  62  *
  63  * note:
  64  *      This routine is completely type-unsafe. The upside is that this
  65  *      single routine is able to search arrays of arbitrary type, leaving
  66  *      the caller free to structure their array in any way that is convenient
  67  *      to solve the problem at hand.
  68  */
  69 #ifndef _ELF64
  70 void *
  71 ld_map_kwfind(const char *name, void *array, size_t name_offset,
  72     size_t elt_size)
  73 {
  74         for (; ; array = elt_size + (char *)array) {
  75                 /* LINTED E_BAD_PTR_CAST_ALIGN */
  76                 const char *arr_name = *((const char **)
  77                     (name_offset + (const char *) array));
  78 
  79                 if (arr_name == NULL)
  80                         return (NULL);
  81 
  82                 if (strcasecmp(name, arr_name) == 0)
  83                         return (array);
  84         }
  85 
  86         /*NOTREACHED*/
  87 }
  88 #endif
  89 
  90 /*
  91  * Given the same NULL terminated array accepted by ld_map_kwfind(), format
  92  * the strings into a comma separated list of names.
  93  *
  94  * entry:
  95  *      array - Base address of array
  96  *      name_offset - Offset of the name field within the struct
  97  *              type used by this array, as generated via
  98  *              SGSOFFSETOF().
  99  *      elt_size - sizeof the basic array element type
 100  *      buf - Buffer to receive output
 101  *      bufsize - sizeof(buf)
 102  *
 103  * exit:
 104  *      As many of the names as will fit are formatted into buf. If all the
 105  *      names do not fit, the remainder are quietly clipped. The caller must
 106  *      ensure that there is sufficient room. buf is returned, for convenience
 107  *      in using this function as an argument for printing.
 108  */
 109 #ifndef _ELF64
 110 char *
 111 ld_map_kwnames(void *array, size_t name_offset, size_t elt_size, char *buf,
 112     size_t bufsize)
 113 {
 114         size_t  cnt = 0;
 115         size_t  len;
 116         char    *str = buf;
 117 
 118         for (; bufsize > 1; array = elt_size + (char *)array, cnt++) {
 119                 /* LINTED E_BAD_PTR_CAST_ALIGN */
 120                 const char *arr_name = *((const char **)
 121                     (name_offset + (const char *) array));
 122 
 123                 if (arr_name == NULL)
 124                         break;
 125 
 126                 if (cnt > 0) {
 127                         if (bufsize < 3)
 128                                 break;
 129                         *str++ = ',';
 130                         *str++ = ' ';
 131                         bufsize -= 2;
 132                         *(str + 1) = '\0';
 133                 }
 134 
 135                 len = strlcpy(str, arr_name, bufsize);
 136                 if (len >= bufsize)
 137                         break;
 138                 str += len;
 139                 bufsize -= len;
 140         }
 141 
 142         return (buf);
 143 }
 144 #endif
 145 
 146 /*
 147  * Create a pseudo input file descriptor to represent the specified Mapfile.
 148  * An input descriptor is required any time a symbol is generated.
 149  *
 150  * entry:
 151  *      mf - Mapfile descriptor.
 152  *
 153  * exit:
 154  *      If an input descriptor was already created for this mapfile
 155  *      by a previous call, it is returned. Otherwise, a new descriptor
 156  *      is created, entered into the mapfile descriptor, and returned.
 157  *
 158  *      Success is indicated by a non-NULL return value, failure by NULL.
 159  */
 160 Ifl_desc *
 161 ld_map_ifl(Mapfile *mf)
 162 {
 163         Ifl_desc        *ifl;
 164 
 165         /*
 166          * If we've already created a pseudo input descriptor for this
 167          * mapfile, reuse it.
 168          */
 169         if (mf->mf_ifl != NULL)
 170                 return (mf->mf_ifl);
 171 
 172         if ((ifl = libld_calloc(sizeof (Ifl_desc), 1)) == NULL)
 173                 return (NULL);
 174         ifl->ifl_name = mf->mf_name;
 175         ifl->ifl_flags = (FLG_IF_MAPFILE | FLG_IF_NEEDED | FLG_IF_FILEREF);
 176         if ((ifl->ifl_ehdr = libld_calloc(sizeof (Ehdr), 1)) == NULL)
 177                 return (NULL);
 178         ifl->ifl_ehdr->e_type = ET_REL;
 179 
 180         if (aplist_append(&mf->mf_ofl->ofl_objs, ifl, AL_CNT_OFL_OBJS) == NULL)
 181                 return (NULL);
 182 
 183         mf->mf_ifl = ifl;
 184         return (mf->mf_ifl);
 185 }
 186 
 187 /*
 188  * Given a capability tag type, set the override bit in the output descriptor.
 189  * This prevents the use of capability values of that type from the input
 190  * objects.
 191  */
 192 void
 193 ld_map_cap_set_ovflag(Mapfile *mf, Word type)
 194 {
 195         /*
 196          * Map capability tag to the corresponding output descriptor
 197          * override flag.
 198          */
 199         static ofl_flag_t override_flag[CA_SUNW_NUM] = {
 200                 0,                      /* CA_SUNW_NULL */
 201                 FLG_OF1_OVHWCAP1,       /* CA_SUNW_HW_1 */
 202                 FLG_OF1_OVSFCAP1,       /* CA_SUNW_SF_1 */
 203                 FLG_OF1_OVHWCAP2,       /* CA_SUNW_HW_2 */
 204                 FLG_OF1_OVPLATCAP,      /* CA_SUNW_PLAT */
 205                 FLG_OF1_OVMACHCAP,      /* CA_SUNW_MACH */
 206                 FLG_OF1_OVIDCAP         /* CA_SUNW_ID */
 207         };
 208 #if CA_SUNW_NUM != (CA_SUNW_ID + 1)
 209 #error "CA_SUNW_NUM has grown"
 210 #endif
 211         mf->mf_ofl->ofl_flags1 |= override_flag[type];
 212 }
 213 
 214 /*
 215  * Sanity check the given capability bitmask.
 216  */
 217 Boolean
 218 ld_map_cap_sanitize(Mapfile *mf, Word type, Capmask *capmask)
 219 {
 220         elfcap_mask_t   mask;
 221 
 222         switch (type) {
 223         case CA_SUNW_SF_1:
 224                 /*
 225                  * Unlike hardware capabilities, we do not allow setting
 226                  * software capability bits that do not have known definitions.
 227                  * Software capability tokens have to be validated as a unit
 228                  * as the bits can affect each others meaning (see sf1_cap()
 229                  * in files.c).
 230                  */
 231                 if ((mask = (capmask->cm_val & ~SF1_SUNW_MASK)) != 0) {
 232                         mf_warn(mf, MSG_INTL(MSG_MAP_BADSF1),
 233                             EC_XWORD(mask));
 234                         capmask->cm_val &= SF1_SUNW_MASK;
 235                 }
 236                 if ((capmask->cm_val &
 237                     (SF1_SUNW_FPKNWN | SF1_SUNW_FPUSED)) == SF1_SUNW_FPUSED) {
 238                         mf_warn(mf, MSG_INTL(MSG_MAP_BADSF1),
 239                             EC_XWORD(SF1_SUNW_FPUSED));
 240                         capmask->cm_val &= ~SF1_SUNW_FPUSED;
 241                 }
 242 #if     !defined(_ELF64)
 243                 /*
 244                  * The SF1_SUNW_ADDR32 software capability is only meaningful
 245                  * when building a 64-bit object.  Warn the user, and remove the
 246                  * setting, if we're building a 32-bit object.
 247                  */
 248                 if (capmask->cm_val & SF1_SUNW_ADDR32) {
 249                         mf_warn0(mf, MSG_INTL(MSG_MAP_INADDR32SF1));
 250                         capmask->cm_val &= ~SF1_SUNW_ADDR32;
 251                 }
 252 #endif
 253         }
 254 
 255         return (TRUE);
 256 }
 257 
 258 /*
 259  * Return the shared object control definition structure (ofl_socntl)
 260  * for the specified object, creating one if necessary.
 261  *
 262  * entry:
 263  *      mf - Mapfile descriptor
 264  *      obj_name - Name of object
 265  *
 266  * exit:
 267  *      Returns the pointer to the definition structure, or NULL on error.
 268  */
 269 Sdf_desc *
 270 ld_map_dv(Mapfile *mf, const char *obj_name)
 271 {
 272         Sdf_desc        *sdf;
 273 
 274         /*
 275          * If a shared object definition for this file already exists use it,
 276          * otherwise allocate a new descriptor.
 277          */
 278         if ((sdf = sdf_find(obj_name, mf->mf_ofl->ofl_socntl)) == NULL) {
 279                 if ((sdf = sdf_add(obj_name, &mf->mf_ofl->ofl_socntl)) ==
 280                     (Sdf_desc *)S_ERROR)
 281                         return (NULL);
 282                 sdf->sdf_rfile = mf->mf_name;
 283         }
 284 
 285         DBG_CALL(Dbg_map_dv(mf->mf_ofl->ofl_lml, sdf->sdf_name,
 286             mf->mf_lineno));
 287         return (sdf);
 288 }
 289 
 290 
 291 Boolean
 292 ld_map_dv_entry(Mapfile *mf, Sdf_desc *sdf, Boolean require,
 293     const char *version)
 294 {
 295         Sdv_desc        sdv;
 296 
 297         sdv.sdv_name = version;
 298         sdv.sdv_ref = mf->mf_name;
 299         sdv.sdv_flags = 0;
 300 
 301 
 302         if (require) {
 303                 /*
 304                  * Add a VERNEED entry for the specified version
 305                  * from this object:
 306                  *
 307                  *      MapfileVersion  Syntax
 308                  *      ----------------------------------------
 309                  *      1               obj - $ADDVERS=version;
 310                  *      2               DEPENDENCY obj { REQUIRE=version };
 311                  */
 312                 sdf->sdf_flags |= FLG_SDF_ADDVER;
 313 
 314                 if (alist_append(&sdf->sdf_verneed, &sdv, sizeof (Sdv_desc),
 315                     AL_CNT_SDF_VERSIONS) == NULL)
 316                         return (FALSE);
 317         } else {                /* Allow */
 318                 /*
 319                  * Allow linking to symbols found in this version, or
 320                  * from the versions it inherits from.
 321                  *
 322                  *      MapfileVersion  Syntax
 323                  *      ----------------------------------------
 324                  *      1               obj - version;
 325                  *      2               DEPENDENCY obj { ALLOW=version };
 326                  */
 327                 sdf->sdf_flags |= FLG_SDF_SELECT;
 328 
 329                 if (alist_append(&sdf->sdf_vers, &sdv, sizeof (Sdv_desc),
 330                     AL_CNT_SDF_VERSIONS) == NULL)
 331                         return (FALSE);
 332         }
 333 
 334         DBG_CALL(Dbg_map_dv_entry(mf->mf_ofl->ofl_lml, mf->mf_lineno,
 335             require, version));
 336 
 337         return (TRUE);
 338 }
 339 
 340 /*
 341  * Given a segment descriptor, return its index.
 342  *
 343  * entry:
 344  *      mf - Mapfile descriptor
 345  *      sgp - Segment for which index is desired
 346  *
 347  * exit:
 348  *      Index of segment is returned.
 349  */
 350 Xword
 351 ld_map_seg_index(Mapfile *mf, Sg_desc *sgp)
 352 {
 353         Aliste          idx;
 354         Sg_desc         *sgp2;
 355         Ofl_desc        *ofl = mf->mf_ofl;
 356 
 357         for (APLIST_TRAVERSE(ofl->ofl_segs, idx, sgp2))
 358                 if (sgp == sgp2)
 359                         break;
 360 
 361         return (idx);
 362 }
 363 
 364 /*
 365  * Add a section name to the output section sort list for the given
 366  * segment.
 367  *
 368  * entry:
 369  *      mf - Mapfile descriptor
 370  *      sgp - Segment in question
 371  *      sec_name - Name of section to be added.
 372  *
 373  * exit:
 374  *      Returns TRUE for success, FALSE for failure.
 375  */
 376 Boolean
 377 ld_map_seg_os_order_add(Mapfile *mf, Sg_desc *sgp, const char *sec_name)
 378 {
 379         Aliste          idx;
 380         Sec_order       *scop;
 381 
 382         /*
 383          * Make sure it's not already on the list
 384          */
 385         for (ALIST_TRAVERSE(sgp->sg_os_order, idx, scop))
 386                 if (strcmp(scop->sco_secname, sec_name) == 0) {
 387                         mf_fatal(mf, MSG_INTL(MSG_MAP_DUP_OS_ORD), sec_name);
 388                         return (FALSE);
 389                 }
 390 
 391 
 392         scop = alist_append(&sgp->sg_os_order, NULL, sizeof (Sec_order),
 393             AL_CNT_SG_SECORDER);
 394         if (scop == NULL)
 395                 return (FALSE);
 396 
 397         scop->sco_secname = sec_name;
 398 
 399         DBG_CALL(Dbg_map_seg_os_order(mf->mf_ofl->ofl_lml, sgp, sec_name,
 400             alist_nitems(sgp->sg_os_order), mf->mf_lineno));
 401 
 402         /*
 403          * Output section ordering is a relatively expensive operation,
 404          * and one that is generally not used. In order to avoid needless
 405          * work, the FLG_OF_OS_ORDER must be set when it will be needed.
 406          * The section we just added needs this flag to be set. However,
 407          * it is possible that a subsequent mapfile directive may come
 408          * along and clear the order list, making it unnecessary.
 409          *
 410          * Instead of setting it here, we do a final pass over the segments
 411          * in ld_map_finalize() and set it there if a segment with sorting
 412          * requirements is seen.
 413          */
 414 
 415         return (TRUE);
 416 }
 417 
 418 /*
 419  * Add a size symbol to a segment
 420  *
 421  * entry:
 422  *      mf - Mapfile descriptor
 423  *      sgp - Segment descriptor
 424  *      eq_tol - Type of assignment: TK_EQUAL, or TK_PLUSEQ
 425  *      symname - Name of symbol. Must be in stable static storage
 426  *              that can be retained.
 427  *
 428  * exit:
 429  *      On success, the symbol has been added and TRUE is returned.
 430  *      Otherwise an error is reported and FALSE is returned.
 431  */
 432 Boolean
 433 ld_map_seg_size_symbol(Mapfile *mf, Sg_desc *sgp, Token eq_tok,
 434     const char *symname)
 435 {
 436         Sym             *sym;           /* New symbol pointer */
 437         Sym_desc        *sdp;           /* New symbol node pointer */
 438         Ifl_desc        *ifl;           /* Dummy input file structure */
 439         avl_index_t     where;
 440         Ofl_desc        *ofl = mf->mf_ofl;
 441 
 442         /*
 443          * We don't allow resetting the list of size symbols, so if the
 444          * operator is TK_EQUAL and the list is not empty, issue an error.
 445          *
 446          * If we want to lift this restriction, we would have to save the
 447          * size symbols and enter them from ld_map_post_process(). Doing that
 448          * well would require a significant overhead in saved error reporting
 449          * state, and interactions with the same symbols created by symbol
 450          * directives. As size symbols are of little practical use, and are
 451          * maintained primarily for backward compatibility with SysV, we have
 452          * decided not to do that, but to create the symbols as the mapfiles
 453          * are processed, and to disallow later attempts to remove them.
 454          */
 455         if ((eq_tok == TK_EQUAL) && (aplist_nitems(sgp->sg_sizesym) > 0)) {
 456                 mf_fatal(mf, MSG_INTL(MSG_MAP_SEGSIZE), sgp->sg_name);
 457                 return (FALSE);
 458         }
 459 
 460         /*
 461          * Make sure we have a pseudo file descriptor to associate to the
 462          * symbol.
 463          */
 464         if ((ifl = ld_map_ifl(mf)) == NULL)
 465                 return (FALSE);
 466 
 467         /*
 468          * Make sure the symbol doesn't already exist.  It is possible that the
 469          * symbol has been scoped or versioned, in which case it does exist
 470          * but we can freely update it here.
 471          */
 472         if ((sdp = ld_sym_find(symname, SYM_NOHASH, &where, ofl)) == NULL) {
 473                 Word hval;
 474 
 475                 if ((sym = libld_calloc(sizeof (Sym), 1)) == NULL)
 476                         return (FALSE);
 477                 sym->st_shndx = SHN_ABS;
 478                 sym->st_size = 0;
 479                 sym->st_info = ELF_ST_INFO(STB_GLOBAL, STT_OBJECT);
 480 
 481                 DBG_CALL(Dbg_map_size_new(ofl->ofl_lml, symname,
 482                     sgp->sg_name, mf->mf_lineno));
 483                 /* LINTED */
 484                 hval = (Word)elf_hash(symname);
 485                 if ((sdp = ld_sym_enter(symname, sym, hval, ifl, ofl, 0,
 486                     SHN_ABS, (FLG_SY_SPECSEC | FLG_SY_GLOBREF), &where)) ==
 487                     (Sym_desc *)S_ERROR)
 488                         return (FALSE);
 489                 sdp->sd_flags &= ~FLG_SY_CLEAN;
 490                 DBG_CALL(Dbg_map_symbol(ofl, sdp));
 491         } else {
 492                 sym = sdp->sd_sym;
 493 
 494                 if (sym->st_shndx == SHN_UNDEF) {
 495                         sdp->sd_shndx = sym->st_shndx = SHN_ABS;
 496                         sdp->sd_flags |= FLG_SY_SPECSEC;
 497                         sym->st_size = 0;
 498                         sym->st_info = ELF_ST_INFO(STB_GLOBAL, STT_OBJECT);
 499 
 500                         sdp->sd_flags &= ~FLG_SY_MAPREF;
 501 
 502                         DBG_CALL(Dbg_map_size_old(ofl, sdp,
 503                             sgp->sg_name, mf->mf_lineno));
 504                 } else {
 505                         mf_fatal(mf, MSG_INTL(MSG_MAP_SYMDEF1),
 506                             demangle(sdp->sd_name), sdp->sd_file->ifl_name,
 507                             MSG_INTL(MSG_MAP_DIFF_SYMMUL));
 508                         return (FALSE);
 509                 }
 510         }
 511 
 512         /*
 513          * Assign the symbol to the segment.
 514          */
 515         if (aplist_append(&sgp->sg_sizesym, sdp, AL_CNT_SG_SIZESYM) == NULL)
 516                 return (FALSE);
 517 
 518         return (TRUE);
 519 }
 520 
 521 /*
 522  * Allocate a zeroed segment descriptor.
 523  *
 524  * exit:
 525  *      Returns pointer to the descriptor on success, NULL on failure.
 526  *      The contents of the returned descriptor have been zeroed.
 527  *      The returned descriptor is not added to the segment list
 528  *      (ofl_segs). That is done using ld_map_seg_insert().
 529  */
 530 Sg_desc *
 531 ld_map_seg_alloc(const char *name, Word p_type, sg_flags_t sg_flags)
 532 {
 533         Sg_desc *sgp;
 534 
 535         if ((sgp = libld_calloc(sizeof (Sg_desc), 1)) == NULL)
 536                 return (NULL);
 537         sgp->sg_phdr.p_type = p_type;
 538         sgp->sg_name = name;
 539         sgp->sg_flags = sg_flags;
 540 
 541         return (sgp);
 542 }
 543 
 544 /*
 545  * Return the PT_SUNWSTACK segment descriptor from the ofl_segs list.
 546  * This segment is part of the default set and cannot be removed, so
 547  * this routine will always succeed.
 548  *
 549  * exit:
 550  *      The descriptor is located, a DBG_STATE_MOD_BEFORE debug
 551  *      message issued, the FLG_SG_DISABLED flag is cleared, and the
 552  *      descriptor pointer returned.
 553  */
 554 Sg_desc *
 555 ld_map_seg_stack(Mapfile *mf)
 556 {
 557         Ofl_desc        *ofl = mf->mf_ofl;
 558         Sg_desc         *sgp;
 559         Aliste          idx;
 560 
 561         /*
 562          * The stack is established by exec(), using the executable's program
 563          * headers, before any sharable objects are loaded. If there is a
 564          * PT_SUNWSTACK program header, exec() will act on it. As such, stack
 565          * program headers are normally only applicable to executables.
 566          *
 567          * However, ELF allows a sharable object with an interpreter to
 568          * be executed directly, and in this extremely rare case, the
 569          * PT_SUNWSTACK program header would have meaning. Rather than
 570          * second guess user intent, we simply create it on demand for any
 571          * dynamic object, trusting that the user has a good reason for it.
 572          */
 573         for (APLIST_TRAVERSE(ofl->ofl_segs, idx, sgp))
 574                 if (sgp->sg_phdr.p_type == PT_SUNWSTACK) {
 575                         DBG_CALL(Dbg_map_seg(mf->mf_ofl, DBG_STATE_MOD_BEFORE,
 576                             idx, sgp, mf->mf_lineno));
 577                         sgp->sg_flags &= ~FLG_SG_DISABLED;
 578                         return (sgp);
 579                 }
 580 
 581         /*NOTREACHED*/
 582         return (NULL);
 583 }
 584 
 585 /*
 586  * Finish the initialization of a new segment descriptor allocated by
 587  * ld_map_seg_alloc(), and enter it into the segment list.
 588  *
 589  * entry:
 590  *      mf - Mapfile descriptor
 591  *      seg_type - One of DBG_SEG_NEW or DBG_SEG_NEW_IMPLICIT
 592  *      ins_head - If TRUE, the new segment goes at the front of
 593  *              others of its type. If FALSE, it goes at the end.
 594  *      sgp - Segment descriptor to enter.
 595  *      where - Insertion point, initialized by a previous (failed) call to
 596  *              ld_seg_lookup(). Ignored if the segment has a NULL sg_name.
 597  *
 598  * exit:
 599  *      On success, returns SEG_INS_OK. A non-fatal error is indicated with
 600  *      a return value of SEG_INS_SKIP, in which case the descriptor is
 601  *      not entered, but the user is expected to discard it and continue
 602  *      running. On failure, returns SEG_INS_FAIL.
 603  *
 604  * note:
 605  *      This routine will modify the contents of the descriptor referenced
 606  *      by sgp_tmpl before allocating the new descriptor. The caller must
 607  *      not expect it to be unmodified.
 608  */
 609 ld_map_seg_ins_t
 610 ld_map_seg_insert(Mapfile *mf, dbg_state_t dbg_state, Sg_desc *sgp,
 611     avl_index_t where)
 612 {
 613         Ofl_desc        *ofl = mf->mf_ofl;
 614         Aliste          idx;
 615         Sg_desc         *sgp2;          /* temp segment descriptor pointer */
 616         int             ins_head;
 617         Xword           sg_ndx;
 618 
 619         /*
 620          * If specific fields have not been supplied via
 621          * map_equal(), make sure defaults are supplied.
 622          */
 623         if (((sgp->sg_flags & FLG_SG_P_TYPE) == 0) &&
 624             (sgp->sg_phdr.p_type == PT_NULL)) {
 625                 /*
 626                  * Default to a loadable segment.
 627                  */
 628                 sgp->sg_phdr.p_type = PT_LOAD;
 629                 sgp->sg_flags |= FLG_SG_P_TYPE;
 630         }
 631         if (sgp->sg_phdr.p_type == PT_LOAD) {
 632                 if ((sgp->sg_flags & FLG_SG_P_FLAGS) == 0) {
 633                         /*
 634                          * Default to read/write and execute.
 635                          */
 636                         sgp->sg_phdr.p_flags = PF_R + PF_W + PF_X;
 637                         sgp->sg_flags |= FLG_SG_P_FLAGS;
 638                 }
 639                 if ((sgp->sg_flags & FLG_SG_P_ALIGN) == 0) {
 640                         /*
 641                          * Default to segment alignment
 642                          */
 643                         sgp->sg_phdr.p_align = ld_targ.t_m.m_segm_align;
 644                         sgp->sg_flags |= FLG_SG_P_ALIGN;
 645                 }
 646         }
 647 
 648         /*
 649          * Determine where the new item should be inserted in
 650          * the segment descriptor list.
 651          */
 652         switch (sgp->sg_phdr.p_type) {
 653         case PT_LOAD:
 654                 if (sgp->sg_flags & FLG_SG_EMPTY)
 655                         sgp->sg_id = SGID_TEXT_EMPTY;
 656                 else
 657                         sgp->sg_id = SGID_TEXT;
 658                 break;
 659         case PT_NULL:
 660                 if (sgp->sg_flags & FLG_SG_EMPTY)
 661                         sgp->sg_id = SGID_NULL_EMPTY;
 662                 else
 663                         sgp->sg_id = SGID_NULL;
 664                 break;
 665         case PT_NOTE:
 666                 sgp->sg_id = SGID_NOTE;
 667                 break;
 668         default:
 669                 mf_fatal(mf, MSG_INTL(MSG_MAP_UNKSEGTYP),
 670                     EC_WORD(sgp->sg_phdr.p_type));
 671                 return (SEG_INS_FAIL);
 672         }
 673 
 674         /*
 675          * Add the descriptor to the segment list. In the v1 syntax,
 676          * new sections are added at the head of their type, while in
 677          * the newer syntax, they go at the end of their type.
 678          */
 679         sg_ndx = 0;
 680         ins_head = (mf->mf_version == MFV_SYSV);
 681         for (APLIST_TRAVERSE(ofl->ofl_segs, idx, sgp2)) {
 682                 if (ins_head) { /* Insert before the others of its type */
 683                         if (sgp->sg_id > sgp2->sg_id) {
 684                                 sg_ndx++;
 685                                 continue;
 686                         }
 687                 } else {        /* Insert after the others of its type */
 688                         if (sgp->sg_id >= sgp2->sg_id) {
 689                                 sg_ndx++;
 690                                 continue;
 691                         }
 692                 }
 693                 break;
 694         }
 695         if (aplist_insert(&ofl->ofl_segs, sgp, AL_CNT_SEGMENTS, idx) == NULL)
 696                 return (SEG_INS_FAIL);
 697         if (sgp->sg_name != NULL)
 698                 avl_insert(&ofl->ofl_segs_avl, sgp, where);
 699 
 700         DBG_CALL(Dbg_map_seg(ofl, dbg_state, sg_ndx, sgp, mf->mf_lineno));
 701         return (SEG_INS_OK);
 702 }
 703 
 704 /*
 705  * Add an entrance criteria record for the specified segment
 706  *
 707  * entry:
 708  *      mf - Mapfile descriptor
 709  *      sgp - Segment for which a new entrance criteria record is needed
 710  *      name - NULL, or name by which the entrance criteria can be referenced.
 711  *
 712  * exit:
 713  *      On success, a pointer to the new entrace criteria record is
 714  *      returned, the contents of which have been zeroed. On failure,
 715  *      NULL is returned.
 716  */
 717 Ent_desc *
 718 ld_map_seg_ent_add(Mapfile *mf, Sg_desc *sgp, const char *name)
 719 {
 720         Ent_desc        *enp;
 721         avl_index_t     where;
 722         Ofl_desc        *ofl = mf->mf_ofl;
 723 
 724         if ((name != NULL) &&
 725             (ld_ent_lookup(mf->mf_ofl, name, &where) != NULL)) {
 726                 mf_fatal(mf, MSG_INTL(MSG_MAP_DUPNAMENT), name);
 727                 return (NULL);
 728         }
 729 
 730         /* Allocate and initialize the entrace criteria descriptor */
 731         if ((enp = libld_calloc(1, sizeof (*enp))) == NULL)
 732                 return (NULL);
 733         enp->ec_name = name;
 734         enp->ec_segment = sgp;        /* Tie criteria to segment */
 735 
 736 
 737         /*
 738          * Insert into the APlist. The mf_ec_insndx field for each mapfile
 739          * starts at 0, and is incremented with each insertion. This means
 740          * that the entrance criteria for each mapfile go to the head of
 741          * the list, but that within a single mapfile, they are inserted in
 742          * the order they are seen.
 743          */
 744         if (aplist_insert(&ofl->ofl_ents, enp, AL_CNT_OFL_ENTRANCE,
 745             mf->mf_ec_insndx) == NULL)
 746                 return (NULL);
 747         mf->mf_ec_insndx++;
 748 
 749         /*
 750          * If the entrance criteria is named insert it into the AVL tree
 751          * as well. This provides O(logN) lookups by name.
 752          */
 753         if (name != NULL)
 754                 avl_insert(&ofl->ofl_ents_avl, enp, where);
 755 
 756         return (enp);
 757 }
 758 
 759 Boolean
 760 ld_map_seg_ent_files(Mapfile *mf, Ent_desc *enp, Word ecf_type, const char *str)
 761 {
 762         Ent_desc_file   edf;
 763 
 764         /*
 765          * The v1 sysv syntax can let an empty string get in, consisting of
 766          * just a '*' where the '*' is interpreted as 'basename'.
 767          */
 768         if (str[0] == '\0') {
 769                 mf_fatal0(mf, MSG_INTL(MSG_MAP_MALFORM));
 770                 return (FALSE);
 771         }
 772 
 773         /* Basename or objname string must not contain a path separator (/) */
 774         if ((ecf_type != TYP_ECF_PATH) && (strchr(str, '/') != NULL)) {
 775                 const char *msg = (ecf_type == TYP_ECF_BASENAME) ?
 776                     MSG_INTL(MSG_MAP_BADBNAME) : MSG_INTL(MSG_MAP_BADONAME);
 777 
 778                 mf_fatal(mf, msg, str);
 779                 return (FALSE);
 780         }
 781 
 782         edf.edf_flags = ecf_type;
 783         edf.edf_name = str;
 784         edf.edf_name_len = strlen(edf.edf_name);
 785 
 786         /* Does it have an archive member suffix? */
 787         if ((edf.edf_name[edf.edf_name_len - 1] == ')') &&
 788             (strrchr(edf.edf_name, '(') != NULL))
 789                 edf.edf_flags |= FLG_ECF_ARMEMBER;
 790 
 791         if (alist_append(&enp->ec_files, &edf, sizeof (edf),
 792             AL_CNT_EC_FILES) == NULL)
 793                 return (FALSE);
 794 
 795         /*
 796          * Note that an entrance criteria requiring file name matching exists
 797          * in the system. This is used by ld_place_path_info_init() to
 798          * skip Place_pathinfo initialization in cases where there are
 799          * no entrance criteria that will use the results.
 800          */
 801         mf->mf_ofl->ofl_flags |= FLG_OF_EC_FILES;
 802 
 803         return (TRUE);
 804 }
 805 
 806 /*
 807  * Prepare an ld_map_ver_t structure for a new mapfile defined version.
 808  *
 809  * exit:
 810  *      Returns TRUE for success, FALSE for failure.
 811  */
 812 Boolean
 813 ld_map_sym_ver_init(Mapfile *mf, char *name, ld_map_ver_t *mv)
 814 {
 815         Word            hash;
 816         Ofl_desc        *ofl = mf->mf_ofl;
 817 
 818         mv->mv_name = name;
 819         mv->mv_scope = FLG_SCOPE_DFLT;
 820         mv->mv_errcnt = 0;
 821 
 822         /*
 823          * If we're generating segments within the image then any symbol
 824          * reductions will be processed (ie. applied to relocations and symbol
 825          * table entries).  Otherwise (when creating a relocatable object) any
 826          * versioning information is simply recorded for use in a later
 827          * (segment generating) link-edit.
 828          */
 829         if (ofl->ofl_flags & FLG_OF_RELOBJ)
 830                 ofl->ofl_flags |= FLG_OF_VERDEF;
 831 
 832         /*
 833          * If no version descriptors have yet been set up, initialize a base
 834          * version to represent the output file itself.  This `base' version
 835          * catches any internally generated symbols (_end, _etext, etc.) and
 836          * serves to initialize the output version descriptor count.
 837          */
 838         if (ofl->ofl_vercnt == 0) {
 839                 if (ld_vers_base(ofl) == (Ver_desc *)S_ERROR)
 840                         return (FALSE);
 841         }
 842 
 843         /*
 844          * If this definition has an associated version name then generate a
 845          * new version descriptor and an associated version symbol index table.
 846          */
 847         if (name) {
 848                 ofl->ofl_flags |= FLG_OF_VERDEF;
 849 
 850                 /*
 851                  * Traverse the present version descriptor list to see if there
 852                  * is already one of the same name, otherwise create a new one.
 853                  */
 854                 /* LINTED */
 855                 hash = (Word)elf_hash(name);
 856                 if (((mv->mv_vdp = ld_vers_find(name, hash,
 857                     ofl->ofl_verdesc)) == NULL) &&
 858                     ((mv->mv_vdp = ld_vers_desc(name, hash,
 859                     &ofl->ofl_verdesc)) == (Ver_desc *)S_ERROR))
 860                         return (FALSE);
 861 
 862                 /*
 863                  * Initialize any new version with an index, the file from
 864                  * which it was first referenced, and a WEAK flag (indicates
 865                  * that there are no symbols assigned to it yet).
 866                  */
 867                 if (mv->mv_vdp->vd_ndx == 0) {
 868                         /* LINTED */
 869                         mv->mv_vdp->vd_ndx = (Half)++ofl->ofl_vercnt;
 870                         mv->mv_vdp->vd_file = ld_map_ifl(mf);
 871                         mv->mv_vdp->vd_flags = VER_FLG_WEAK;
 872                 }
 873         } else {
 874                 /*
 875                  * If a version definition hasn't been specified assign any
 876                  * symbols to the base version.
 877                  */
 878                 mv->mv_vdp = (Ver_desc *)ofl->ofl_verdesc->apl_data[0];
 879         }
 880 
 881         return (TRUE);
 882 }
 883 
 884 /*
 885  * Change the current scope for the given version.
 886  *
 887  * entry:
 888  *      mf - Mapfile descriptor
 889  *      scope_name - Name for new scope
 890  *      mv - Information related to version being defined
 891  *
 892  * exit:
 893  *      On success, mv is updated to change the current scope.
 894  *      On failure, mv->errcnt is incremented, and mv is otherwise unaltered.
 895  */
 896 void
 897 ld_map_sym_scope(Mapfile *mf, const char *scope_name, ld_map_ver_t *mv)
 898 {
 899         typedef struct {
 900                 const char      *name;          /* scope keyword string */
 901                 ld_map_scope_t  type;           /* Resulting type */
 902                 ofl_flag_t      ofl_flags;      /* 0, or ofl flags to add */
 903         } scope_t;
 904 
 905         /*
 906          * Valid symbol scope keywords
 907          *
 908          * All symbols added by a mapfile are actually global entries, and
 909          * are assigned the scope that is presently in effect.
 910          *
 911          * If a protected/symbolic scope is detected, remember this. If
 912          * a protected/symbolic scope is the only scope defined in this
 913          * (or any other mapfiles), then the mode -Bsymbolic is established.
 914          */
 915         static scope_t scope_list[] = {
 916                 { MSG_ORIG(MSG_MAPKW_DEFAULT), FLG_SCOPE_DFLT, FLG_OF_MAPGLOB },
 917                 { MSG_ORIG(MSG_MAPKW_ELIMINATE), FLG_SCOPE_ELIM, 0 },
 918                 { MSG_ORIG(MSG_MAPKW_EXPORTED), FLG_SCOPE_EXPT, 0 },
 919                 { MSG_ORIG(MSG_MAPKW_HIDDEN), FLG_SCOPE_HIDD, 0 },
 920                 { MSG_ORIG(MSG_MAPKW_GLOBAL), FLG_SCOPE_DFLT, FLG_OF_MAPGLOB },
 921                 { MSG_ORIG(MSG_MAPKW_LOCAL), FLG_SCOPE_HIDD, 0 },
 922                 { MSG_ORIG(MSG_MAPKW_PROTECTED),
 923                     FLG_SCOPE_PROT, FLG_OF_MAPSYMB },
 924                 { MSG_ORIG(MSG_MAPKW_SINGLETON),
 925                     FLG_SCOPE_SNGL, FLG_OF_MAPGLOB },
 926                 { MSG_ORIG(MSG_MAPKW_SYMBOLIC),
 927                     FLG_SCOPE_PROT, FLG_OF_MAPSYMB },
 928 
 929                 /* List must be null terminated */
 930                 { 0 }
 931         };
 932 
 933         /*
 934          * Size of buffer needed to format the names in scope_list[]. Must
 935          * be kept in sync with scope_list.
 936          */
 937         static size_t scope_list_bufsize =
 938             KW_NAME_SIZE(MSG_MAPKW_DEFAULT) +
 939             KW_NAME_SIZE(MSG_MAPKW_ELIMINATE) +
 940             KW_NAME_SIZE(MSG_MAPKW_EXPORTED) +
 941             KW_NAME_SIZE(MSG_MAPKW_HIDDEN) +
 942             KW_NAME_SIZE(MSG_MAPKW_GLOBAL) +
 943             KW_NAME_SIZE(MSG_MAPKW_LOCAL) +
 944             KW_NAME_SIZE(MSG_MAPKW_PROTECTED) +
 945             KW_NAME_SIZE(MSG_MAPKW_SINGLETON) +
 946             KW_NAME_SIZE(MSG_MAPKW_SYMBOLIC);
 947 
 948         scope_t *scope;
 949 
 950         scope = ld_map_kwfind(scope_name, scope_list,
 951             SGSOFFSETOF(scope_t, name), sizeof (scope_list[0]));
 952         if (scope == NULL) {
 953                 char buf[VLA_SIZE(scope_list_bufsize)];
 954 
 955                 mf_fatal(mf, MSG_INTL(MSG_MAP_EXP_SYMSCOPE),
 956                     ld_map_kwnames(scope_list, SGSOFFSETOF(scope_t, name),
 957                     sizeof (scope[0]), buf, scope_list_bufsize), scope_name);
 958                 mv->mv_errcnt++;
 959                 return;
 960         }
 961 
 962         mv->mv_scope = scope->type;
 963         mf->mf_ofl->ofl_flags |= scope->ofl_flags;
 964 }
 965 
 966 /*
 967  * Process the special auto-reduction directive ('*'). It can be specified
 968  * in hidden/local, and eliminate scope. This directive indicates that all
 969  * symbols processed that are not explicitly defined to be global are to be
 970  * reduced to hidden/local scope in, or eliminated from, the output image.
 971  *
 972  * An auto-reduction directive also implies that a version definition must
 973  * be created, as the user has effectively defined an interface.
 974  */
 975 void
 976 ld_map_sym_autoreduce(Mapfile *mf, ld_map_ver_t *mv)
 977 {
 978         switch (mv->mv_scope) {
 979         case FLG_SCOPE_HIDD:
 980                 mf->mf_ofl->ofl_flags |= (FLG_OF_VERDEF | FLG_OF_AUTOLCL);
 981                 break;
 982         case FLG_SCOPE_ELIM:
 983                 mf->mf_ofl->ofl_flags |= (FLG_OF_VERDEF | FLG_OF_AUTOELM);
 984                 break;
 985         default:
 986                 /*
 987                  * Auto reduction has been applied to a scope that doesn't
 988                  * support it. This should be a fatal error, but we limit
 989                  * it to a warning for version 1 mapfiles. For years, we
 990                  * quietly ignored this case, so there may be mapfiles in
 991                  * production use that we do not wish to break.
 992                  */
 993                 if (mf->mf_version == 1) {
 994                         mf_warn0(mf, MSG_INTL(MSG_MAP_BADAUTORED));
 995                 } else {
 996                         mf_fatal0(mf, MSG_INTL(MSG_MAP_BADAUTORED));
 997                         mv->mv_errcnt++;
 998                 }
 999         }
1000 }
1001 
1002 /*
1003  * Add a standard or auxiliary filter to the given symbol
1004  *
1005  * entry:
1006  *      mf - Mapfile descriptor
1007  *      mv - Information related to version being defined
1008  *      ms - Information related to symbol being defined
1009  *      dft_flag - One of FLG_SY_STDFLTR or FLG_SY_AUXFLTR,
1010  *              specifying the type of filter.
1011  *      filtee - String giving filtee to be added
1012  *
1013  * exit:
1014  *      On success, the filtee is added. On failure, mv->errcnt is
1015  *      incremented, and mv/ms are otherwise unaltered.
1016  */
1017 void
1018 ld_map_sym_filtee(Mapfile *mf, ld_map_ver_t *mv, ld_map_sym_t *ms,
1019     Word dft_flag, const char *filtee)
1020 {
1021         /*
1022          * A given symbol can only be tied to a single filter, be it
1023          * a standard filter, or auxiliary.
1024          */
1025         if (ms->ms_filtee) {
1026                 mf_fatal0(mf, MSG_INTL(MSG_MAP_MULTFILTEE));
1027                 mv->mv_errcnt++;
1028                 return;
1029         }
1030 
1031         /* Symbol filtering is only for sharable objects */
1032         if (!(mf->mf_ofl->ofl_flags & FLG_OF_SHAROBJ)) {
1033                 mf_fatal0(mf, MSG_INTL(MSG_MAP_FLTR_ONLYAVL));
1034                 mv->mv_errcnt++;
1035                 return;
1036         }
1037 
1038         ms->ms_filtee = filtee;
1039         ms->ms_dft_flag = dft_flag;
1040         ms->ms_sdflags |= dft_flag;
1041         mf->mf_ofl->ofl_flags |= FLG_OF_SYMINFO;
1042 }
1043 
1044 /*
1045  * Enter a mapfile defined symbol into the given version
1046  *
1047  * entry:
1048  *      mf - Mapfile descriptor
1049  *      ms - Information related to symbol being added to version
1050  *
1051  * exit:
1052  *      On success, returns TRUE. On failure that requires an immediate
1053  *      halt, returns FALSE.
1054  *
1055  *      On failure that requires eventual halt, but for which it would
1056  *      be OK to continue parsing in hopes of flushing out additional
1057  *      problems, increments mv->mv_errcnt, and returns TRUE.
1058  */
1059 Boolean
1060 ld_map_sym_enter(Mapfile *mf, ld_map_ver_t *mv, ld_map_sym_t *ms)
1061 {
1062         Ofl_desc        *ofl = mf->mf_ofl;
1063         Word            hash;
1064         avl_index_t     where;
1065         Sym             *sym;
1066         Sym_desc        *sdp;
1067         const char      *conflict;
1068 
1069         /*
1070          * Add the new symbol.  It should be noted that all
1071          * symbols added by the mapfile start out with global
1072          * scope, thus they will fall through the normal symbol
1073          * resolution process.  Symbols defined as locals will
1074          * be reduced in scope after all input file processing.
1075          */
1076         /* LINTED */
1077         hash = (Word)elf_hash(ms->ms_name);
1078         DBG_CALL(Dbg_map_version(ofl->ofl_lml, mv->mv_name, ms->ms_name,
1079             mv->mv_scope));
1080 
1081         /*
1082          * Make sure that any parent or external declarations fall back to
1083          * references.
1084          */
1085         if (ms->ms_sdflags & (FLG_SY_PARENT | FLG_SY_EXTERN)) {
1086                 /*
1087                  * Turn it into a reference by setting the section index
1088                  * to UNDEF.
1089                  */
1090                 ms->ms_shndx = SHN_UNDEF;
1091 
1092                 /*
1093                  * It is wrong to specify size or value for an external symbol.
1094                  */
1095                 if (ms->ms_value_set || (ms->ms_size != 0)) {
1096                         mf_fatal0(mf, MSG_INTL(MSG_MAP_NOEXVLSZ));
1097                         mv->mv_errcnt++;
1098                         return (TRUE);
1099                 }
1100         }
1101 
1102         if ((sdp = ld_sym_find(ms->ms_name, hash, &where, ofl)) == NULL) {
1103                 if ((sym = libld_calloc(sizeof (Sym), 1)) == NULL)
1104                         return (FALSE);
1105 
1106                 sym->st_shndx = (Half)ms->ms_shndx;
1107                 sym->st_value = ms->ms_value;
1108                 sym->st_size = ms->ms_size;
1109                 sym->st_info = ELF_ST_INFO(STB_GLOBAL, ms->ms_type);
1110 
1111                 if ((sdp = ld_sym_enter(ms->ms_name, sym, hash,
1112                     ld_map_ifl(mf), ofl, 0, ms->ms_shndx, ms->ms_sdflags,
1113                     &where)) == (Sym_desc *)S_ERROR)
1114                         return (FALSE);
1115 
1116                 sdp->sd_flags &= ~FLG_SY_CLEAN;
1117 
1118                 /*
1119                  * Identify any references.  FLG_SY_MAPREF is
1120                  * turned off once a relocatable object with
1121                  * the same symbol is found, thus the existence
1122                  * of FLG_SY_MAPREF at symbol validation is
1123                  * used to flag undefined/misspelled entries.
1124                  */
1125                 if (sym->st_shndx == SHN_UNDEF)
1126                         sdp->sd_flags |= (FLG_SY_MAPREF | FLG_SY_GLOBREF);
1127 
1128         } else {
1129                 conflict = NULL;
1130                 sym = sdp->sd_sym;
1131 
1132                 /*
1133                  * If this symbol already exists, make sure this
1134                  * definition doesn't conflict with the former.
1135                  * Provided it doesn't, multiple definitions
1136                  * from different mapfiles can augment each
1137                  * other.
1138                  */
1139                 if (sym->st_value) {
1140                         if (ms->ms_value && (sym->st_value != ms->ms_value))
1141                                 conflict = MSG_INTL(MSG_MAP_DIFF_SYMVAL);
1142                 } else {
1143                         sym->st_value = ms->ms_value;
1144                 }
1145                 if (sym->st_size) {
1146                         if (ms->ms_size && (sym->st_size != ms->ms_size))
1147                                 conflict = MSG_INTL(MSG_MAP_DIFF_SYMSZ);
1148                 } else {
1149                         sym->st_size = ms->ms_size;
1150                 }
1151                 if (ELF_ST_TYPE(sym->st_info) != STT_NOTYPE) {
1152                         if ((ms->ms_type != STT_NOTYPE) &&
1153                             (ELF_ST_TYPE(sym->st_info) != ms->ms_type))
1154                                 conflict = MSG_INTL(MSG_MAP_DIFF_SYMTYP);
1155                 } else {
1156                         sym->st_info = ELF_ST_INFO(STB_GLOBAL, ms->ms_type);
1157                 }
1158                 if (sym->st_shndx != SHN_UNDEF) {
1159                         if ((ms->ms_shndx != SHN_UNDEF) &&
1160                             (sym->st_shndx != ms->ms_shndx))
1161                                 conflict = MSG_INTL(MSG_MAP_DIFF_SYMNDX);
1162                 } else {
1163                         sym->st_shndx = sdp->sd_shndx = ms->ms_shndx;
1164                 }
1165 
1166                 if ((sdp->sd_flags & MSK_SY_GLOBAL) &&
1167                     (sdp->sd_aux->sa_overndx != VER_NDX_GLOBAL) &&
1168                     (mv->mv_vdp->vd_ndx != VER_NDX_GLOBAL) &&
1169                     (sdp->sd_aux->sa_overndx != mv->mv_vdp->vd_ndx)) {
1170                         conflict = MSG_INTL(MSG_MAP_DIFF_SYMVER);
1171                 }
1172 
1173                 if (conflict) {
1174                         mf_fatal(mf, MSG_INTL(MSG_MAP_SYMDEF1),
1175                             demangle(ms->ms_name),
1176                             sdp->sd_file->ifl_name, conflict);
1177                         mv->mv_errcnt++;
1178                         return (TRUE);
1179                 }
1180 
1181                 /*
1182                  * If this mapfile entry supplies a definition,
1183                  * indicate that the symbol is now used.
1184                  */
1185                 if (ms->ms_shndx != SHN_UNDEF)
1186                         sdp->sd_flags |= FLG_SY_MAPUSED;
1187         }
1188 
1189         /*
1190          * A symbol declaration that defines a size but no
1191          * value is processed as a request to create an
1192          * associated backing section.  The intent behind this
1193          * functionality is to provide OBJT definitions within
1194          * filters that are not ABS.  ABS symbols don't allow
1195          * copy-relocations to be established to filter OBJT
1196          * definitions.
1197          */
1198         if ((ms->ms_shndx == SHN_ABS) && ms->ms_size && !ms->ms_value_set) {
1199                 /* Create backing section if not there */
1200                 if (sdp->sd_isc == NULL) {
1201                         Is_desc *isp;
1202 
1203                         if (ms->ms_type == STT_OBJECT) {
1204                                 if ((isp = ld_make_data(ofl, ms->ms_size)) ==
1205                                     (Is_desc *)S_ERROR)
1206                                         return (FALSE);
1207                         } else {
1208                                 if ((isp = ld_make_text(ofl, ms->ms_size)) ==
1209                                     (Is_desc *)S_ERROR)
1210                                         return (FALSE);
1211                         }
1212 
1213                         sdp->sd_isc = isp;
1214                         isp->is_file = ld_map_ifl(mf);
1215                 }
1216 
1217                 /*
1218                  * Now that backing storage has been created,
1219                  * associate the symbol descriptor.  Remove the
1220                  * symbols special section tag so that it will
1221                  * be assigned the correct section index as part
1222                  * of update symbol processing.
1223                  */
1224                 sdp->sd_flags &= ~FLG_SY_SPECSEC;
1225                 ms->ms_sdflags &= ~FLG_SY_SPECSEC;
1226         }
1227 
1228         /*
1229          * Indicate the new symbols scope.  Although the
1230          * symbols st_other field will eventually be updated as
1231          * part of writing out the final symbol, update the
1232          * st_other field here to trigger better diagnostics
1233          * during symbol validation (for example, undefined
1234          * references that are defined symbolic in a mapfile).
1235          */
1236         if (mv->mv_scope == FLG_SCOPE_HIDD) {
1237                 /*
1238                  * This symbol needs to be reduced to local.
1239                  */
1240                 if (ofl->ofl_flags & FLG_OF_REDLSYM) {
1241                         sdp->sd_flags |= (FLG_SY_HIDDEN | FLG_SY_ELIM);
1242                         sdp->sd_sym->st_other = STV_ELIMINATE;
1243                 } else {
1244                         sdp->sd_flags |= FLG_SY_HIDDEN;
1245                         sdp->sd_sym->st_other = STV_HIDDEN;
1246                 }
1247         } else if (mv->mv_scope == FLG_SCOPE_ELIM) {
1248                 /*
1249                  * This symbol needs to be eliminated.  Note,
1250                  * the symbol is also tagged as local to trigger
1251                  * any necessary relocation processing prior
1252                  * to the symbol being eliminated.
1253                  */
1254                 sdp->sd_flags |= (FLG_SY_HIDDEN | FLG_SY_ELIM);
1255                 sdp->sd_sym->st_other = STV_ELIMINATE;
1256 
1257         } else {
1258                 /*
1259                  * This symbol is explicitly defined to remain
1260                  * global.
1261                  */
1262                 sdp->sd_flags |= ms->ms_sdflags;
1263 
1264                 /*
1265                  * Qualify any global scope.
1266                  */
1267                 if (mv->mv_scope == FLG_SCOPE_SNGL) {
1268                         sdp->sd_flags |= (FLG_SY_SINGLE | FLG_SY_NDIR);
1269                         sdp->sd_sym->st_other = STV_SINGLETON;
1270                 } else if (mv->mv_scope == FLG_SCOPE_PROT) {
1271                         sdp->sd_flags |= FLG_SY_PROTECT;
1272                         sdp->sd_sym->st_other = STV_PROTECTED;
1273                 } else if (mv->mv_scope == FLG_SCOPE_EXPT) {
1274                         sdp->sd_flags |= FLG_SY_EXPORT;
1275                         sdp->sd_sym->st_other = STV_EXPORTED;
1276                 } else
1277                         sdp->sd_flags |= FLG_SY_DEFAULT;
1278 
1279                 /*
1280                  * Record the present version index for later
1281                  * potential versioning.
1282                  */
1283                 if ((sdp->sd_aux->sa_overndx == 0) ||
1284                     (sdp->sd_aux->sa_overndx == VER_NDX_GLOBAL))
1285                         sdp->sd_aux->sa_overndx = mv->mv_vdp->vd_ndx;
1286                 mv->mv_vdp->vd_flags |= FLG_VER_REFER;
1287         }
1288 
1289         conflict = NULL;
1290 
1291         /*
1292          * Carry out some validity checks to ensure incompatible
1293          * symbol characteristics have not been defined.
1294          * These checks are carried out after symbols are added
1295          * or resolved, to catch single instance, and
1296          * multi-instance definition inconsistencies.
1297          */
1298         if ((sdp->sd_flags & (FLG_SY_HIDDEN | FLG_SY_ELIM)) &&
1299             ((mv->mv_scope != FLG_SCOPE_HIDD) &&
1300             (mv->mv_scope != FLG_SCOPE_ELIM))) {
1301                 conflict = MSG_INTL(MSG_MAP_DIFF_SYMLCL);
1302 
1303         } else if ((sdp->sd_flags &
1304             (FLG_SY_SINGLE | FLG_SY_EXPORT)) &&
1305             ((mv->mv_scope != FLG_SCOPE_DFLT) &&
1306             (mv->mv_scope != FLG_SCOPE_EXPT) &&
1307             (mv->mv_scope != FLG_SCOPE_SNGL))) {
1308                 conflict = MSG_INTL(MSG_MAP_DIFF_SYMGLOB);
1309 
1310         } else if ((sdp->sd_flags & FLG_SY_PROTECT) &&
1311             ((mv->mv_scope != FLG_SCOPE_DFLT) &&
1312             (mv->mv_scope != FLG_SCOPE_PROT))) {
1313                 conflict = MSG_INTL(MSG_MAP_DIFF_SYMPROT);
1314 
1315         } else if ((sdp->sd_flags & FLG_SY_NDIR) &&
1316             (mv->mv_scope == FLG_SCOPE_PROT)) {
1317                 conflict = MSG_INTL(MSG_MAP_DIFF_PROTNDIR);
1318 
1319         } else if ((sdp->sd_flags & FLG_SY_DIR) &&
1320             (mv->mv_scope == FLG_SCOPE_SNGL)) {
1321                 conflict = MSG_INTL(MSG_MAP_DIFF_SNGLDIR);
1322         }
1323 
1324         if (conflict) {
1325                 /*
1326                  * Select the conflict message from either a
1327                  * single instance or multi-instance definition.
1328                  */
1329                 if (sdp->sd_file->ifl_name == mf->mf_name) {
1330                         mf_fatal(mf, MSG_INTL(MSG_MAP_SYMDEF2),
1331                             demangle(ms->ms_name), conflict);
1332                 } else {
1333                         mf_fatal(mf, MSG_INTL(MSG_MAP_SYMDEF1),
1334                             demangle(ms->ms_name),
1335                             sdp->sd_file->ifl_name, conflict);
1336                 }
1337                 mv->mv_errcnt++;
1338                 return (TRUE);
1339         }
1340 
1341         /*
1342          * Indicate that this symbol has been explicitly
1343          * contributed from a mapfile.
1344          */
1345         sdp->sd_flags |= (FLG_SY_MAPFILE | FLG_SY_EXPDEF);
1346 
1347         /*
1348          * If we've encountered a symbol definition simulate
1349          * that an input file has been processed - this allows
1350          * things like filters to be created purely from a
1351          * mapfile.
1352          */
1353         if (ms->ms_type != STT_NOTYPE)
1354                 ofl->ofl_objscnt++;
1355         DBG_CALL(Dbg_map_symbol(ofl, sdp));
1356 
1357         /*
1358          * If this symbol has an associated filtee, record the
1359          * filtee string and associate the string index with the
1360          * symbol.  This is used later to associate the syminfo
1361          * information with the necessary .dynamic entry.
1362          */
1363         if (ms->ms_filtee) {
1364                 Dfltr_desc *    dftp;
1365                 Sfltr_desc      sft;
1366                 Aliste          idx, _idx, nitems;
1367 
1368                 /*
1369                  * Make sure we don't duplicate any filtee
1370                  * strings, and create a new descriptor if
1371                  * necessary.
1372                  */
1373                 idx = nitems = alist_nitems(ofl->ofl_dtsfltrs);
1374                 for (ALIST_TRAVERSE(ofl->ofl_dtsfltrs, _idx, dftp)) {
1375                         if ((ms->ms_dft_flag != dftp->dft_flag) ||
1376                             (strcmp(dftp->dft_str, ms->ms_filtee)))
1377                                 continue;
1378                         idx = _idx;
1379                         break;
1380                 }
1381                 if (idx == nitems) {
1382                         Dfltr_desc      dft;
1383 
1384                         dft.dft_str = ms->ms_filtee;
1385                         dft.dft_flag = ms->ms_dft_flag;
1386                         dft.dft_ndx = 0;
1387 
1388                         /*
1389                          * The following append puts the new
1390                          * item at the offset contained in
1391                          * idx, because we know idx contains
1392                          * the index of the next available slot.
1393                          */
1394                         if (alist_append(&ofl->ofl_dtsfltrs, &dft,
1395                             sizeof (Dfltr_desc), AL_CNT_OFL_DTSFLTRS) == NULL)
1396                                 return (FALSE);
1397                 }
1398 
1399                 /*
1400                  * Create a new filter descriptor for this
1401                  * symbol.
1402                  */
1403                 sft.sft_sdp = sdp;
1404                 sft.sft_idx = idx;
1405 
1406                 if (alist_append(&ofl->ofl_symfltrs, &sft, sizeof (Sfltr_desc),
1407                     AL_CNT_OFL_SYMFLTRS) == NULL)
1408                         return (FALSE);
1409         }
1410 
1411         return (TRUE);
1412 }
1413 
1414 /*
1415  * In both the version 1 and version 2 syntaxes, a version definition
1416  * can have 0 or more inherited versions following the closing '}',
1417  * terminated by a ';'.
1418  *
1419  * Add the inherited names, and return when the terminator is seen.
1420  */
1421 Boolean
1422 ld_map_sym_ver_fini(Mapfile *mf, ld_map_ver_t *mv)
1423 {
1424         Token           tok;
1425         ld_map_tkval_t  tkv;            /* Value of token */
1426         Boolean         done = FALSE;
1427         Conv_inv_buf_t  inv_buf;
1428         const char      *name;
1429         Ver_desc        *vdp;
1430         Word            hash;
1431 
1432         /*
1433          * Read version names until we encounter the ';' terminator.
1434          */
1435         while (!done) {
1436                 switch (tok = ld_map_gettoken(mf, 0, &tkv)) {
1437                 case TK_ERROR:
1438                         return (FALSE);
1439 
1440                 case TK_STRING:
1441                         name = tkv.tkv_str;
1442 
1443                         /* The unnamed global scope can't inherit */
1444                         if (mv->mv_vdp->vd_ndx == VER_NDX_GLOBAL) {
1445                                 mf_fatal(mf, MSG_INTL(MSG_MAP_UNEXINHERIT),
1446                                     name);
1447                                 return (FALSE);
1448                         }
1449 
1450                         /*
1451                          * Generate a new version descriptor if it doesn't
1452                          * already exist.
1453                          */
1454                         /* LINTED */
1455                         hash = (Word)elf_hash(name);
1456                         vdp = ld_vers_find(name, hash, mf->mf_ofl->ofl_verdesc);
1457                         if ((vdp == NULL) && ((vdp = ld_vers_desc(name, hash,
1458                             &mf->mf_ofl->ofl_verdesc)) == (Ver_desc *)S_ERROR))
1459                                 return (FALSE);
1460 
1461                         /*
1462                          * Add the new version descriptor to the parent version
1463                          * descriptors reference list.  Indicate the version
1464                          * descriptors first reference (used for error diags
1465                          * if undefined version dependencies remain).
1466                          */
1467                         if (ld_vers_find(name, hash, mv->mv_vdp->vd_deps) ==
1468                             NULL)
1469                                 if (aplist_append(&mv->mv_vdp->vd_deps, vdp,
1470                                     AL_CNT_VERDESCS) == NULL)
1471                                         return (FALSE);
1472 
1473                         if (vdp->vd_ref == NULL)
1474                                 vdp->vd_ref = mv->mv_vdp;
1475                         break;
1476 
1477                 case TK_SEMICOLON:
1478                         done = TRUE;
1479                         break;
1480 
1481                 default:
1482                         mf_fatal(mf, MSG_INTL(MSG_MAP_EXP_SYMEND),
1483                             ld_map_tokenstr(tok, &tkv, &inv_buf));
1484                         return (FALSE);
1485                 }
1486         }
1487 
1488         return (TRUE);
1489 }