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