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 (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  27  */
  28 
  29 /*
  30  * Update the new output file image, perform virtual address, offset and
  31  * displacement calculations on the program headers and sections headers,
  32  * and generate any new output section information.
  33  */
  34 
  35 #define ELF_TARGET_AMD64
  36 
  37 #include        <stdio.h>
  38 #include        <string.h>
  39 #include        <unistd.h>
  40 #include        <debug.h>
  41 #include        "msg.h"
  42 #include        "_libld.h"
  43 
  44 /*
  45  * Comparison routine used by qsort() for sorting of the global symbol list
  46  * based off of the hashbuckets the symbol will eventually be deposited in.
  47  */
  48 static int
  49 sym_hash_compare(Sym_s_list * s1, Sym_s_list * s2)
  50 {
  51         return (s1->sl_hval - s2->sl_hval);
  52 }
  53 
  54 /*
  55  * Comparison routine used by qsort() for sorting of dyn[sym|tls]sort section
  56  * indices based on the address of the symbols they reference. The
  57  * use of the global dynsort_compare_syms variable is needed because
  58  * we need to examine the symbols the indices reference. It is safe, because
  59  * the linker is single threaded.
  60  */
  61 Sym *dynsort_compare_syms;
  62 
  63 static int
  64 dynsort_compare(const void *idx1, const void *idx2)
  65 {
  66         Sym *s1 = dynsort_compare_syms + *((const Word *) idx1);
  67         Sym *s2 = dynsort_compare_syms + *((const Word *) idx2);
  68 
  69         /*
  70          * Note: the logical computation for this is
  71          *      (st_value1 - st_value2)
  72          * However, that is only correct if the address type is smaller
  73          * than a pointer. Writing it this way makes it immune to the
  74          * class (32 or 64-bit) of the linker.
  75          */
  76         return ((s1->st_value < s2->st_value) ? -1 :
  77             (s1->st_value > s2->st_value));
  78 }
  79 
  80 /*
  81  * Scan the sorted symbols, and issue warnings if there are any duplicate
  82  * values in the list. We only do this if -zverbose is set, or we are
  83  * running with LD_DEBUG defined
  84  *
  85  * entry:
  86  *      ofl - Output file descriptor
  87  *      ldynsym - Pointer to start of .SUNW_ldynsym section that the
  88  *              sort section indexes reference.
  89  *      symsort - Pointer to start of .SUNW_dynsymsort or .SUNW_dyntlssort
  90  *              section.
  91  *      n - # of indices in symsort array
  92  *      secname - Name of the symsort section.
  93  *
  94  * exit:
  95  *      If the symsort section contains indexes to more than one
  96  *      symbol with the same address value, a warning is issued.
  97  */
  98 static void
  99 dynsort_dupwarn(Ofl_desc *ofl, Sym *ldynsym, const char *str,
 100     Word *symsort, Word n, const char *secname)
 101 {
 102         int zverbose = (ofl->ofl_flags & FLG_OF_VERBOSE) != 0;
 103         Word ndx, cmp_ndx;
 104         Addr addr, cmp_addr;
 105 
 106         /* Nothing to do if -zverbose or LD_DEBUG are not active */
 107         if (!(zverbose || DBG_ENABLED))
 108                 return;
 109 
 110         cmp_ndx = 0;
 111         cmp_addr = ldynsym[symsort[cmp_ndx]].st_value;
 112         for (ndx = 1; ndx < n; ndx++) {
 113                 addr = ldynsym[symsort[ndx]].st_value;
 114                 if (cmp_addr == addr) {
 115                         if (zverbose)
 116                                 ld_eprintf(ofl, ERR_WARNING,
 117                                     MSG_INTL(MSG_SYM_DUPSORTADDR), secname,
 118                                     str + ldynsym[symsort[cmp_ndx]].st_name,
 119                                     str + ldynsym[symsort[ndx]].st_name,
 120                                     EC_ADDR(addr));
 121                         DBG_CALL(Dbg_syms_dup_sort_addr(ofl->ofl_lml, secname,
 122                             str + ldynsym[symsort[cmp_ndx]].st_name,
 123                             str + ldynsym[symsort[ndx]].st_name,
 124                             EC_ADDR(addr)));
 125                 } else {        /* Not a dup. Move reference up */
 126                         cmp_ndx = ndx;
 127                         cmp_addr = addr;
 128                 }
 129         }
 130 }
 131 
 132 /*
 133  * Build and update any output symbol tables.  Here we work on all the symbol
 134  * tables at once to reduce the duplication of symbol and string manipulation.
 135  * Symbols and their associated strings are copied from the read-only input
 136  * file images to the output image and their values and index's updated in the
 137  * output image.
 138  */
 139 static Addr
 140 update_osym(Ofl_desc *ofl)
 141 {
 142         /*
 143          * There are several places in this function where we wish
 144          * to insert a symbol index to the combined .SUNW_ldynsym/.dynsym
 145          * symbol table into one of the two sort sections (.SUNW_dynsymsort
 146          * or .SUNW_dyntlssort), if that symbol has the right attributes.
 147          * This macro is used to generate the necessary code from a single
 148          * specification.
 149          *
 150          * entry:
 151          *      _sdp, _sym, _type - As per DYNSORT_COUNT. See _libld.h
 152          *      _sym_ndx - Index that _sym will have in the combined
 153          *              .SUNW_ldynsym/.dynsym symbol table.
 154          */
 155 #define ADD_TO_DYNSORT(_sdp, _sym, _type, _sym_ndx) \
 156         { \
 157                 Word *_dynsort_arr, *_dynsort_ndx; \
 158                 \
 159                 if (dynsymsort_symtype[_type]) { \
 160                         _dynsort_arr = dynsymsort; \
 161                         _dynsort_ndx = &dynsymsort_ndx; \
 162                 } else if (_type == STT_TLS) { \
 163                         _dynsort_arr = dyntlssort; \
 164                         _dynsort_ndx = &dyntlssort_ndx; \
 165                 } else { \
 166                         _dynsort_arr = NULL; \
 167                 } \
 168                 if ((_dynsort_arr != NULL) && DYNSORT_TEST_ATTR(_sdp, _sym)) \
 169                     _dynsort_arr[(*_dynsort_ndx)++] = _sym_ndx; \
 170         }
 171 
 172         Sym_desc        *sdp;
 173         Sym_avlnode     *sav;
 174         Sg_desc         *sgp, *tsgp = NULL, *dsgp = NULL, *esgp = NULL;
 175         Os_desc         *osp, *iosp = NULL, *fosp = NULL;
 176         Is_desc         *isc;
 177         Ifl_desc        *ifl;
 178         Word            bssndx, etext_ndx, edata_ndx = 0, end_ndx, start_ndx;
 179         Word            end_abs = 0, etext_abs = 0, edata_abs;
 180         Word            tlsbssndx = 0, parexpnndx;
 181 #if     defined(_ELF64)
 182         Word            lbssndx = 0;
 183         Addr            lbssaddr = 0;
 184 #endif
 185         Addr            bssaddr, etext = 0, edata = 0, end = 0, start = 0;
 186         Addr            tlsbssaddr = 0;
 187         Addr            parexpnbase, parexpnaddr;
 188         int             start_set = 0;
 189         Sym             _sym = {0}, *sym, *symtab = NULL;
 190         Sym             *dynsym = NULL, *ldynsym = NULL;
 191         Word            symtab_ndx = 0;         /* index into .symtab */
 192         Word            symtab_gbl_bndx;        /* .symtab ndx 1st global */
 193         Word            ldynsym_ndx = 0;        /* index into .SUNW_ldynsym */
 194         Word            dynsym_ndx = 0;         /* index into .dynsym */
 195         Word            scopesym_ndx = 0;       /* index into scoped symbols */
 196         Word            scopesym_bndx = 0;      /* .symtab ndx 1st scoped sym */
 197         Word            ldynscopesym_ndx = 0;   /* index to ldynsym scoped */
 198                                                 /*      symbols */
 199         Word            *dynsymsort = NULL;     /* SUNW_dynsymsort index */
 200                                                 /*      vector */
 201         Word            *dyntlssort = NULL;     /* SUNW_dyntlssort index */
 202                                                 /*      vector */
 203         Word            dynsymsort_ndx;         /* index dynsymsort array */
 204         Word            dyntlssort_ndx;         /* index dyntlssort array */
 205         Word            *symndx;                /* symbol index (for */
 206                                                 /*      relocation use) */
 207         Word            *symshndx = NULL;       /* .symtab_shndx table */
 208         Word            *dynshndx = NULL;       /* .dynsym_shndx table */
 209         Word            *ldynshndx = NULL;      /* .SUNW_ldynsym_shndx table */
 210         Word            ldynsym_cnt = NULL;     /* number of items in */
 211                                                 /*      .SUNW_ldynsym */
 212         Str_tbl         *shstrtab;
 213         Str_tbl         *strtab;
 214         Str_tbl         *dynstr;
 215         Word            *hashtab;       /* hash table pointer */
 216         Word            *hashbkt;       /* hash table bucket pointer */
 217         Word            *hashchain;     /* hash table chain pointer */
 218         Wk_desc         *wkp;
 219         Alist           *weak = NULL;
 220         ofl_flag_t      flags = ofl->ofl_flags;
 221         Versym          *versym;
 222         Gottable        *gottable;      /* used for display got debugging */
 223                                         /*      information */
 224         Syminfo         *syminfo;
 225         Sym_s_list      *sorted_syms;   /* table to hold sorted symbols */
 226         Word            ssndx;          /* global index into sorted_syms */
 227         Word            scndx;          /* scoped index into sorted_syms */
 228         size_t          stoff;          /* string offset */
 229         Aliste          idx1;
 230 
 231         /*
 232          * Initialize pointers to the symbol table entries and the symbol
 233          * table strings.  Skip the first symbol entry and the first string
 234          * table byte.  Note that if we are not generating any output symbol
 235          * tables we must still generate and update internal copies so
 236          * that the relocation phase has the correct information.
 237          */
 238         if (!(flags & FLG_OF_STRIP) || (flags & FLG_OF_RELOBJ) ||
 239             ((flags & FLG_OF_STATIC) && ofl->ofl_osversym)) {
 240                 symtab = (Sym *)ofl->ofl_ossymtab->os_outdata->d_buf;
 241                 symtab[symtab_ndx++] = _sym;
 242                 if (ofl->ofl_ossymshndx)
 243                         symshndx =
 244                             (Word *)ofl->ofl_ossymshndx->os_outdata->d_buf;
 245         }
 246         if (OFL_ALLOW_DYNSYM(ofl)) {
 247                 dynsym = (Sym *)ofl->ofl_osdynsym->os_outdata->d_buf;
 248                 dynsym[dynsym_ndx++] = _sym;
 249                 /*
 250                  * If we are also constructing a .SUNW_ldynsym section
 251                  * to contain local function symbols, then set it up too.
 252                  */
 253                 if (ofl->ofl_osldynsym) {
 254                         ldynsym = (Sym *)ofl->ofl_osldynsym->os_outdata->d_buf;
 255                         ldynsym[ldynsym_ndx++] = _sym;
 256                         ldynsym_cnt = 1 + ofl->ofl_dynlocscnt +
 257                             ofl->ofl_dynscopecnt;
 258 
 259                         /*
 260                          * If there is a SUNW_ldynsym, then there may also
 261                          * be a .SUNW_dynsymsort and/or .SUNW_dyntlssort
 262                          * sections, used to collect indices of function
 263                          * and data symbols sorted by address order.
 264                          */
 265                         if (ofl->ofl_osdynsymsort) { /* .SUNW_dynsymsort */
 266                                 dynsymsort = (Word *)
 267                                     ofl->ofl_osdynsymsort->os_outdata->d_buf;
 268                                 dynsymsort_ndx = 0;
 269                         }
 270                         if (ofl->ofl_osdyntlssort) { /* .SUNW_dyntlssort */
 271                                 dyntlssort = (Word *)
 272                                     ofl->ofl_osdyntlssort->os_outdata->d_buf;
 273                                 dyntlssort_ndx = 0;
 274                         }
 275                 }
 276 
 277                 /*
 278                  * Initialize the hash table.
 279                  */
 280                 hashtab = (Word *)(ofl->ofl_oshash->os_outdata->d_buf);
 281                 hashbkt = &hashtab[2];
 282                 hashchain = &hashtab[2 + ofl->ofl_hashbkts];
 283                 hashtab[0] = ofl->ofl_hashbkts;
 284                 hashtab[1] = DYNSYM_ALL_CNT(ofl);
 285                 if (ofl->ofl_osdynshndx)
 286                         dynshndx =
 287                             (Word *)ofl->ofl_osdynshndx->os_outdata->d_buf;
 288                 if (ofl->ofl_osldynshndx)
 289                         ldynshndx =
 290                             (Word *)ofl->ofl_osldynshndx->os_outdata->d_buf;
 291         }
 292 
 293         /*
 294          * symndx is the symbol index to be used for relocation processing.  It
 295          * points to the relevant symtab's (.dynsym or .symtab) symbol ndx.
 296          */
 297         if (dynsym)
 298                 symndx = &dynsym_ndx;
 299         else
 300                 symndx = &symtab_ndx;
 301 
 302         /*
 303          * If we have version definitions initialize the version symbol index
 304          * table.  There is one entry for each symbol which contains the symbols
 305          * version index.
 306          */
 307         if (!(flags & FLG_OF_NOVERSEC) &&
 308             (flags & (FLG_OF_VERNEED | FLG_OF_VERDEF))) {
 309                 versym = (Versym *)ofl->ofl_osversym->os_outdata->d_buf;
 310                 versym[0] = NULL;
 311         } else
 312                 versym = NULL;
 313 
 314         /*
 315          * If syminfo section exists be prepared to fill it in.
 316          */
 317         if (ofl->ofl_ossyminfo) {
 318                 syminfo = ofl->ofl_ossyminfo->os_outdata->d_buf;
 319                 syminfo[0].si_flags = SYMINFO_CURRENT;
 320         } else
 321                 syminfo = NULL;
 322 
 323         /*
 324          * Setup our string tables.
 325          */
 326         shstrtab = ofl->ofl_shdrsttab;
 327         strtab = ofl->ofl_strtab;
 328         dynstr = ofl->ofl_dynstrtab;
 329 
 330         DBG_CALL(Dbg_syms_sec_title(ofl->ofl_lml));
 331 
 332         /*
 333          * Put output file name to the first .symtab and .SUNW_ldynsym symbol.
 334          */
 335         if (symtab) {
 336                 (void) st_setstring(strtab, ofl->ofl_name, &stoff);
 337                 sym = &symtab[symtab_ndx++];
 338                 /* LINTED */
 339                 sym->st_name = stoff;
 340                 sym->st_value = 0;
 341                 sym->st_size = 0;
 342                 sym->st_info = ELF_ST_INFO(STB_LOCAL, STT_FILE);
 343                 sym->st_other = 0;
 344                 sym->st_shndx = SHN_ABS;
 345 
 346                 if (versym && !dynsym)
 347                         versym[1] = 0;
 348         }
 349         if (ldynsym) {
 350                 (void) st_setstring(dynstr, ofl->ofl_name, &stoff);
 351                 sym = &ldynsym[ldynsym_ndx];
 352                 /* LINTED */
 353                 sym->st_name = stoff;
 354                 sym->st_value = 0;
 355                 sym->st_size = 0;
 356                 sym->st_info = ELF_ST_INFO(STB_LOCAL, STT_FILE);
 357                 sym->st_other = 0;
 358                 sym->st_shndx = SHN_ABS;
 359 
 360                 /* Scoped symbols get filled in global loop below */
 361                 ldynscopesym_ndx = ldynsym_ndx + 1;
 362                 ldynsym_ndx += ofl->ofl_dynscopecnt;
 363         }
 364 
 365         /*
 366          * If we are to display GOT summary information, then allocate
 367          * the buffer to 'cache' the GOT symbols into now.
 368          */
 369         if (DBG_ENABLED) {
 370                 if ((ofl->ofl_gottable = gottable =
 371                     libld_calloc(ofl->ofl_gotcnt, sizeof (Gottable))) == NULL)
 372                         return ((Addr)S_ERROR);
 373         }
 374 
 375         /*
 376          * Traverse the program headers.  Determine the last executable segment
 377          * and the last data segment so that we can update etext and edata. If
 378          * we have empty segments (reservations) record them for setting _end.
 379          */
 380         for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp)) {
 381                 Phdr    *phd = &(sgp->sg_phdr);
 382                 Os_desc *osp;
 383                 Aliste  idx2;
 384 
 385                 if (phd->p_type == PT_LOAD) {
 386                         if (sgp->sg_osdescs != NULL) {
 387                                 Word    _flags = phd->p_flags & (PF_W | PF_R);
 388 
 389                                 if (_flags == PF_R)
 390                                         tsgp = sgp;
 391                                 else if (_flags == (PF_W | PF_R))
 392                                         dsgp = sgp;
 393                         } else if (sgp->sg_flags & FLG_SG_EMPTY)
 394                                 esgp = sgp;
 395                 }
 396 
 397                 /*
 398                  * Generate a section symbol for each output section.
 399                  */
 400                 for (APLIST_TRAVERSE(sgp->sg_osdescs, idx2, osp)) {
 401                         Word    sectndx;
 402 
 403                         sym = &_sym;
 404                         sym->st_value = osp->os_shdr->sh_addr;
 405                         sym->st_info = ELF_ST_INFO(STB_LOCAL, STT_SECTION);
 406                         /* LINTED */
 407                         sectndx = elf_ndxscn(osp->os_scn);
 408 
 409                         if (symtab) {
 410                                 if (sectndx >= SHN_LORESERVE) {
 411                                         symshndx[symtab_ndx] = sectndx;
 412                                         sym->st_shndx = SHN_XINDEX;
 413                                 } else {
 414                                         /* LINTED */
 415                                         sym->st_shndx = (Half)sectndx;
 416                                 }
 417                                 symtab[symtab_ndx++] = *sym;
 418                         }
 419 
 420                         if (dynsym && (osp->os_flags & FLG_OS_OUTREL))
 421                                 dynsym[dynsym_ndx++] = *sym;
 422 
 423                         if ((dynsym == NULL) ||
 424                             (osp->os_flags & FLG_OS_OUTREL)) {
 425                                 if (versym)
 426                                         versym[*symndx - 1] = 0;
 427                                 osp->os_identndx = *symndx - 1;
 428                                 DBG_CALL(Dbg_syms_sec_entry(ofl->ofl_lml,
 429                                     osp->os_identndx, sgp, osp));
 430                         }
 431 
 432                         /*
 433                          * Generate the .shstrtab for this section.
 434                          */
 435                         (void) st_setstring(shstrtab, osp->os_name, &stoff);
 436                         osp->os_shdr->sh_name = (Word)stoff;
 437 
 438                         /*
 439                          * Find the section index for our special symbols.
 440                          */
 441                         if (sgp == tsgp) {
 442                                 /* LINTED */
 443                                 etext_ndx = elf_ndxscn(osp->os_scn);
 444                         } else if (dsgp == sgp) {
 445                                 if (osp->os_shdr->sh_type != SHT_NOBITS) {
 446                                         /* LINTED */
 447                                         edata_ndx = elf_ndxscn(osp->os_scn);
 448                                 }
 449                         }
 450 
 451                         if (start_set == 0) {
 452                                 start = sgp->sg_phdr.p_vaddr;
 453                                 /* LINTED */
 454                                 start_ndx = elf_ndxscn(osp->os_scn);
 455                                 start_set++;
 456                         }
 457 
 458                         /*
 459                          * While we're here, determine whether a .init or .fini
 460                          * section exist.
 461                          */
 462                         if ((iosp == NULL) && (strcmp(osp->os_name,
 463                             MSG_ORIG(MSG_SCN_INIT)) == 0))
 464                                 iosp = osp;
 465                         if ((fosp == NULL) && (strcmp(osp->os_name,
 466                             MSG_ORIG(MSG_SCN_FINI)) == 0))
 467                                 fosp = osp;
 468                 }
 469         }
 470 
 471         /*
 472          * Add local register symbols to the .dynsym.  These are required as
 473          * DT_REGISTER .dynamic entries must have a symbol to reference.
 474          */
 475         if (ofl->ofl_regsyms && dynsym) {
 476                 int     ndx;
 477 
 478                 for (ndx = 0; ndx < ofl->ofl_regsymsno; ndx++) {
 479                         Sym_desc        *rsdp;
 480 
 481                         if ((rsdp = ofl->ofl_regsyms[ndx]) == NULL)
 482                                 continue;
 483 
 484                         if (!SYM_IS_HIDDEN(rsdp) &&
 485                             (ELF_ST_BIND(rsdp->sd_sym->st_info) != STB_LOCAL))
 486                                 continue;
 487 
 488                         dynsym[dynsym_ndx] = *(rsdp->sd_sym);
 489                         rsdp->sd_symndx = *symndx;
 490 
 491                         if (dynsym[dynsym_ndx].st_name) {
 492                                 (void) st_setstring(dynstr, rsdp->sd_name,
 493                                     &stoff);
 494                                 dynsym[dynsym_ndx].st_name = stoff;
 495                         }
 496                         dynsym_ndx++;
 497                 }
 498         }
 499 
 500         /*
 501          * Having traversed all the output segments, warn the user if the
 502          * traditional text or data segments don't exist.  Otherwise from these
 503          * segments establish the values for `etext', `edata', `end', `END',
 504          * and `START'.
 505          */
 506         if (!(flags & FLG_OF_RELOBJ)) {
 507                 Sg_desc *sgp;
 508 
 509                 if (tsgp)
 510                         etext = tsgp->sg_phdr.p_vaddr + tsgp->sg_phdr.p_filesz;
 511                 else {
 512                         etext = (Addr)0;
 513                         etext_ndx = SHN_ABS;
 514                         etext_abs = 1;
 515                         if (flags & FLG_OF_VERBOSE)
 516                                 ld_eprintf(ofl, ERR_WARNING,
 517                                     MSG_INTL(MSG_UPD_NOREADSEG));
 518                 }
 519                 if (dsgp) {
 520                         edata = dsgp->sg_phdr.p_vaddr + dsgp->sg_phdr.p_filesz;
 521                 } else {
 522                         edata = (Addr)0;
 523                         edata_ndx = SHN_ABS;
 524                         edata_abs = 1;
 525                         if (flags & FLG_OF_VERBOSE)
 526                                 ld_eprintf(ofl, ERR_WARNING,
 527                                     MSG_INTL(MSG_UPD_NORDWRSEG));
 528                 }
 529 
 530                 if (dsgp == NULL) {
 531                         if (tsgp)
 532                                 sgp = tsgp;
 533                         else
 534                                 sgp = 0;
 535                 } else if (tsgp == NULL)
 536                         sgp = dsgp;
 537                 else if (dsgp->sg_phdr.p_vaddr > tsgp->sg_phdr.p_vaddr)
 538                         sgp = dsgp;
 539                 else if (dsgp->sg_phdr.p_vaddr < tsgp->sg_phdr.p_vaddr)
 540                         sgp = tsgp;
 541                 else {
 542                         /*
 543                          * One of the segments must be of zero size.
 544                          */
 545                         if (tsgp->sg_phdr.p_memsz)
 546                                 sgp = tsgp;
 547                         else
 548                                 sgp = dsgp;
 549                 }
 550 
 551                 if (esgp && (esgp->sg_phdr.p_vaddr > sgp->sg_phdr.p_vaddr))
 552                         sgp = esgp;
 553 
 554                 if (sgp) {
 555                         end = sgp->sg_phdr.p_vaddr + sgp->sg_phdr.p_memsz;
 556 
 557                         /*
 558                          * If the last loadable segment is a read-only segment,
 559                          * then the application which uses the symbol _end to
 560                          * find the beginning of writable heap area may cause
 561                          * segmentation violation. We adjust the value of the
 562                          * _end to skip to the next page boundary.
 563                          *
 564                          * 6401812 System interface which returs beginning
 565                          *         heap would be nice.
 566                          * When the above RFE is implemented, the changes below
 567                          * could be changed in a better way.
 568                          */
 569                         if ((sgp->sg_phdr.p_flags & PF_W) == 0)
 570                                 end = (Addr)S_ROUND(end, sysconf(_SC_PAGESIZE));
 571 
 572                         /*
 573                          * If we're dealing with a memory reservation there are
 574                          * no sections to establish an index for _end, so assign
 575                          * it as an absolute.
 576                          */
 577                         if (sgp->sg_osdescs != NULL) {
 578                                 /*
 579                                  * Determine the last section for this segment.
 580                                  */
 581                                 Os_desc *osp = sgp->sg_osdescs->apl_data
 582                                     [sgp->sg_osdescs->apl_nitems - 1];
 583 
 584                                 /* LINTED */
 585                                 end_ndx = elf_ndxscn(osp->os_scn);
 586                         } else {
 587                                 end_ndx = SHN_ABS;
 588                                 end_abs = 1;
 589                         }
 590                 } else {
 591                         end = (Addr) 0;
 592                         end_ndx = SHN_ABS;
 593                         end_abs = 1;
 594                         ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_UPD_NOSEG));
 595                 }
 596         }
 597 
 598         /*
 599          * Initialize the scoped symbol table entry point.  This is for all
 600          * the global symbols that have been scoped to locals and will be
 601          * filled in during global symbol processing so that we don't have
 602          * to traverse the globals symbol hash array more than once.
 603          */
 604         if (symtab) {
 605                 scopesym_bndx = symtab_ndx;
 606                 scopesym_ndx = scopesym_bndx;
 607                 symtab_ndx += ofl->ofl_scopecnt;
 608         }
 609 
 610         /*
 611          * If expanding partially expanded symbols under '-z nopartial',
 612          * prepare to do that.
 613          */
 614         if (ofl->ofl_isparexpn) {
 615                 osp = ofl->ofl_isparexpn->is_osdesc;
 616                 parexpnbase = parexpnaddr = (Addr)(osp->os_shdr->sh_addr +
 617                     ofl->ofl_isparexpn->is_indata->d_off);
 618                 /* LINTED */
 619                 parexpnndx = elf_ndxscn(osp->os_scn);
 620                 ofl->ofl_parexpnndx = osp->os_identndx;
 621         }
 622 
 623         /*
 624          * If we are generating a .symtab collect all the local symbols,
 625          * assigning a new virtual address or displacement (value).
 626          */
 627         for (APLIST_TRAVERSE(ofl->ofl_objs, idx1, ifl)) {
 628                 Xword           lndx, local = ifl->ifl_locscnt;
 629                 Cap_desc        *cdp = ifl->ifl_caps;
 630 
 631                 for (lndx = 1; lndx < local; lndx++) {
 632                         Gotndx          *gnp;
 633                         uchar_t         type;
 634                         Word            *_symshndx;
 635                         int             enter_in_symtab, enter_in_ldynsym;
 636                         int             update_done;
 637 
 638                         sdp = ifl->ifl_oldndx[lndx];
 639                         sym = sdp->sd_sym;
 640 
 641                         /*
 642                          * Assign a got offset if necessary.
 643                          */
 644                         if ((ld_targ.t_mr.mr_assign_got != NULL) &&
 645                             (*ld_targ.t_mr.mr_assign_got)(ofl, sdp) == S_ERROR)
 646                                 return ((Addr)S_ERROR);
 647 
 648                         if (DBG_ENABLED) {
 649                                 Aliste  idx2;
 650 
 651                                 for (ALIST_TRAVERSE(sdp->sd_GOTndxs,
 652                                     idx2, gnp)) {
 653                                         gottable->gt_sym = sdp;
 654                                         gottable->gt_gndx.gn_gotndx =
 655                                             gnp->gn_gotndx;
 656                                         gottable->gt_gndx.gn_addend =
 657                                             gnp->gn_addend;
 658                                         gottable++;
 659                                 }
 660                         }
 661 
 662                         if ((type = ELF_ST_TYPE(sym->st_info)) == STT_SECTION)
 663                                 continue;
 664 
 665                         /*
 666                          * Ignore any symbols that have been marked as invalid
 667                          * during input processing.  Providing these aren't used
 668                          * for relocation they'll just be dropped from the
 669                          * output image.
 670                          */
 671                         if (sdp->sd_flags & FLG_SY_INVALID)
 672                                 continue;
 673 
 674                         /*
 675                          * If the section that this symbol was associated
 676                          * with has been discarded - then we discard
 677                          * the local symbol along with it.
 678                          */
 679                         if (sdp->sd_flags & FLG_SY_ISDISC)
 680                                 continue;
 681 
 682                         /*
 683                          * If this symbol is from a different file
 684                          * than the input descriptor we are processing,
 685                          * treat it as if it has FLG_SY_ISDISC set.
 686                          * This happens when sloppy_comdat_reloc()
 687                          * replaces a symbol to a discarded comdat section
 688                          * with an equivalent symbol from a different
 689                          * file. We only want to enter such a symbol
 690                          * once --- as part of the file that actually
 691                          * supplies it.
 692                          */
 693                         if (ifl != sdp->sd_file)
 694                                 continue;
 695 
 696                         /*
 697                          * Generate an output symbol to represent this input
 698                          * symbol.  Even if the symbol table is to be stripped
 699                          * we still need to update any local symbols that are
 700                          * used during relocation.
 701                          */
 702                         enter_in_symtab = symtab &&
 703                             (!(ofl->ofl_flags & FLG_OF_REDLSYM) ||
 704                             sdp->sd_move);
 705                         enter_in_ldynsym = ldynsym && sdp->sd_name &&
 706                             ldynsym_symtype[type] &&
 707                             !(ofl->ofl_flags & FLG_OF_REDLSYM);
 708                         _symshndx = NULL;
 709 
 710                         if (enter_in_symtab) {
 711                                 if (!dynsym)
 712                                         sdp->sd_symndx = *symndx;
 713                                 symtab[symtab_ndx] = *sym;
 714 
 715                                 /*
 716                                  * Provided this isn't an unnamed register
 717                                  * symbol, update its name.
 718                                  */
 719                                 if (((sdp->sd_flags & FLG_SY_REGSYM) == 0) ||
 720                                     symtab[symtab_ndx].st_name) {
 721                                         (void) st_setstring(strtab,
 722                                             sdp->sd_name, &stoff);
 723                                         symtab[symtab_ndx].st_name = stoff;
 724                                 }
 725                                 sdp->sd_flags &= ~FLG_SY_CLEAN;
 726                                 if (symshndx)
 727                                         _symshndx = &symshndx[symtab_ndx];
 728                                 sdp->sd_sym = sym = &symtab[symtab_ndx++];
 729 
 730                                 if ((sdp->sd_flags & FLG_SY_SPECSEC) &&
 731                                     (sym->st_shndx == SHN_ABS) &&
 732                                     !enter_in_ldynsym)
 733                                         continue;
 734                         } else if (enter_in_ldynsym) {
 735                                 /*
 736                                  * Not using symtab, but we do have ldynsym
 737                                  * available.
 738                                  */
 739                                 ldynsym[ldynsym_ndx] = *sym;
 740                                 (void) st_setstring(dynstr, sdp->sd_name,
 741                                     &stoff);
 742                                 ldynsym[ldynsym_ndx].st_name = stoff;
 743 
 744                                 sdp->sd_flags &= ~FLG_SY_CLEAN;
 745                                 if (ldynshndx)
 746                                         _symshndx = &ldynshndx[ldynsym_ndx];
 747                                 sdp->sd_sym = sym = &ldynsym[ldynsym_ndx];
 748                                 /* Add it to sort section if it qualifies */
 749                                 ADD_TO_DYNSORT(sdp, sym, type, ldynsym_ndx);
 750                                 ldynsym_ndx++;
 751                         } else {        /* Not using symtab or ldynsym */
 752                                 /*
 753                                  * If this symbol requires modifying to provide
 754                                  * for a relocation or move table update, make
 755                                  * a copy of it.
 756                                  */
 757                                 if (!(sdp->sd_flags & FLG_SY_UPREQD) &&
 758                                     !(sdp->sd_move))
 759                                         continue;
 760                                 if ((sdp->sd_flags & FLG_SY_SPECSEC) &&
 761                                     (sym->st_shndx == SHN_ABS))
 762                                         continue;
 763 
 764                                 if (ld_sym_copy(sdp) == S_ERROR)
 765                                         return ((Addr)S_ERROR);
 766                                 sym = sdp->sd_sym;
 767                         }
 768 
 769                         /*
 770                          * Update the symbols contents if necessary.
 771                          */
 772                         update_done = 0;
 773                         if (type == STT_FILE) {
 774                                 sdp->sd_shndx = sym->st_shndx = SHN_ABS;
 775                                 sdp->sd_flags |= FLG_SY_SPECSEC;
 776                                 update_done = 1;
 777                         }
 778 
 779                         /*
 780                          * If we are expanding the locally bound partially
 781                          * initialized symbols, then update the address here.
 782                          */
 783                         if (ofl->ofl_isparexpn &&
 784                             (sdp->sd_flags & FLG_SY_PAREXPN) && !update_done) {
 785                                 sym->st_shndx = parexpnndx;
 786                                 sdp->sd_isc = ofl->ofl_isparexpn;
 787                                 sym->st_value = parexpnaddr;
 788                                 parexpnaddr += sym->st_size;
 789                                 if ((flags & FLG_OF_RELOBJ) == 0)
 790                                         sym->st_value -= parexpnbase;
 791                         }
 792 
 793                         /*
 794                          * If this isn't an UNDEF symbol (ie. an input section
 795                          * is associated), update the symbols value and index.
 796                          */
 797                         if (((isc = sdp->sd_isc) != NULL) && !update_done) {
 798                                 Word    sectndx;
 799 
 800                                 osp = isc->is_osdesc;
 801                                 /* LINTED */
 802                                 sym->st_value +=
 803                                     (Off)_elf_getxoff(isc->is_indata);
 804                                 if ((flags & FLG_OF_RELOBJ) == 0) {
 805                                         sym->st_value += osp->os_shdr->sh_addr;
 806                                         /*
 807                                          * TLS symbols are relative to
 808                                          * the TLS segment.
 809                                          */
 810                                         if ((type == STT_TLS) &&
 811                                             (ofl->ofl_tlsphdr)) {
 812                                                 sym->st_value -=
 813                                                     ofl->ofl_tlsphdr->p_vaddr;
 814                                         }
 815                                 }
 816                                 /* LINTED */
 817                                 if ((sdp->sd_shndx = sectndx =
 818                                     elf_ndxscn(osp->os_scn)) >= SHN_LORESERVE) {
 819                                         if (_symshndx) {
 820                                                 *_symshndx = sectndx;
 821                                         }
 822                                         sym->st_shndx = SHN_XINDEX;
 823                                 } else {
 824                                         /* LINTED */
 825                                         sym->st_shndx = sectndx;
 826                                 }
 827                         }
 828 
 829                         /*
 830                          * If entering the symbol in both the symtab and the
 831                          * ldynsym, then the one in symtab needs to be
 832                          * copied to ldynsym. If it is only in the ldynsym,
 833                          * then the code above already set it up and we have
 834                          * nothing more to do here.
 835                          */
 836                         if (enter_in_symtab && enter_in_ldynsym) {
 837                                 ldynsym[ldynsym_ndx] = *sym;
 838                                 (void) st_setstring(dynstr, sdp->sd_name,
 839                                     &stoff);
 840                                 ldynsym[ldynsym_ndx].st_name = stoff;
 841 
 842                                 if (_symshndx && ldynshndx)
 843                                         ldynshndx[ldynsym_ndx] = *_symshndx;
 844 
 845                                 /* Add it to sort section if it qualifies */
 846                                 ADD_TO_DYNSORT(sdp, sym, type, ldynsym_ndx);
 847 
 848                                 ldynsym_ndx++;
 849                         }
 850                 }
 851 
 852                 /*
 853                  * If this input file has undergone object to symbol
 854                  * capabilities conversion, supply any new capabilities symbols.
 855                  * These symbols are copies of the original global symbols, and
 856                  * follow the existing local symbols that are supplied from this
 857                  * input file (which are identified with a preceding STT_FILE).
 858                  */
 859                 if (symtab && cdp && cdp->ca_syms) {
 860                         Aliste          idx2;
 861                         Cap_sym         *csp;
 862 
 863                         for (APLIST_TRAVERSE(cdp->ca_syms, idx2, csp)) {
 864                                 Is_desc *isp;
 865 
 866                                 sdp = csp->cs_sdp;
 867                                 sym = sdp->sd_sym;
 868 
 869                                 if ((isp = sdp->sd_isc) != NULL) {
 870                                         Os_desc *osp = isp->is_osdesc;
 871 
 872                                         /*
 873                                          * Update the symbols value.
 874                                          */
 875                                         /* LINTED */
 876                                         sym->st_value +=
 877                                             (Off)_elf_getxoff(isp->is_indata);
 878                                         if ((flags & FLG_OF_RELOBJ) == 0)
 879                                                 sym->st_value +=
 880                                                     osp->os_shdr->sh_addr;
 881 
 882                                         /*
 883                                          * Update the symbols section index.
 884                                          */
 885                                         sdp->sd_shndx = sym->st_shndx =
 886                                             elf_ndxscn(osp->os_scn);
 887                                 }
 888 
 889                                 symtab[symtab_ndx] = *sym;
 890                                 (void) st_setstring(strtab, sdp->sd_name,
 891                                     &stoff);
 892                                 symtab[symtab_ndx].st_name = stoff;
 893                                 sdp->sd_symndx = symtab_ndx++;
 894                         }
 895                 }
 896         }
 897 
 898         symtab_gbl_bndx = symtab_ndx;   /* .symtab index of 1st global entry */
 899 
 900         /*
 901          * Two special symbols are `_init' and `_fini'.  If these are supplied
 902          * by crti.o then they are used to represent the total concatenation of
 903          * the `.init' and `.fini' sections.
 904          *
 905          * Determine whether any .init or .fini sections exist.  If these
 906          * sections exist and a dynamic object is being built, but no `_init'
 907          * or `_fini' symbols are found, then the user is probably building
 908          * this object directly from ld(1) rather than using a compiler driver
 909          * that provides the symbols via crt's.
 910          *
 911          * If the .init or .fini section exist, and their associated symbols,
 912          * determine the size of the sections and updated the symbols value
 913          * accordingly.
 914          */
 915         if (((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_INIT_U), SYM_NOHASH, 0,
 916             ofl)) != NULL) && (sdp->sd_ref == REF_REL_NEED) && sdp->sd_isc &&
 917             (sdp->sd_isc->is_osdesc == iosp)) {
 918                 if (ld_sym_copy(sdp) == S_ERROR)
 919                         return ((Addr)S_ERROR);
 920                 sdp->sd_sym->st_size = sdp->sd_isc->is_osdesc->os_shdr->sh_size;
 921 
 922         } else if (iosp && !(flags & FLG_OF_RELOBJ)) {
 923                 ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_NOCRT),
 924                     MSG_ORIG(MSG_SYM_INIT_U), MSG_ORIG(MSG_SCN_INIT));
 925         }
 926 
 927         if (((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_FINI_U), SYM_NOHASH, 0,
 928             ofl)) != NULL) && (sdp->sd_ref == REF_REL_NEED) && sdp->sd_isc &&
 929             (sdp->sd_isc->is_osdesc == fosp)) {
 930                 if (ld_sym_copy(sdp) == S_ERROR)
 931                         return ((Addr)S_ERROR);
 932                 sdp->sd_sym->st_size = sdp->sd_isc->is_osdesc->os_shdr->sh_size;
 933 
 934         } else if (fosp && !(flags & FLG_OF_RELOBJ)) {
 935                 ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_SYM_NOCRT),
 936                     MSG_ORIG(MSG_SYM_FINI_U), MSG_ORIG(MSG_SCN_FINI));
 937         }
 938 
 939         /*
 940          * Assign .bss information for use with updating COMMON symbols.
 941          */
 942         if (ofl->ofl_isbss) {
 943                 isc = ofl->ofl_isbss;
 944                 osp = isc->is_osdesc;
 945 
 946                 bssaddr = osp->os_shdr->sh_addr +
 947                     (Off)_elf_getxoff(isc->is_indata);
 948                 /* LINTED */
 949                 bssndx = elf_ndxscn(osp->os_scn);
 950         }
 951 
 952 #if     defined(_ELF64)
 953         /*
 954          * For amd64 target, assign .lbss information for use
 955          * with updating LCOMMON symbols.
 956          */
 957         if ((ld_targ.t_m.m_mach == EM_AMD64) && ofl->ofl_islbss) {
 958                 osp = ofl->ofl_islbss->is_osdesc;
 959 
 960                 lbssaddr = osp->os_shdr->sh_addr +
 961                     (Off)_elf_getxoff(ofl->ofl_islbss->is_indata);
 962                 /* LINTED */
 963                 lbssndx = elf_ndxscn(osp->os_scn);
 964         }
 965 #endif
 966         /*
 967          * Assign .tlsbss information for use with updating COMMON symbols.
 968          */
 969         if (ofl->ofl_istlsbss) {
 970                 osp = ofl->ofl_istlsbss->is_osdesc;
 971                 tlsbssaddr = osp->os_shdr->sh_addr +
 972                     (Off)_elf_getxoff(ofl->ofl_istlsbss->is_indata);
 973                 /* LINTED */
 974                 tlsbssndx = elf_ndxscn(osp->os_scn);
 975         }
 976 
 977         if ((sorted_syms = libld_calloc(ofl->ofl_globcnt +
 978             ofl->ofl_elimcnt + ofl->ofl_scopecnt,
 979             sizeof (*sorted_syms))) == NULL)
 980                 return ((Addr)S_ERROR);
 981 
 982         scndx = 0;
 983         ssndx = ofl->ofl_scopecnt + ofl->ofl_elimcnt;
 984 
 985         DBG_CALL(Dbg_syms_up_title(ofl->ofl_lml));
 986 
 987         /*
 988          * Traverse the internal symbol table updating global symbol information
 989          * and allocating common.
 990          */
 991         for (sav = avl_first(&ofl->ofl_symavl); sav;
 992             sav = AVL_NEXT(&ofl->ofl_symavl, sav)) {
 993                 Sym     *symptr;
 994                 int     local;
 995                 int     restore;
 996 
 997                 sdp = sav->sav_sdp;
 998 
 999                 /*
1000                  * Ignore any symbols that have been marked as invalid during
1001                  * input processing.  Providing these aren't used for
1002                  * relocation, they will be dropped from the output image.
1003                  */
1004                 if (sdp->sd_flags & FLG_SY_INVALID) {
1005                         DBG_CALL(Dbg_syms_old(ofl, sdp));
1006                         DBG_CALL(Dbg_syms_ignore(ofl, sdp));
1007                         continue;
1008                 }
1009 
1010                 /*
1011                  * Only needed symbols are copied to the output symbol table.
1012                  */
1013                 if (sdp->sd_ref == REF_DYN_SEEN)
1014                         continue;
1015 
1016                 if (SYM_IS_HIDDEN(sdp) && (flags & FLG_OF_PROCRED))
1017                         local = 1;
1018                 else
1019                         local = 0;
1020 
1021                 if (local || (ofl->ofl_hashbkts == 0)) {
1022                         sorted_syms[scndx++].sl_sdp = sdp;
1023                 } else {
1024                         sorted_syms[ssndx].sl_hval = sdp->sd_aux->sa_hash %
1025                             ofl->ofl_hashbkts;
1026                         sorted_syms[ssndx].sl_sdp = sdp;
1027                         ssndx++;
1028                 }
1029 
1030                 /*
1031                  * Note - expand the COMMON symbols here because an address
1032                  * must be assigned to them in the same order that space was
1033                  * calculated in sym_validate().  If this ordering isn't
1034                  * followed differing alignment requirements can throw us all
1035                  * out of whack.
1036                  *
1037                  * The expanded .bss global symbol is handled here as well.
1038                  *
1039                  * The actual adding entries into the symbol table still occurs
1040                  * below in hashbucket order.
1041                  */
1042                 symptr = sdp->sd_sym;
1043                 restore = 0;
1044                 if ((sdp->sd_flags & FLG_SY_PAREXPN) ||
1045                     ((sdp->sd_flags & FLG_SY_SPECSEC) &&
1046                     (sdp->sd_shndx = symptr->st_shndx) == SHN_COMMON)) {
1047 
1048                         /*
1049                          * An expanded symbol goes to a special .data section
1050                          * prepared for that purpose (ofl->ofl_isparexpn).
1051                          * Assign COMMON allocations to .bss.
1052                          * Otherwise leave it as is.
1053                          */
1054                         if (sdp->sd_flags & FLG_SY_PAREXPN) {
1055                                 restore = 1;
1056                                 sdp->sd_shndx = parexpnndx;
1057                                 sdp->sd_flags &= ~FLG_SY_SPECSEC;
1058                                 symptr->st_value = (Xword) S_ROUND(
1059                                     parexpnaddr, symptr->st_value);
1060                                 parexpnaddr = symptr->st_value +
1061                                     symptr->st_size;
1062                                 sdp->sd_isc = ofl->ofl_isparexpn;
1063                                 sdp->sd_flags |= FLG_SY_COMMEXP;
1064 
1065                         } else if (ELF_ST_TYPE(symptr->st_info) != STT_TLS &&
1066                             (local || !(flags & FLG_OF_RELOBJ))) {
1067                                 restore = 1;
1068                                 sdp->sd_shndx = bssndx;
1069                                 sdp->sd_flags &= ~FLG_SY_SPECSEC;
1070                                 symptr->st_value = (Xword)S_ROUND(bssaddr,
1071                                     symptr->st_value);
1072                                 bssaddr = symptr->st_value + symptr->st_size;
1073                                 sdp->sd_isc = ofl->ofl_isbss;
1074                                 sdp->sd_flags |= FLG_SY_COMMEXP;
1075 
1076                         } else if (ELF_ST_TYPE(symptr->st_info) == STT_TLS &&
1077                             (local || !(flags & FLG_OF_RELOBJ))) {
1078                                 restore = 1;
1079                                 sdp->sd_shndx = tlsbssndx;
1080                                 sdp->sd_flags &= ~FLG_SY_SPECSEC;
1081                                 symptr->st_value = (Xword)S_ROUND(tlsbssaddr,
1082                                     symptr->st_value);
1083                                 tlsbssaddr = symptr->st_value + symptr->st_size;
1084                                 sdp->sd_isc = ofl->ofl_istlsbss;
1085                                 sdp->sd_flags |= FLG_SY_COMMEXP;
1086                                 /*
1087                                  * TLS symbols are relative to the TLS segment.
1088                                  */
1089                                 symptr->st_value -= ofl->ofl_tlsphdr->p_vaddr;
1090                         }
1091 #if     defined(_ELF64)
1092                 } else if ((ld_targ.t_m.m_mach == EM_AMD64) &&
1093                     (sdp->sd_flags & FLG_SY_SPECSEC) &&
1094                     ((sdp->sd_shndx = symptr->st_shndx) ==
1095                     SHN_X86_64_LCOMMON) &&
1096                     ((local || !(flags & FLG_OF_RELOBJ)))) {
1097                         restore = 1;
1098                         sdp->sd_shndx = lbssndx;
1099                         sdp->sd_flags &= ~FLG_SY_SPECSEC;
1100                         symptr->st_value = (Xword)S_ROUND(lbssaddr,
1101                             symptr->st_value);
1102                         lbssaddr = symptr->st_value + symptr->st_size;
1103                         sdp->sd_isc = ofl->ofl_islbss;
1104                         sdp->sd_flags |= FLG_SY_COMMEXP;
1105 #endif
1106                 }
1107 
1108                 if (restore != 0) {
1109                         uchar_t         type, bind;
1110 
1111                         /*
1112                          * Make sure this COMMON symbol is returned to the same
1113                          * binding as was defined in the original relocatable
1114                          * object reference.
1115                          */
1116                         type = ELF_ST_TYPE(symptr->st_info);
1117                         if (sdp->sd_flags & FLG_SY_GLOBREF)
1118                                 bind = STB_GLOBAL;
1119                         else
1120                                 bind = STB_WEAK;
1121 
1122                         symptr->st_info = ELF_ST_INFO(bind, type);
1123                 }
1124         }
1125 
1126         /*
1127          * If this is a dynamic object then add any local capabilities symbols.
1128          */
1129         if (dynsym && ofl->ofl_capfamilies) {
1130                 Cap_avlnode     *cav;
1131 
1132                 for (cav = avl_first(ofl->ofl_capfamilies); cav;
1133                     cav = AVL_NEXT(ofl->ofl_capfamilies, cav)) {
1134                         Cap_sym         *csp;
1135                         Aliste          idx;
1136 
1137                         for (APLIST_TRAVERSE(cav->cn_members, idx, csp)) {
1138                                 sdp = csp->cs_sdp;
1139 
1140                                 DBG_CALL(Dbg_syms_created(ofl->ofl_lml,
1141                                     sdp->sd_name));
1142                                 DBG_CALL(Dbg_syms_entered(ofl, sdp->sd_sym,
1143                                     sdp));
1144 
1145                                 dynsym[dynsym_ndx] = *sdp->sd_sym;
1146 
1147                                 (void) st_setstring(dynstr, sdp->sd_name,
1148                                     &stoff);
1149                                 dynsym[dynsym_ndx].st_name = stoff;
1150 
1151                                 sdp->sd_sym = &dynsym[dynsym_ndx];
1152                                 sdp->sd_symndx = dynsym_ndx;
1153 
1154                                 /*
1155                                  * Indicate that this is a capabilities symbol.
1156                                  * Note, that this identification only provides
1157                                  * information regarding the symbol that is
1158                                  * visible from elfdump(1) -y.  The association
1159                                  * of a symbol to its capabilities is derived
1160                                  * from a .SUNW_capinfo entry.
1161                                  */
1162                                 if (syminfo) {
1163                                         syminfo[dynsym_ndx].si_flags |=
1164                                             SYMINFO_FLG_CAP;
1165                                 }
1166 
1167                                 dynsym_ndx++;
1168                         }
1169                 }
1170         }
1171 
1172         if (ofl->ofl_hashbkts) {
1173                 qsort(sorted_syms + ofl->ofl_scopecnt + ofl->ofl_elimcnt,
1174                     ofl->ofl_globcnt, sizeof (Sym_s_list),
1175                     (int (*)(const void *, const void *))sym_hash_compare);
1176         }
1177 
1178         for (ssndx = 0; ssndx < (ofl->ofl_elimcnt + ofl->ofl_scopecnt +
1179             ofl->ofl_globcnt); ssndx++) {
1180                 const char      *name;
1181                 Sym             *sym;
1182                 Sym_aux         *sap;
1183                 Half            spec;
1184                 int             local = 0, dynlocal = 0, enter_in_symtab;
1185                 Gotndx          *gnp;
1186                 Word            sectndx;
1187 
1188                 sdp = sorted_syms[ssndx].sl_sdp;
1189                 sectndx = 0;
1190 
1191                 if (symtab)
1192                         enter_in_symtab = 1;
1193                 else
1194                         enter_in_symtab = 0;
1195 
1196                 /*
1197                  * Assign a got offset if necessary.
1198                  */
1199                 if ((ld_targ.t_mr.mr_assign_got != NULL) &&
1200                     (*ld_targ.t_mr.mr_assign_got)(ofl, sdp) == S_ERROR)
1201                         return ((Addr)S_ERROR);
1202 
1203                 if (DBG_ENABLED) {
1204                         Aliste  idx2;
1205 
1206                         for (ALIST_TRAVERSE(sdp->sd_GOTndxs, idx2, gnp)) {
1207                                 gottable->gt_sym = sdp;
1208                                 gottable->gt_gndx.gn_gotndx = gnp->gn_gotndx;
1209                                 gottable->gt_gndx.gn_addend = gnp->gn_addend;
1210                                 gottable++;
1211                         }
1212 
1213                         if (sdp->sd_aux && sdp->sd_aux->sa_PLTGOTndx) {
1214                                 gottable->gt_sym = sdp;
1215                                 gottable->gt_gndx.gn_gotndx =
1216                                     sdp->sd_aux->sa_PLTGOTndx;
1217                                 gottable++;
1218                         }
1219                 }
1220 
1221                 /*
1222                  * If this symbol has been marked as being reduced to local
1223                  * scope then it will have to be placed in the scoped portion
1224                  * of the .symtab.  Retain the appropriate index for use in
1225                  * version symbol indexing and relocation.
1226                  */
1227                 if (SYM_IS_HIDDEN(sdp) && (flags & FLG_OF_PROCRED)) {
1228                         local = 1;
1229                         if (!(sdp->sd_flags & FLG_SY_ELIM) && !dynsym)
1230                                 sdp->sd_symndx = scopesym_ndx;
1231                         else
1232                                 sdp->sd_symndx = 0;
1233 
1234                         if (sdp->sd_flags & FLG_SY_ELIM) {
1235                                 enter_in_symtab = 0;
1236                         } else if (ldynsym && sdp->sd_sym->st_name &&
1237                             ldynsym_symtype[
1238                             ELF_ST_TYPE(sdp->sd_sym->st_info)]) {
1239                                 dynlocal = 1;
1240                         }
1241                 } else {
1242                         sdp->sd_symndx = *symndx;
1243                 }
1244 
1245                 /*
1246                  * Copy basic symbol and string information.
1247                  */
1248                 name = sdp->sd_name;
1249                 sap = sdp->sd_aux;
1250 
1251                 /*
1252                  * If we require to record version symbol indexes, update the
1253                  * associated version symbol information for all defined
1254                  * symbols.  If a version definition is required any zero value
1255                  * symbol indexes would have been flagged as undefined symbol
1256                  * errors, however if we're just scoping these need to fall into
1257                  * the base of global symbols.
1258                  */
1259                 if (sdp->sd_symndx && versym) {
1260                         Half    vndx = 0;
1261 
1262                         if (sdp->sd_flags & FLG_SY_MVTOCOMM) {
1263                                 vndx = VER_NDX_GLOBAL;
1264                         } else if (sdp->sd_ref == REF_REL_NEED) {
1265                                 vndx = sap->sa_overndx;
1266 
1267                                 if ((vndx == 0) &&
1268                                     (sdp->sd_sym->st_shndx != SHN_UNDEF)) {
1269                                         if (SYM_IS_HIDDEN(sdp))
1270                                                 vndx = VER_NDX_LOCAL;
1271                                         else
1272                                                 vndx = VER_NDX_GLOBAL;
1273                                 }
1274                         } else if ((sdp->sd_ref == REF_DYN_NEED) &&
1275                             (sap->sa_dverndx > 0) &&
1276                             (sap->sa_dverndx <= sdp->sd_file->ifl_vercnt) &&
1277                             (sdp->sd_file->ifl_verndx != NULL)) {
1278                                 /* Use index of verneed record */
1279                                 vndx = sdp->sd_file->ifl_verndx
1280                                     [sap->sa_dverndx].vi_overndx;
1281                         }
1282                         versym[sdp->sd_symndx] = vndx;
1283                 }
1284 
1285                 /*
1286                  * If we are creating the .syminfo section then set per symbol
1287                  * flags here.
1288                  */
1289                 if (sdp->sd_symndx && syminfo &&
1290                     !(sdp->sd_flags & FLG_SY_NOTAVAIL)) {
1291                         int     ndx = sdp->sd_symndx;
1292                         APlist  **alpp = &(ofl->ofl_symdtent);
1293 
1294                         if (sdp->sd_flags & FLG_SY_MVTOCOMM)
1295                                 /*
1296                                  * Identify a copy relocation symbol.
1297                                  */
1298                                 syminfo[ndx].si_flags |= SYMINFO_FLG_COPY;
1299 
1300                         if (sdp->sd_ref == REF_DYN_NEED) {
1301                                 /*
1302                                  * A reference is bound to a needed dependency.
1303                                  * Save the syminfo entry, so that when the
1304                                  * .dynamic section has been updated, a
1305                                  * DT_NEEDED entry can be associated
1306                                  * (see update_osyminfo()).
1307                                  */
1308                                 if (aplist_append(alpp, sdp,
1309                                     AL_CNT_OFL_SYMINFOSYMS) == NULL)
1310                                         return (0);
1311 
1312                                 /*
1313                                  * Flag that the symbol has a direct association
1314                                  * with the external reference (this is an old
1315                                  * tagging, that has no real effect by itself).
1316                                  */
1317                                 syminfo[ndx].si_flags |= SYMINFO_FLG_DIRECT;
1318 
1319                                 /*
1320                                  * Flag any lazy or deferred reference.
1321                                  */
1322                                 if (sdp->sd_flags & FLG_SY_LAZYLD)
1323                                         syminfo[ndx].si_flags |=
1324                                             SYMINFO_FLG_LAZYLOAD;
1325                                 if (sdp->sd_flags & FLG_SY_DEFERRED)
1326                                         syminfo[ndx].si_flags |=
1327                                             SYMINFO_FLG_DEFERRED;
1328 
1329                                 /*
1330                                  * Enable direct symbol bindings if:
1331                                  *
1332                                  *  -   Symbol was identified with the DIRECT
1333                                  *      keyword in a mapfile.
1334                                  *
1335                                  *  -   Symbol reference has been bound to a
1336                                  *      dependency which was specified as
1337                                  *      requiring direct bindings with -zdirect.
1338                                  *
1339                                  *  -   All symbol references are required to
1340                                  *      use direct bindings via -Bdirect.
1341                                  */
1342                                 if (sdp->sd_flags & FLG_SY_DIR)
1343                                         syminfo[ndx].si_flags |=
1344                                             SYMINFO_FLG_DIRECTBIND;
1345 
1346                         } else if ((sdp->sd_flags & FLG_SY_EXTERN) &&
1347                             (sdp->sd_sym->st_shndx == SHN_UNDEF)) {
1348                                 /*
1349                                  * If this symbol has been explicitly defined
1350                                  * as external, and remains unresolved, mark
1351                                  * it as external.
1352                                  */
1353                                 syminfo[ndx].si_boundto = SYMINFO_BT_EXTERN;
1354 
1355                         } else if ((sdp->sd_flags & FLG_SY_PARENT) &&
1356                             (sdp->sd_sym->st_shndx == SHN_UNDEF)) {
1357                                 /*
1358                                  * If this symbol has been explicitly defined
1359                                  * to be a reference to a parent object,
1360                                  * indicate whether a direct binding should be
1361                                  * established.
1362                                  */
1363                                 syminfo[ndx].si_flags |= SYMINFO_FLG_DIRECT;
1364                                 syminfo[ndx].si_boundto = SYMINFO_BT_PARENT;
1365                                 if (sdp->sd_flags & FLG_SY_DIR)
1366                                         syminfo[ndx].si_flags |=
1367                                             SYMINFO_FLG_DIRECTBIND;
1368 
1369                         } else if (sdp->sd_flags & FLG_SY_STDFLTR) {
1370                                 /*
1371                                  * A filter definition.  Although this symbol
1372                                  * can only be a stub, it might be necessary to
1373                                  * prevent external direct bindings.
1374                                  */
1375                                 syminfo[ndx].si_flags |= SYMINFO_FLG_FILTER;
1376                                 if (sdp->sd_flags & FLG_SY_NDIR)
1377                                         syminfo[ndx].si_flags |=
1378                                             SYMINFO_FLG_NOEXTDIRECT;
1379 
1380                         } else if (sdp->sd_flags & FLG_SY_AUXFLTR) {
1381                                 /*
1382                                  * An auxiliary filter definition.  By nature,
1383                                  * this definition is direct, in that should the
1384                                  * filtee lookup fail, we'll fall back to this
1385                                  * object.  It may still be necessary to
1386                                  * prevent external direct bindings.
1387                                  */
1388                                 syminfo[ndx].si_flags |= SYMINFO_FLG_AUXILIARY;
1389                                 if (sdp->sd_flags & FLG_SY_NDIR)
1390                                         syminfo[ndx].si_flags |=
1391                                             SYMINFO_FLG_NOEXTDIRECT;
1392 
1393                         } else if ((sdp->sd_ref == REF_REL_NEED) &&
1394                             (sdp->sd_sym->st_shndx != SHN_UNDEF)) {
1395                                 /*
1396                                  * This definition exists within the object
1397                                  * being created.  Provide a default boundto
1398                                  * definition, which may be overridden later.
1399                                  */
1400                                 syminfo[ndx].si_boundto = SYMINFO_BT_NONE;
1401 
1402                                 /*
1403                                  * Indicate whether it is necessary to prevent
1404                                  * external direct bindings.
1405                                  */
1406                                 if (sdp->sd_flags & FLG_SY_NDIR) {
1407                                         syminfo[ndx].si_flags |=
1408                                             SYMINFO_FLG_NOEXTDIRECT;
1409                                 }
1410 
1411                                 /*
1412                                  * Indicate that this symbol is acting as an
1413                                  * individual interposer.
1414                                  */
1415                                 if (sdp->sd_flags & FLG_SY_INTPOSE) {
1416                                         syminfo[ndx].si_flags |=
1417                                             SYMINFO_FLG_INTERPOSE;
1418                                 }
1419 
1420                                 /*
1421                                  * Indicate that this symbol is deferred, and
1422                                  * hence should not be bound to during BIND_NOW
1423                                  * relocations.
1424                                  */
1425                                 if (sdp->sd_flags & FLG_SY_DEFERRED) {
1426                                         syminfo[ndx].si_flags |=
1427                                             SYMINFO_FLG_DEFERRED;
1428                                 }
1429 
1430                                 /*
1431                                  * If external bindings are allowed, indicate
1432                                  * the binding, and a direct binding if
1433                                  * necessary.
1434                                  */
1435                                 if ((sdp->sd_flags & FLG_SY_NDIR) == 0) {
1436                                         syminfo[ndx].si_flags |=
1437                                             SYMINFO_FLG_DIRECT;
1438 
1439                                         if (sdp->sd_flags & FLG_SY_DIR)
1440                                                 syminfo[ndx].si_flags |=
1441                                                     SYMINFO_FLG_DIRECTBIND;
1442 
1443                                         /*
1444                                          * Provide a default boundto definition,
1445                                          * which may be overridden later.
1446                                          */
1447                                         syminfo[ndx].si_boundto =
1448                                             SYMINFO_BT_SELF;
1449                                 }
1450 
1451                                 /*
1452                                  * Indicate that this is a capabilities symbol.
1453                                  * Note, that this identification only provides
1454                                  * information regarding the symbol that is
1455                                  * visible from elfdump(1) -y.  The association
1456                                  * of a symbol to its capabilities is derived
1457                                  * from a .SUNW_capinfo entry.
1458                                  */
1459                                 if ((sdp->sd_flags & FLG_SY_CAP) &&
1460                                     ofl->ofl_oscapinfo) {
1461                                         syminfo[ndx].si_flags |=
1462                                             SYMINFO_FLG_CAP;
1463                                 }
1464                         }
1465                 }
1466 
1467                 /*
1468                  * Note that the `sym' value is reset to be one of the new
1469                  * symbol table entries.  This symbol will be updated further
1470                  * depending on the type of the symbol.  Process the .symtab
1471                  * first, followed by the .dynsym, thus the `sym' value will
1472                  * remain as the .dynsym value when the .dynsym is present.
1473                  * This ensures that any versioning symbols st_name value will
1474                  * be appropriate for the string table used by version
1475                  * entries.
1476                  */
1477                 if (enter_in_symtab) {
1478                         Word    _symndx;
1479 
1480                         if (local)
1481                                 _symndx = scopesym_ndx;
1482                         else
1483                                 _symndx = symtab_ndx;
1484 
1485                         symtab[_symndx] = *sdp->sd_sym;
1486                         sdp->sd_sym = sym = &symtab[_symndx];
1487                         (void) st_setstring(strtab, name, &stoff);
1488                         sym->st_name = stoff;
1489                 }
1490                 if (dynlocal) {
1491                         ldynsym[ldynscopesym_ndx] = *sdp->sd_sym;
1492                         sdp->sd_sym = sym = &ldynsym[ldynscopesym_ndx];
1493                         (void) st_setstring(dynstr, name, &stoff);
1494                         ldynsym[ldynscopesym_ndx].st_name = stoff;
1495                         /* Add it to sort section if it qualifies */
1496                         ADD_TO_DYNSORT(sdp, sym, ELF_ST_TYPE(sym->st_info),
1497                             ldynscopesym_ndx);
1498                 }
1499 
1500                 if (dynsym && !local) {
1501                         dynsym[dynsym_ndx] = *sdp->sd_sym;
1502 
1503                         /*
1504                          * Provided this isn't an unnamed register symbol,
1505                          * update the symbols name and hash value.
1506                          */
1507                         if (((sdp->sd_flags & FLG_SY_REGSYM) == 0) ||
1508                             dynsym[dynsym_ndx].st_name) {
1509                                 (void) st_setstring(dynstr, name, &stoff);
1510                                 dynsym[dynsym_ndx].st_name = stoff;
1511 
1512                                 if (stoff) {
1513                                         Word    hashval, _hashndx;
1514 
1515                                         hashval =
1516                                             sap->sa_hash % ofl->ofl_hashbkts;
1517 
1518                                         /* LINTED */
1519                                         if (_hashndx = hashbkt[hashval]) {
1520                                                 while (hashchain[_hashndx]) {
1521                                                         _hashndx =
1522                                                             hashchain[_hashndx];
1523                                                 }
1524                                                 hashchain[_hashndx] =
1525                                                     sdp->sd_symndx;
1526                                         } else {
1527                                                 hashbkt[hashval] =
1528                                                     sdp->sd_symndx;
1529                                         }
1530                                 }
1531                         }
1532                         sdp->sd_sym = sym = &dynsym[dynsym_ndx];
1533 
1534                         /*
1535                          * Add it to sort section if it qualifies.
1536                          * The indexes in that section are relative to the
1537                          * the adjacent SUNW_ldynsym/dymsym pair, so we
1538                          * add the number of items in SUNW_ldynsym to the
1539                          * dynsym index.
1540                          */
1541                         ADD_TO_DYNSORT(sdp, sym, ELF_ST_TYPE(sym->st_info),
1542                             ldynsym_cnt + dynsym_ndx);
1543                 }
1544 
1545                 if (!enter_in_symtab && (!dynsym || (local && !dynlocal))) {
1546                         if (!(sdp->sd_flags & FLG_SY_UPREQD))
1547                                 continue;
1548                         sym = sdp->sd_sym;
1549                 } else
1550                         sdp->sd_flags &= ~FLG_SY_CLEAN;
1551 
1552                 /*
1553                  * If we have a weak data symbol for which we need the real
1554                  * symbol also, save this processing until later.
1555                  *
1556                  * The exception to this is if the weak/strong have PLT's
1557                  * assigned to them.  In that case we don't do the post-weak
1558                  * processing because the PLT's must be maintained so that we
1559                  * can do 'interpositioning' on both of the symbols.
1560                  */
1561                 if ((sap->sa_linkndx) &&
1562                     (ELF_ST_BIND(sym->st_info) == STB_WEAK) &&
1563                     (!sap->sa_PLTndx)) {
1564                         Sym_desc        *_sdp;
1565 
1566                         _sdp = sdp->sd_file->ifl_oldndx[sap->sa_linkndx];
1567 
1568                         if (_sdp->sd_ref != REF_DYN_SEEN) {
1569                                 Wk_desc wk;
1570 
1571                                 if (enter_in_symtab) {
1572                                         if (local) {
1573                                                 wk.wk_symtab =
1574                                                     &symtab[scopesym_ndx];
1575                                                 scopesym_ndx++;
1576                                         } else {
1577                                                 wk.wk_symtab =
1578                                                     &symtab[symtab_ndx];
1579                                                 symtab_ndx++;
1580                                         }
1581                                 } else {
1582                                         wk.wk_symtab = NULL;
1583                                 }
1584                                 if (dynsym) {
1585                                         if (!local) {
1586                                                 wk.wk_dynsym =
1587                                                     &dynsym[dynsym_ndx];
1588                                                 dynsym_ndx++;
1589                                         } else if (dynlocal) {
1590                                                 wk.wk_dynsym =
1591                                                     &ldynsym[ldynscopesym_ndx];
1592                                                 ldynscopesym_ndx++;
1593                                         }
1594                                 } else {
1595                                         wk.wk_dynsym = NULL;
1596                                 }
1597                                 wk.wk_weak = sdp;
1598                                 wk.wk_alias = _sdp;
1599 
1600                                 if (alist_append(&weak, &wk,
1601                                     sizeof (Wk_desc), AL_CNT_WEAK) == NULL)
1602                                         return ((Addr)S_ERROR);
1603 
1604                                 continue;
1605                         }
1606                 }
1607 
1608                 DBG_CALL(Dbg_syms_old(ofl, sdp));
1609 
1610                 spec = NULL;
1611                 /*
1612                  * assign new symbol value.
1613                  */
1614                 sectndx = sdp->sd_shndx;
1615                 if (sectndx == SHN_UNDEF) {
1616                         if (((sdp->sd_flags & FLG_SY_REGSYM) == 0) &&
1617                             (sym->st_value != 0)) {
1618                                 ld_eprintf(ofl, ERR_WARNING,
1619                                     MSG_INTL(MSG_SYM_NOTNULL),
1620                                     demangle(name), sdp->sd_file->ifl_name);
1621                         }
1622 
1623                         /*
1624                          * Undefined weak global, if we are generating a static
1625                          * executable, output as an absolute zero.  Otherwise
1626                          * leave it as is, ld.so.1 will skip symbols of this
1627                          * type (this technique allows applications and
1628                          * libraries to test for the existence of a symbol as an
1629                          * indication of the presence or absence of certain
1630                          * functionality).
1631                          */
1632                         if (OFL_IS_STATIC_EXEC(ofl) &&
1633                             (ELF_ST_BIND(sym->st_info) == STB_WEAK)) {
1634                                 sdp->sd_flags |= FLG_SY_SPECSEC;
1635                                 sdp->sd_shndx = sectndx = SHN_ABS;
1636                         }
1637                 } else if ((sdp->sd_flags & FLG_SY_SPECSEC) &&
1638                     (sectndx == SHN_COMMON)) {
1639                         /* COMMONs have already been processed */
1640                         /* EMPTY */
1641                         ;
1642                 } else {
1643                         if ((sdp->sd_flags & FLG_SY_SPECSEC) &&
1644                             (sectndx == SHN_ABS))
1645                                 spec = sdp->sd_aux->sa_symspec;
1646 
1647                         /* LINTED */
1648                         if (sdp->sd_flags & FLG_SY_COMMEXP) {
1649                                 /*
1650                                  * This is (or was) a COMMON symbol which was
1651                                  * processed above - no processing
1652                                  * required here.
1653                                  */
1654                                 ;
1655                         } else if (sdp->sd_ref == REF_DYN_NEED) {
1656                                 uchar_t type, bind;
1657 
1658                                 sectndx = SHN_UNDEF;
1659                                 sym->st_value = 0;
1660                                 sym->st_size = 0;
1661 
1662                                 /*
1663                                  * Make sure this undefined symbol is returned
1664                                  * to the same binding as was defined in the
1665                                  * original relocatable object reference.
1666                                  */
1667                                 type = ELF_ST_TYPE(sym-> st_info);
1668                                 if (sdp->sd_flags & FLG_SY_GLOBREF)
1669                                         bind = STB_GLOBAL;
1670                                 else
1671                                         bind = STB_WEAK;
1672 
1673                                 sym->st_info = ELF_ST_INFO(bind, type);
1674 
1675                         } else if (((sdp->sd_flags & FLG_SY_SPECSEC) == 0) &&
1676                             (sdp->sd_ref == REF_REL_NEED)) {
1677                                 osp = sdp->sd_isc->is_osdesc;
1678                                 /* LINTED */
1679                                 sectndx = elf_ndxscn(osp->os_scn);
1680 
1681                                 /*
1682                                  * In an executable, the new symbol value is the
1683                                  * old value (offset into defining section) plus
1684                                  * virtual address of defining section.  In a
1685                                  * relocatable, the new value is the old value
1686                                  * plus the displacement of the section within
1687                                  * the file.
1688                                  */
1689                                 /* LINTED */
1690                                 sym->st_value +=
1691                                     (Off)_elf_getxoff(sdp->sd_isc->is_indata);
1692 
1693                                 if (!(flags & FLG_OF_RELOBJ)) {
1694                                         sym->st_value += osp->os_shdr->sh_addr;
1695                                         /*
1696                                          * TLS symbols are relative to
1697                                          * the TLS segment.
1698                                          */
1699                                         if ((ELF_ST_TYPE(sym->st_info) ==
1700                                             STT_TLS) && (ofl->ofl_tlsphdr))
1701                                                 sym->st_value -=
1702                                                     ofl->ofl_tlsphdr->p_vaddr;
1703                                 }
1704                         }
1705                 }
1706 
1707                 if (spec) {
1708                         switch (spec) {
1709                         case SDAUX_ID_ETEXT:
1710                                 sym->st_value = etext;
1711                                 sectndx = etext_ndx;
1712                                 if (etext_abs)
1713                                         sdp->sd_flags |= FLG_SY_SPECSEC;
1714                                 else
1715                                         sdp->sd_flags &= ~FLG_SY_SPECSEC;
1716                                 break;
1717                         case SDAUX_ID_EDATA:
1718                                 sym->st_value = edata;
1719                                 sectndx = edata_ndx;
1720                                 if (edata_abs)
1721                                         sdp->sd_flags |= FLG_SY_SPECSEC;
1722                                 else
1723                                         sdp->sd_flags &= ~FLG_SY_SPECSEC;
1724                                 break;
1725                         case SDAUX_ID_END:
1726                                 sym->st_value = end;
1727                                 sectndx = end_ndx;
1728                                 if (end_abs)
1729                                         sdp->sd_flags |= FLG_SY_SPECSEC;
1730                                 else
1731                                         sdp->sd_flags &= ~FLG_SY_SPECSEC;
1732                                 break;
1733                         case SDAUX_ID_START:
1734                                 sym->st_value = start;
1735                                 sectndx = start_ndx;
1736                                 sdp->sd_flags &= ~FLG_SY_SPECSEC;
1737                                 break;
1738                         case SDAUX_ID_DYN:
1739                                 if (flags & FLG_OF_DYNAMIC) {
1740                                         sym->st_value = ofl->
1741                                             ofl_osdynamic->os_shdr->sh_addr;
1742                                         /* LINTED */
1743                                         sectndx = elf_ndxscn(
1744                                             ofl->ofl_osdynamic->os_scn);
1745                                         sdp->sd_flags &= ~FLG_SY_SPECSEC;
1746                                 }
1747                                 break;
1748                         case SDAUX_ID_PLT:
1749                                 if (ofl->ofl_osplt) {
1750                                         sym->st_value = ofl->
1751                                             ofl_osplt->os_shdr->sh_addr;
1752                                         /* LINTED */
1753                                         sectndx = elf_ndxscn(
1754                                             ofl->ofl_osplt->os_scn);
1755                                         sdp->sd_flags &= ~FLG_SY_SPECSEC;
1756                                 }
1757                                 break;
1758                         case SDAUX_ID_GOT:
1759                                 /*
1760                                  * Symbol bias for negative growing tables is
1761                                  * stored in symbol's value during
1762                                  * allocate_got().
1763                                  */
1764                                 sym->st_value += ofl->
1765                                     ofl_osgot->os_shdr->sh_addr;
1766                                 /* LINTED */
1767                                 sectndx = elf_ndxscn(ofl->
1768                                     ofl_osgot->os_scn);
1769                                 sdp->sd_flags &= ~FLG_SY_SPECSEC;
1770                                 break;
1771                         default:
1772                                 /* NOTHING */
1773                                 ;
1774                         }
1775                 }
1776 
1777                 /*
1778                  * If a plt index has been assigned to an undefined function,
1779                  * update the symbols value to the appropriate .plt address.
1780                  */
1781                 if ((flags & FLG_OF_DYNAMIC) && (flags & FLG_OF_EXEC) &&
1782                     (sdp->sd_file) &&
1783                     (sdp->sd_file->ifl_ehdr->e_type == ET_DYN) &&
1784                     (ELF_ST_TYPE(sym->st_info) == STT_FUNC) &&
1785                     !(flags & FLG_OF_BFLAG)) {
1786                         if (sap->sa_PLTndx)
1787                                 sym->st_value =
1788                                     (*ld_targ.t_mr.mr_calc_plt_addr)(sdp, ofl);
1789                 }
1790 
1791                 /*
1792                  * Finish updating the symbols.
1793                  */
1794 
1795                 /*
1796                  * Sym Update: if scoped local - set local binding
1797                  */
1798                 if (local)
1799                         sym->st_info = ELF_ST_INFO(STB_LOCAL,
1800                             ELF_ST_TYPE(sym->st_info));
1801 
1802                 /*
1803                  * Sym Updated: If both the .symtab and .dynsym
1804                  * are present then we've actually updated the information in
1805                  * the .dynsym, therefore copy this same information to the
1806                  * .symtab entry.
1807                  */
1808                 sdp->sd_shndx = sectndx;
1809                 if (enter_in_symtab && dynsym && (!local || dynlocal)) {
1810                         Word _symndx = dynlocal ? scopesym_ndx : symtab_ndx;
1811 
1812                         symtab[_symndx].st_value = sym->st_value;
1813                         symtab[_symndx].st_size = sym->st_size;
1814                         symtab[_symndx].st_info = sym->st_info;
1815                         symtab[_symndx].st_other = sym->st_other;
1816                 }
1817 
1818                 if (enter_in_symtab) {
1819                         Word    _symndx;
1820 
1821                         if (local)
1822                                 _symndx = scopesym_ndx++;
1823                         else
1824                                 _symndx = symtab_ndx++;
1825                         if (((sdp->sd_flags & FLG_SY_SPECSEC) == 0) &&
1826                             (sectndx >= SHN_LORESERVE)) {
1827                                 assert(symshndx != NULL);
1828                                 symshndx[_symndx] = sectndx;
1829                                 symtab[_symndx].st_shndx = SHN_XINDEX;
1830                         } else {
1831                                 /* LINTED */
1832                                 symtab[_symndx].st_shndx = (Half)sectndx;
1833                         }
1834                 }
1835 
1836                 if (dynsym && (!local || dynlocal)) {
1837                         /*
1838                          * dynsym and ldynsym are distinct tables, so
1839                          * we use indirection to access the right one
1840                          * and the related extended section index array.
1841                          */
1842                         Word    _symndx;
1843                         Sym     *_dynsym;
1844                         Word    *_dynshndx;
1845 
1846                         if (!local) {
1847                                 _symndx = dynsym_ndx++;
1848                                 _dynsym = dynsym;
1849                                 _dynshndx = dynshndx;
1850                         } else {
1851                                 _symndx = ldynscopesym_ndx++;
1852                                 _dynsym = ldynsym;
1853                                 _dynshndx = ldynshndx;
1854                         }
1855                         if (((sdp->sd_flags & FLG_SY_SPECSEC) == 0) &&
1856                             (sectndx >= SHN_LORESERVE)) {
1857                                 assert(_dynshndx != NULL);
1858                                 _dynshndx[_symndx] = sectndx;
1859                                 _dynsym[_symndx].st_shndx = SHN_XINDEX;
1860                         } else {
1861                                 /* LINTED */
1862                                 _dynsym[_symndx].st_shndx = (Half)sectndx;
1863                         }
1864                 }
1865 
1866                 DBG_CALL(Dbg_syms_new(ofl, sym, sdp));
1867         }
1868 
1869         /*
1870          * Now that all the symbols have been processed update any weak symbols
1871          * information (ie. copy all information except `st_name').  As both
1872          * symbols will be represented in the output, return the weak symbol to
1873          * its correct type.
1874          */
1875         for (ALIST_TRAVERSE(weak, idx1, wkp)) {
1876                 Sym_desc        *sdp, *_sdp;
1877                 Sym             *sym, *_sym, *__sym;
1878                 uchar_t         bind;
1879 
1880                 sdp = wkp->wk_weak;
1881                 _sdp = wkp->wk_alias;
1882                 _sym = __sym = _sdp->sd_sym;
1883 
1884                 sdp->sd_flags |= FLG_SY_WEAKDEF;
1885 
1886                 /*
1887                  * If the symbol definition has been scoped then assign it to
1888                  * be local, otherwise if it's from a shared object then we need
1889                  * to maintain the binding of the original reference.
1890                  */
1891                 if (SYM_IS_HIDDEN(sdp)) {
1892                         if (flags & FLG_OF_PROCRED)
1893                                 bind = STB_LOCAL;
1894                         else
1895                                 bind = STB_WEAK;
1896                 } else if ((sdp->sd_ref == REF_DYN_NEED) &&
1897                     (sdp->sd_flags & FLG_SY_GLOBREF))
1898                         bind = STB_GLOBAL;
1899                 else
1900                         bind = STB_WEAK;
1901 
1902                 DBG_CALL(Dbg_syms_old(ofl, sdp));
1903                 if ((sym = wkp->wk_symtab) != NULL) {
1904                         sym->st_value = _sym->st_value;
1905                         sym->st_size = _sym->st_size;
1906                         sym->st_other = _sym->st_other;
1907                         sym->st_shndx = _sym->st_shndx;
1908                         sym->st_info = ELF_ST_INFO(bind,
1909                             ELF_ST_TYPE(sym->st_info));
1910                         __sym = sym;
1911                 }
1912                 if ((sym = wkp->wk_dynsym) != NULL) {
1913                         sym->st_value = _sym->st_value;
1914                         sym->st_size = _sym->st_size;
1915                         sym->st_other = _sym->st_other;
1916                         sym->st_shndx = _sym->st_shndx;
1917                         sym->st_info = ELF_ST_INFO(bind,
1918                             ELF_ST_TYPE(sym->st_info));
1919                         __sym = sym;
1920                 }
1921                 DBG_CALL(Dbg_syms_new(ofl, __sym, sdp));
1922         }
1923 
1924         /*
1925          * Now display GOT debugging information if required.
1926          */
1927         DBG_CALL(Dbg_got_display(ofl, 0, 0,
1928             ld_targ.t_m.m_got_xnumber, ld_targ.t_m.m_got_entsize));
1929 
1930         /*
1931          * Update the section headers information. sh_info is
1932          * supposed to contain the offset at which the first
1933          * global symbol resides in the symbol table, while
1934          * sh_link contains the section index of the associated
1935          * string table.
1936          */
1937         if (symtab) {
1938                 Shdr    *shdr = ofl->ofl_ossymtab->os_shdr;
1939 
1940                 shdr->sh_info = symtab_gbl_bndx;
1941                 /* LINTED */
1942                 shdr->sh_link = (Word)elf_ndxscn(ofl->ofl_osstrtab->os_scn);
1943                 if (symshndx)
1944                         ofl->ofl_ossymshndx->os_shdr->sh_link =
1945                             (Word)elf_ndxscn(ofl->ofl_ossymtab->os_scn);
1946 
1947                 /*
1948                  * Ensure that the expected number of symbols
1949                  * were entered into the right spots:
1950                  *      - Scoped symbols in the right range
1951                  *      - Globals start at the right spot
1952                  *              (correct number of locals entered)
1953                  *      - The table is exactly filled
1954                  *              (correct number of globals entered)
1955                  */
1956                 assert((scopesym_bndx + ofl->ofl_scopecnt) == scopesym_ndx);
1957                 assert(shdr->sh_info == SYMTAB_LOC_CNT(ofl));
1958                 assert((shdr->sh_info + ofl->ofl_globcnt) == symtab_ndx);
1959         }
1960         if (dynsym) {
1961                 Shdr    *shdr = ofl->ofl_osdynsym->os_shdr;
1962 
1963                 shdr->sh_info = DYNSYM_LOC_CNT(ofl);
1964                 /* LINTED */
1965                 shdr->sh_link = (Word)elf_ndxscn(ofl->ofl_osdynstr->os_scn);
1966 
1967                 ofl->ofl_oshash->os_shdr->sh_link =
1968                     /* LINTED */
1969                     (Word)elf_ndxscn(ofl->ofl_osdynsym->os_scn);
1970                 if (dynshndx) {
1971                         shdr = ofl->ofl_osdynshndx->os_shdr;
1972                         shdr->sh_link =
1973                             (Word)elf_ndxscn(ofl->ofl_osdynsym->os_scn);
1974                 }
1975         }
1976         if (ldynsym) {
1977                 Shdr    *shdr = ofl->ofl_osldynsym->os_shdr;
1978 
1979                 /* ldynsym has no globals, so give index one past the end */
1980                 shdr->sh_info = ldynsym_ndx;
1981 
1982                 /*
1983                  * The ldynsym and dynsym must be adjacent. The
1984                  * idea is that rtld should be able to start with
1985                  * the ldynsym and march straight through the end
1986                  * of dynsym, seeing them as a single symbol table,
1987                  * despite the fact that they are in distinct sections.
1988                  * Ensure that this happened correctly.
1989                  *
1990                  * Note that I use ldynsym_ndx here instead of the
1991                  * computation I used to set the section size
1992                  * (found in ldynsym_cnt). The two will agree, unless
1993                  * we somehow miscounted symbols or failed to insert them
1994                  * all. Using ldynsym_ndx here catches that error in
1995                  * addition to checking for adjacency.
1996                  */
1997                 assert(dynsym == (ldynsym + ldynsym_ndx));
1998 
1999 
2000                 /* LINTED */
2001                 shdr->sh_link = (Word)elf_ndxscn(ofl->ofl_osdynstr->os_scn);
2002 
2003                 if (ldynshndx) {
2004                         shdr = ofl->ofl_osldynshndx->os_shdr;
2005                         shdr->sh_link =
2006                             (Word)elf_ndxscn(ofl->ofl_osldynsym->os_scn);
2007                 }
2008 
2009                 /*
2010                  * The presence of .SUNW_ldynsym means that there may be
2011                  * associated sort sections, one for regular symbols
2012                  * and the other for TLS. Each sort section needs the
2013                  * following done:
2014                  *      - Section header link references .SUNW_ldynsym
2015                  *      - Should have received the expected # of items
2016                  *      - Sorted by increasing address
2017                  */
2018                 if (ofl->ofl_osdynsymsort) { /* .SUNW_dynsymsort */
2019                         ofl->ofl_osdynsymsort->os_shdr->sh_link =
2020                             (Word)elf_ndxscn(ofl->ofl_osldynsym->os_scn);
2021                         assert(ofl->ofl_dynsymsortcnt == dynsymsort_ndx);
2022 
2023                         if (dynsymsort_ndx > 1) {
2024                                 dynsort_compare_syms = ldynsym;
2025                                 qsort(dynsymsort, dynsymsort_ndx,
2026                                     sizeof (*dynsymsort), dynsort_compare);
2027                                 dynsort_dupwarn(ofl, ldynsym,
2028                                     st_getstrbuf(dynstr),
2029                                     dynsymsort, dynsymsort_ndx,
2030                                     MSG_ORIG(MSG_SCN_DYNSYMSORT));
2031                         }
2032                 }
2033                 if (ofl->ofl_osdyntlssort) { /* .SUNW_dyntlssort */
2034                         ofl->ofl_osdyntlssort->os_shdr->sh_link =
2035                             (Word)elf_ndxscn(ofl->ofl_osldynsym->os_scn);
2036                         assert(ofl->ofl_dyntlssortcnt == dyntlssort_ndx);
2037 
2038                         if (dyntlssort_ndx > 1) {
2039                                 dynsort_compare_syms = ldynsym;
2040                                 qsort(dyntlssort, dyntlssort_ndx,
2041                                     sizeof (*dyntlssort), dynsort_compare);
2042                                 dynsort_dupwarn(ofl, ldynsym,
2043                                     st_getstrbuf(dynstr),
2044                                     dyntlssort, dyntlssort_ndx,
2045                                     MSG_ORIG(MSG_SCN_DYNTLSSORT));
2046                         }
2047                 }
2048         }
2049 
2050         /*
2051          * Used by ld.so.1 only.
2052          */
2053         return (etext);
2054 
2055 #undef ADD_TO_DYNSORT
2056 }
2057 
2058 /*
2059  * Build the dynamic section.
2060  *
2061  * This routine must be maintained in parallel with make_dynamic()
2062  * in sections.c
2063  */
2064 static int
2065 update_odynamic(Ofl_desc *ofl)
2066 {
2067         Aliste          idx;
2068         Ifl_desc        *ifl;
2069         Sym_desc        *sdp;
2070         Shdr            *shdr;
2071         Dyn             *_dyn = (Dyn *)ofl->ofl_osdynamic->os_outdata->d_buf;
2072         Dyn             *dyn;
2073         Os_desc         *symosp, *strosp;
2074         Str_tbl         *strtbl;
2075         size_t          stoff;
2076         ofl_flag_t      flags = ofl->ofl_flags;
2077         int             not_relobj = !(flags & FLG_OF_RELOBJ);
2078         Word            cnt;
2079 
2080         /*
2081          * Relocatable objects can be built with -r and -dy to trigger the
2082          * creation of a .dynamic section.  This model is used to create kernel
2083          * device drivers.  The .dynamic section provides a subset of userland
2084          * .dynamic entries, typically entries such as DT_NEEDED and DT_RUNPATH.
2085          *
2086          * Within a dynamic object, any .dynamic string references are to the
2087          * .dynstr table.  Within a relocatable object, these strings can reside
2088          * within the .strtab.
2089          */
2090         if (OFL_IS_STATIC_OBJ(ofl)) {
2091                 symosp = ofl->ofl_ossymtab;
2092                 strosp = ofl->ofl_osstrtab;
2093                 strtbl = ofl->ofl_strtab;
2094         } else {
2095                 symosp = ofl->ofl_osdynsym;
2096                 strosp = ofl->ofl_osdynstr;
2097                 strtbl = ofl->ofl_dynstrtab;
2098         }
2099 
2100         /* LINTED */
2101         ofl->ofl_osdynamic->os_shdr->sh_link = (Word)elf_ndxscn(strosp->os_scn);
2102 
2103         dyn = _dyn;
2104 
2105         for (APLIST_TRAVERSE(ofl->ofl_sos, idx, ifl)) {
2106                 if ((ifl->ifl_flags &
2107                     (FLG_IF_IGNORE | FLG_IF_DEPREQD)) == FLG_IF_IGNORE)
2108                         continue;
2109 
2110                 /*
2111                  * Create and set up the DT_POSFLAG_1 entry here if required.
2112                  */
2113                 if ((ifl->ifl_flags & MSK_IF_POSFLAG1) &&
2114                     (ifl->ifl_flags & FLG_IF_NEEDED) && not_relobj) {
2115                         dyn->d_tag = DT_POSFLAG_1;
2116                         if (ifl->ifl_flags & FLG_IF_LAZYLD)
2117                                 dyn->d_un.d_val = DF_P1_LAZYLOAD;
2118                         if (ifl->ifl_flags & FLG_IF_GRPPRM)
2119                                 dyn->d_un.d_val |= DF_P1_GROUPPERM;
2120                         if (ifl->ifl_flags & FLG_IF_DEFERRED)
2121                                 dyn->d_un.d_val |= DF_P1_DEFERRED;
2122                         dyn++;
2123                 }
2124 
2125                 if (ifl->ifl_flags & (FLG_IF_NEEDED | FLG_IF_NEEDSTR))
2126                         dyn->d_tag = DT_NEEDED;
2127                 else
2128                         continue;
2129 
2130                 (void) st_setstring(strtbl, ifl->ifl_soname, &stoff);
2131                 dyn->d_un.d_val = stoff;
2132                 /* LINTED */
2133                 ifl->ifl_neededndx = (Half)(((uintptr_t)dyn - (uintptr_t)_dyn) /
2134                     sizeof (Dyn));
2135                 dyn++;
2136         }
2137 
2138         if (not_relobj) {
2139                 if (ofl->ofl_dtsfltrs != NULL) {
2140                         Dfltr_desc      *dftp;
2141 
2142                         for (ALIST_TRAVERSE(ofl->ofl_dtsfltrs, idx, dftp)) {
2143                                 if (dftp->dft_flag == FLG_SY_AUXFLTR)
2144                                         dyn->d_tag = DT_SUNW_AUXILIARY;
2145                                 else
2146                                         dyn->d_tag = DT_SUNW_FILTER;
2147 
2148                                 (void) st_setstring(strtbl, dftp->dft_str,
2149                                     &stoff);
2150                                 dyn->d_un.d_val = stoff;
2151                                 dftp->dft_ndx = (Half)(((uintptr_t)dyn -
2152                                     (uintptr_t)_dyn) / sizeof (Dyn));
2153                                 dyn++;
2154                         }
2155                 }
2156                 if (((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_INIT_U),
2157                     SYM_NOHASH, 0, ofl)) != NULL) &&
2158                     (sdp->sd_ref == REF_REL_NEED) &&
2159                     (sdp->sd_sym->st_shndx != SHN_UNDEF)) {
2160                         dyn->d_tag = DT_INIT;
2161                         dyn->d_un.d_ptr = sdp->sd_sym->st_value;
2162                         dyn++;
2163                 }
2164                 if (((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_FINI_U),
2165                     SYM_NOHASH, 0, ofl)) != NULL) &&
2166                     (sdp->sd_ref == REF_REL_NEED) &&
2167                     (sdp->sd_sym->st_shndx != SHN_UNDEF)) {
2168                         dyn->d_tag = DT_FINI;
2169                         dyn->d_un.d_ptr = sdp->sd_sym->st_value;
2170                         dyn++;
2171                 }
2172                 if (ofl->ofl_soname) {
2173                         dyn->d_tag = DT_SONAME;
2174                         (void) st_setstring(strtbl, ofl->ofl_soname, &stoff);
2175                         dyn->d_un.d_val = stoff;
2176                         dyn++;
2177                 }
2178                 if (ofl->ofl_filtees) {
2179                         if (flags & FLG_OF_AUX) {
2180                                 dyn->d_tag = DT_AUXILIARY;
2181                         } else {
2182                                 dyn->d_tag = DT_FILTER;
2183                         }
2184                         (void) st_setstring(strtbl, ofl->ofl_filtees, &stoff);
2185                         dyn->d_un.d_val = stoff;
2186                         dyn++;
2187                 }
2188         }
2189 
2190         if (ofl->ofl_rpath) {
2191                 (void) st_setstring(strtbl, ofl->ofl_rpath, &stoff);
2192                 dyn->d_tag = DT_RUNPATH;
2193                 dyn->d_un.d_val = stoff;
2194                 dyn++;
2195                 dyn->d_tag = DT_RPATH;
2196                 dyn->d_un.d_val = stoff;
2197                 dyn++;
2198         }
2199 
2200         if (not_relobj) {
2201                 Aliste  idx;
2202                 Sg_desc *sgp;
2203 
2204                 if (ofl->ofl_config) {
2205                         dyn->d_tag = DT_CONFIG;
2206                         (void) st_setstring(strtbl, ofl->ofl_config, &stoff);
2207                         dyn->d_un.d_val = stoff;
2208                         dyn++;
2209                 }
2210                 if (ofl->ofl_depaudit) {
2211                         dyn->d_tag = DT_DEPAUDIT;
2212                         (void) st_setstring(strtbl, ofl->ofl_depaudit, &stoff);
2213                         dyn->d_un.d_val = stoff;
2214                         dyn++;
2215                 }
2216                 if (ofl->ofl_audit) {
2217                         dyn->d_tag = DT_AUDIT;
2218                         (void) st_setstring(strtbl, ofl->ofl_audit, &stoff);
2219                         dyn->d_un.d_val = stoff;
2220                         dyn++;
2221                 }
2222 
2223                 dyn->d_tag = DT_HASH;
2224                 dyn->d_un.d_ptr = ofl->ofl_oshash->os_shdr->sh_addr;
2225                 dyn++;
2226 
2227                 shdr = strosp->os_shdr;
2228                 dyn->d_tag = DT_STRTAB;
2229                 dyn->d_un.d_ptr = shdr->sh_addr;
2230                 dyn++;
2231 
2232                 dyn->d_tag = DT_STRSZ;
2233                 dyn->d_un.d_ptr = shdr->sh_size;
2234                 dyn++;
2235 
2236                 /*
2237                  * Note, the shdr is set and used in the ofl->ofl_osldynsym case
2238                  * that follows.
2239                  */
2240                 shdr = symosp->os_shdr;
2241                 dyn->d_tag = DT_SYMTAB;
2242                 dyn->d_un.d_ptr = shdr->sh_addr;
2243                 dyn++;
2244 
2245                 dyn->d_tag = DT_SYMENT;
2246                 dyn->d_un.d_ptr = shdr->sh_entsize;
2247                 dyn++;
2248 
2249                 if (ofl->ofl_osldynsym) {
2250                         Shdr    *lshdr = ofl->ofl_osldynsym->os_shdr;
2251 
2252                         /*
2253                          * We have arranged for the .SUNW_ldynsym data to be
2254                          * immediately in front of the .dynsym data.
2255                          * This means that you could start at the top
2256                          * of .SUNW_ldynsym and see the data for both tables
2257                          * without a break. This is the view we want to
2258                          * provide for DT_SUNW_SYMTAB, which is why we
2259                          * add the lengths together.
2260                          */
2261                         dyn->d_tag = DT_SUNW_SYMTAB;
2262                         dyn->d_un.d_ptr = lshdr->sh_addr;
2263                         dyn++;
2264 
2265                         dyn->d_tag = DT_SUNW_SYMSZ;
2266                         dyn->d_un.d_val = lshdr->sh_size + shdr->sh_size;
2267                         dyn++;
2268                 }
2269 
2270                 if (ofl->ofl_osdynsymsort || ofl->ofl_osdyntlssort) {
2271                         dyn->d_tag = DT_SUNW_SORTENT;
2272                         dyn->d_un.d_val = sizeof (Word);
2273                         dyn++;
2274                 }
2275 
2276                 if (ofl->ofl_osdynsymsort) {
2277                         shdr = ofl->ofl_osdynsymsort->os_shdr;
2278 
2279                         dyn->d_tag = DT_SUNW_SYMSORT;
2280                         dyn->d_un.d_ptr = shdr->sh_addr;
2281                         dyn++;
2282 
2283                         dyn->d_tag = DT_SUNW_SYMSORTSZ;
2284                         dyn->d_un.d_val = shdr->sh_size;
2285                         dyn++;
2286                 }
2287 
2288                 if (ofl->ofl_osdyntlssort) {
2289                         shdr = ofl->ofl_osdyntlssort->os_shdr;
2290 
2291                         dyn->d_tag = DT_SUNW_TLSSORT;
2292                         dyn->d_un.d_ptr = shdr->sh_addr;
2293                         dyn++;
2294 
2295                         dyn->d_tag = DT_SUNW_TLSSORTSZ;
2296                         dyn->d_un.d_val = shdr->sh_size;
2297                         dyn++;
2298                 }
2299 
2300                 /*
2301                  * Reserve the DT_CHECKSUM entry.  Its value will be filled in
2302                  * after the complete image is built.
2303                  */
2304                 dyn->d_tag = DT_CHECKSUM;
2305                 ofl->ofl_checksum = &dyn->d_un.d_val;
2306                 dyn++;
2307 
2308                 /*
2309                  * Versioning sections: DT_VERDEF and DT_VERNEED.
2310                  *
2311                  * The Solaris ld does not produce DT_VERSYM, but the GNU ld
2312                  * does, in order to support their style of versioning, which
2313                  * differs from ours:
2314                  *
2315                  *      - The top bit of the 16-bit Versym index is
2316                  *              not part of the version, but is interpreted
2317                  *              as a "hidden bit".
2318                  *
2319                  *      - External (SHN_UNDEF) symbols can have non-zero
2320                  *              Versym values, which specify versions in
2321                  *              referenced objects, via the Verneed section.
2322                  *
2323                  *      - The vna_other field of the Vernaux structures
2324                  *              found in the Verneed section are not zero as
2325                  *              with Solaris, but instead contain the version
2326                  *              index to be used by Versym indices to reference
2327                  *              the given external version.
2328                  *
2329                  * The Solaris ld, rtld, and elfdump programs all interpret the
2330                  * presence of DT_VERSYM as meaning that GNU versioning rules
2331                  * apply to the given file. If DT_VERSYM is not present,
2332                  * then Solaris versioning rules apply. If we should ever need
2333                  * to change our ld so that it does issue DT_VERSYM, then
2334                  * this rule for detecting GNU versioning will no longer work.
2335                  * In that case, we will have to invent a way to explicitly
2336                  * specify the style of versioning in use, perhaps via a
2337                  * new dynamic entry named something like DT_SUNW_VERSIONSTYLE,
2338                  * where the d_un.d_val value specifies which style is to be
2339                  * used.
2340                  */
2341                 if ((flags & (FLG_OF_VERDEF | FLG_OF_NOVERSEC)) ==
2342                     FLG_OF_VERDEF) {
2343                         shdr = ofl->ofl_osverdef->os_shdr;
2344 
2345                         dyn->d_tag = DT_VERDEF;
2346                         dyn->d_un.d_ptr = shdr->sh_addr;
2347                         dyn++;
2348                         dyn->d_tag = DT_VERDEFNUM;
2349                         dyn->d_un.d_ptr = shdr->sh_info;
2350                         dyn++;
2351                 }
2352                 if ((flags & (FLG_OF_VERNEED | FLG_OF_NOVERSEC)) ==
2353                     FLG_OF_VERNEED) {
2354                         shdr = ofl->ofl_osverneed->os_shdr;
2355 
2356                         dyn->d_tag = DT_VERNEED;
2357                         dyn->d_un.d_ptr = shdr->sh_addr;
2358                         dyn++;
2359                         dyn->d_tag = DT_VERNEEDNUM;
2360                         dyn->d_un.d_ptr = shdr->sh_info;
2361                         dyn++;
2362                 }
2363 
2364                 if ((flags & FLG_OF_COMREL) && ofl->ofl_relocrelcnt) {
2365                         dyn->d_tag = ld_targ.t_m.m_rel_dt_count;
2366                         dyn->d_un.d_val = ofl->ofl_relocrelcnt;
2367                         dyn++;
2368                 }
2369                 if (flags & FLG_OF_TEXTREL) {
2370                         /*
2371                          * Only the presence of this entry is used in this
2372                          * implementation, not the value stored.
2373                          */
2374                         dyn->d_tag = DT_TEXTREL;
2375                         dyn->d_un.d_val = 0;
2376                         dyn++;
2377                 }
2378 
2379                 if (ofl->ofl_osfiniarray) {
2380                         shdr = ofl->ofl_osfiniarray->os_shdr;
2381 
2382                         dyn->d_tag = DT_FINI_ARRAY;
2383                         dyn->d_un.d_ptr = shdr->sh_addr;
2384                         dyn++;
2385 
2386                         dyn->d_tag = DT_FINI_ARRAYSZ;
2387                         dyn->d_un.d_val = shdr->sh_size;
2388                         dyn++;
2389                 }
2390 
2391                 if (ofl->ofl_osinitarray) {
2392                         shdr = ofl->ofl_osinitarray->os_shdr;
2393 
2394                         dyn->d_tag = DT_INIT_ARRAY;
2395                         dyn->d_un.d_ptr = shdr->sh_addr;
2396                         dyn++;
2397 
2398                         dyn->d_tag = DT_INIT_ARRAYSZ;
2399                         dyn->d_un.d_val = shdr->sh_size;
2400                         dyn++;
2401                 }
2402 
2403                 if (ofl->ofl_ospreinitarray) {
2404                         shdr = ofl->ofl_ospreinitarray->os_shdr;
2405 
2406                         dyn->d_tag = DT_PREINIT_ARRAY;
2407                         dyn->d_un.d_ptr = shdr->sh_addr;
2408                         dyn++;
2409 
2410                         dyn->d_tag = DT_PREINIT_ARRAYSZ;
2411                         dyn->d_un.d_val = shdr->sh_size;
2412                         dyn++;
2413                 }
2414 
2415                 if (ofl->ofl_pltcnt) {
2416                         shdr = ofl->ofl_osplt->os_relosdesc->os_shdr;
2417 
2418                         dyn->d_tag = DT_PLTRELSZ;
2419                         dyn->d_un.d_ptr = shdr->sh_size;
2420                         dyn++;
2421                         dyn->d_tag = DT_PLTREL;
2422                         dyn->d_un.d_ptr = ld_targ.t_m.m_rel_dt_type;
2423                         dyn++;
2424                         dyn->d_tag = DT_JMPREL;
2425                         dyn->d_un.d_ptr = shdr->sh_addr;
2426                         dyn++;
2427                 }
2428                 if (ofl->ofl_pltpad) {
2429                         shdr = ofl->ofl_osplt->os_shdr;
2430 
2431                         dyn->d_tag = DT_PLTPAD;
2432                         if (ofl->ofl_pltcnt) {
2433                                 dyn->d_un.d_ptr = shdr->sh_addr +
2434                                     ld_targ.t_m.m_plt_reservsz +
2435                                     ofl->ofl_pltcnt * ld_targ.t_m.m_plt_entsize;
2436                         } else
2437                                 dyn->d_un.d_ptr = shdr->sh_addr;
2438                         dyn++;
2439                         dyn->d_tag = DT_PLTPADSZ;
2440                         dyn->d_un.d_val = ofl->ofl_pltpad *
2441                             ld_targ.t_m.m_plt_entsize;
2442                         dyn++;
2443                 }
2444                 if (ofl->ofl_relocsz) {
2445                         shdr = ofl->ofl_osrelhead->os_shdr;
2446 
2447                         dyn->d_tag = ld_targ.t_m.m_rel_dt_type;
2448                         dyn->d_un.d_ptr = shdr->sh_addr;
2449                         dyn++;
2450                         dyn->d_tag = ld_targ.t_m.m_rel_dt_size;
2451                         dyn->d_un.d_ptr = ofl->ofl_relocsz;
2452                         dyn++;
2453                         dyn->d_tag = ld_targ.t_m.m_rel_dt_ent;
2454                         if (shdr->sh_type == SHT_REL)
2455                                 dyn->d_un.d_ptr = sizeof (Rel);
2456                         else
2457                                 dyn->d_un.d_ptr = sizeof (Rela);
2458                         dyn++;
2459                 }
2460                 if (ofl->ofl_ossyminfo) {
2461                         shdr = ofl->ofl_ossyminfo->os_shdr;
2462 
2463                         dyn->d_tag = DT_SYMINFO;
2464                         dyn->d_un.d_ptr = shdr->sh_addr;
2465                         dyn++;
2466                         dyn->d_tag = DT_SYMINSZ;
2467                         dyn->d_un.d_val = shdr->sh_size;
2468                         dyn++;
2469                         dyn->d_tag = DT_SYMINENT;
2470                         dyn->d_un.d_val = sizeof (Syminfo);
2471                         dyn++;
2472                 }
2473                 if (ofl->ofl_osmove) {
2474                         shdr = ofl->ofl_osmove->os_shdr;
2475 
2476                         dyn->d_tag = DT_MOVETAB;
2477                         dyn->d_un.d_val = shdr->sh_addr;
2478                         dyn++;
2479                         dyn->d_tag = DT_MOVESZ;
2480                         dyn->d_un.d_val = shdr->sh_size;
2481                         dyn++;
2482                         dyn->d_tag = DT_MOVEENT;
2483                         dyn->d_un.d_val = shdr->sh_entsize;
2484                         dyn++;
2485                 }
2486                 if (ofl->ofl_regsymcnt) {
2487                         int     ndx;
2488 
2489                         for (ndx = 0; ndx < ofl->ofl_regsymsno; ndx++) {
2490                                 if ((sdp = ofl->ofl_regsyms[ndx]) == NULL)
2491                                         continue;
2492 
2493                                 dyn->d_tag = ld_targ.t_m.m_dt_register;
2494                                 dyn->d_un.d_val = sdp->sd_symndx;
2495                                 dyn++;
2496                         }
2497                 }
2498 
2499                 for (APLIST_TRAVERSE(ofl->ofl_rtldinfo, idx, sdp)) {
2500                         dyn->d_tag = DT_SUNW_RTLDINF;
2501                         dyn->d_un.d_ptr = sdp->sd_sym->st_value;
2502                         dyn++;
2503                 }
2504 
2505                 if (((sgp = ofl->ofl_osdynamic->os_sgdesc) != NULL) &&
2506                     (sgp->sg_phdr.p_flags & PF_W) && ofl->ofl_osinterp) {
2507                         dyn->d_tag = DT_DEBUG;
2508                         dyn->d_un.d_ptr = 0;
2509                         dyn++;
2510                 }
2511 
2512                 if (ofl->ofl_oscap) {
2513                         dyn->d_tag = DT_SUNW_CAP;
2514                         dyn->d_un.d_val = ofl->ofl_oscap->os_shdr->sh_addr;
2515                         dyn++;
2516                 }
2517                 if (ofl->ofl_oscapinfo) {
2518                         dyn->d_tag = DT_SUNW_CAPINFO;
2519                         dyn->d_un.d_val = ofl->ofl_oscapinfo->os_shdr->sh_addr;
2520                         dyn++;
2521                 }
2522                 if (ofl->ofl_oscapchain) {
2523                         shdr = ofl->ofl_oscapchain->os_shdr;
2524 
2525                         dyn->d_tag = DT_SUNW_CAPCHAIN;
2526                         dyn->d_un.d_val = shdr->sh_addr;
2527                         dyn++;
2528                         dyn->d_tag = DT_SUNW_CAPCHAINSZ;
2529                         dyn->d_un.d_val = shdr->sh_size;
2530                         dyn++;
2531                         dyn->d_tag = DT_SUNW_CAPCHAINENT;
2532                         dyn->d_un.d_val = shdr->sh_entsize;
2533                         dyn++;
2534                 }
2535                 if (flags & FLG_OF_SYMBOLIC) {
2536                         dyn->d_tag = DT_SYMBOLIC;
2537                         dyn->d_un.d_val = 0;
2538                         dyn++;
2539                 }
2540         }
2541 
2542         dyn->d_tag = DT_FLAGS;
2543         dyn->d_un.d_val = ofl->ofl_dtflags;
2544         dyn++;
2545 
2546         /*
2547          * If -Bdirect was specified, but some NODIRECT symbols were specified
2548          * via a mapfile, or -znodirect was used on the command line, then
2549          * clear the DF_1_DIRECT flag.  The resultant object will use per-symbol
2550          * direct bindings rather than be enabled for global direct bindings.
2551          *
2552          * If any no-direct bindings exist within this object, set the
2553          * DF_1_NODIRECT flag.  ld(1) recognizes this flag when processing
2554          * dependencies, and performs extra work to ensure that no direct
2555          * bindings are established to the no-direct symbols that exist
2556          * within these dependencies.
2557          */
2558         if (ofl->ofl_flags1 & FLG_OF1_NGLBDIR)
2559                 ofl->ofl_dtflags_1 &= ~DF_1_DIRECT;
2560         if (ofl->ofl_flags1 & FLG_OF1_NDIRECT)
2561                 ofl->ofl_dtflags_1 |= DF_1_NODIRECT;
2562 
2563         dyn->d_tag = DT_FLAGS_1;
2564         dyn->d_un.d_val = ofl->ofl_dtflags_1;
2565         dyn++;
2566 
2567         dyn->d_tag = DT_SUNW_STRPAD;
2568         dyn->d_un.d_val = DYNSTR_EXTRA_PAD;
2569         dyn++;
2570 
2571         dyn->d_tag = DT_SUNW_LDMACH;
2572         dyn->d_un.d_val = ld_sunw_ldmach();
2573         dyn++;
2574 
2575         (*ld_targ.t_mr.mr_mach_update_odynamic)(ofl, &dyn);
2576 
2577         for (cnt = 1 + DYNAMIC_EXTRA_ELTS; cnt--; dyn++) {
2578                 dyn->d_tag = DT_NULL;
2579                 dyn->d_un.d_val = 0;
2580         }
2581 
2582         /*
2583          * Ensure that we wrote the right number of entries. If not, we either
2584          * miscounted in make_dynamic(), or we did something wrong in this
2585          * function.
2586          */
2587         assert((ofl->ofl_osdynamic->os_shdr->sh_size /
2588             ofl->ofl_osdynamic->os_shdr->sh_entsize) ==
2589             ((uintptr_t)dyn - (uintptr_t)_dyn) / sizeof (*dyn));
2590 
2591         return (1);
2592 }
2593 
2594 /*
2595  * Build the version definition section
2596  */
2597 static int
2598 update_overdef(Ofl_desc *ofl)
2599 {
2600         Aliste          idx1;
2601         Ver_desc        *vdp, *_vdp;
2602         Verdef          *vdf, *_vdf;
2603         int             num = 0;
2604         Os_desc         *strosp;
2605         Str_tbl         *strtbl;
2606 
2607         /*
2608          * Determine which string table to use.
2609          */
2610         if (OFL_IS_STATIC_OBJ(ofl)) {
2611                 strtbl = ofl->ofl_strtab;
2612                 strosp = ofl->ofl_osstrtab;
2613         } else {
2614                 strtbl = ofl->ofl_dynstrtab;
2615                 strosp = ofl->ofl_osdynstr;
2616         }
2617 
2618         /*
2619          * Traverse the version descriptors and update the version structures
2620          * to point to the dynstr name in preparation for building the version
2621          * section structure.
2622          */
2623         for (APLIST_TRAVERSE(ofl->ofl_verdesc, idx1, vdp)) {
2624                 Sym_desc        *sdp;
2625 
2626                 if (vdp->vd_flags & VER_FLG_BASE) {
2627                         const char      *name = vdp->vd_name;
2628                         size_t          stoff;
2629 
2630                         /*
2631                          * Create a new string table entry to represent the base
2632                          * version name (there is no corresponding symbol for
2633                          * this).
2634                          */
2635                         (void) st_setstring(strtbl, name, &stoff);
2636                         /* LINTED */
2637                         vdp->vd_name = (const char *)stoff;
2638                 } else {
2639                         sdp = ld_sym_find(vdp->vd_name, vdp->vd_hash, 0, ofl);
2640                         /* LINTED */
2641                         vdp->vd_name = (const char *)
2642                             (uintptr_t)sdp->sd_sym->st_name;
2643                 }
2644         }
2645 
2646         _vdf = vdf = (Verdef *)ofl->ofl_osverdef->os_outdata->d_buf;
2647 
2648         /*
2649          * Traverse the version descriptors and update the version section to
2650          * reflect each version and its associated dependencies.
2651          */
2652         for (APLIST_TRAVERSE(ofl->ofl_verdesc, idx1, vdp)) {
2653                 Aliste          idx2;
2654                 Half            cnt = 1;
2655                 Verdaux         *vdap, *_vdap;
2656 
2657                 _vdap = vdap = (Verdaux *)(vdf + 1);
2658 
2659                 vdf->vd_version = VER_DEF_CURRENT;
2660                 vdf->vd_flags        = vdp->vd_flags & MSK_VER_USER;
2661                 vdf->vd_ndx  = vdp->vd_ndx;
2662                 vdf->vd_hash = vdp->vd_hash;
2663 
2664                 /* LINTED */
2665                 vdap->vda_name = (uintptr_t)vdp->vd_name;
2666                 vdap++;
2667                 /* LINTED */
2668                 _vdap->vda_next = (Word)((uintptr_t)vdap - (uintptr_t)_vdap);
2669 
2670                 /*
2671                  * Traverse this versions dependency list generating the
2672                  * appropriate version dependency entries.
2673                  */
2674                 for (APLIST_TRAVERSE(vdp->vd_deps, idx2, _vdp)) {
2675                         /* LINTED */
2676                         vdap->vda_name = (uintptr_t)_vdp->vd_name;
2677                         _vdap = vdap;
2678                         vdap++, cnt++;
2679                         /* LINTED */
2680                         _vdap->vda_next = (Word)((uintptr_t)vdap -
2681                             (uintptr_t)_vdap);
2682                 }
2683                 _vdap->vda_next = 0;
2684 
2685                 /*
2686                  * Record the versions auxiliary array offset and the associated
2687                  * dependency count.
2688                  */
2689                 /* LINTED */
2690                 vdf->vd_aux = (Word)((uintptr_t)(vdf + 1) - (uintptr_t)vdf);
2691                 vdf->vd_cnt = cnt;
2692 
2693                 /*
2694                  * Record the next versions offset and update the version
2695                  * pointer.  Remember the previous version offset as the very
2696                  * last structures next pointer should be null.
2697                  */
2698                 _vdf = vdf;
2699                 vdf = (Verdef *)vdap, num++;
2700                 /* LINTED */
2701                 _vdf->vd_next = (Word)((uintptr_t)vdf - (uintptr_t)_vdf);
2702         }
2703         _vdf->vd_next = 0;
2704 
2705         /*
2706          * Record the string table association with the version definition
2707          * section, and the symbol table associated with the version symbol
2708          * table (the actual contents of the version symbol table are filled
2709          * in during symbol update).
2710          */
2711         /* LINTED */
2712         ofl->ofl_osverdef->os_shdr->sh_link = (Word)elf_ndxscn(strosp->os_scn);
2713 
2714         /*
2715          * The version definition sections `info' field is used to indicate the
2716          * number of entries in this section.
2717          */
2718         ofl->ofl_osverdef->os_shdr->sh_info = num;
2719 
2720         return (1);
2721 }
2722 
2723 /*
2724  * Finish the version symbol index section
2725  */
2726 static void
2727 update_oversym(Ofl_desc *ofl)
2728 {
2729         Os_desc         *osp;
2730 
2731         /*
2732          * Record the symbol table associated with the version symbol table.
2733          * The contents of the version symbol table are filled in during
2734          * symbol update.
2735          */
2736         if (OFL_IS_STATIC_OBJ(ofl))
2737                 osp = ofl->ofl_ossymtab;
2738         else
2739                 osp = ofl->ofl_osdynsym;
2740 
2741         /* LINTED */
2742         ofl->ofl_osversym->os_shdr->sh_link = (Word)elf_ndxscn(osp->os_scn);
2743 }
2744 
2745 /*
2746  * Build the version needed section
2747  */
2748 static int
2749 update_overneed(Ofl_desc *ofl)
2750 {
2751         Aliste          idx1;
2752         Ifl_desc        *ifl;
2753         Verneed         *vnd, *_vnd;
2754         Os_desc         *strosp;
2755         Str_tbl         *strtbl;
2756         Word            num = 0;
2757 
2758         _vnd = vnd = (Verneed *)ofl->ofl_osverneed->os_outdata->d_buf;
2759 
2760         /*
2761          * Determine which string table is appropriate.
2762          */
2763         if (OFL_IS_STATIC_OBJ(ofl)) {
2764                 strosp = ofl->ofl_osstrtab;
2765                 strtbl = ofl->ofl_strtab;
2766         } else {
2767                 strosp = ofl->ofl_osdynstr;
2768                 strtbl = ofl->ofl_dynstrtab;
2769         }
2770 
2771         /*
2772          * Traverse the shared object list looking for dependencies that have
2773          * versions defined within them.
2774          */
2775         for (APLIST_TRAVERSE(ofl->ofl_sos, idx1, ifl)) {
2776                 Half            _cnt;
2777                 Word            cnt = 0;
2778                 Vernaux         *_vnap, *vnap;
2779                 size_t          stoff;
2780 
2781                 if (!(ifl->ifl_flags & FLG_IF_VERNEED))
2782                         continue;
2783 
2784                 vnd->vn_version = VER_NEED_CURRENT;
2785 
2786                 (void) st_setstring(strtbl, ifl->ifl_soname, &stoff);
2787                 vnd->vn_file = stoff;
2788 
2789                 _vnap = vnap = (Vernaux *)(vnd + 1);
2790 
2791                 /*
2792                  * Traverse the version index list recording
2793                  * each version as a needed dependency.
2794                  */
2795                 for (_cnt = 0; _cnt <= ifl->ifl_vercnt; _cnt++) {
2796                         Ver_index       *vip = &ifl->ifl_verndx[_cnt];
2797 
2798                         if (vip->vi_flags & FLG_VER_REFER) {
2799                                 (void) st_setstring(strtbl, vip->vi_name,
2800                                     &stoff);
2801                                 vnap->vna_name = stoff;
2802 
2803                                 if (vip->vi_desc) {
2804                                         vnap->vna_hash = vip->vi_desc->vd_hash;
2805                                         vnap->vna_flags =
2806                                             vip->vi_desc->vd_flags;
2807                                 } else {
2808                                         vnap->vna_hash = 0;
2809                                         vnap->vna_flags = 0;
2810                                 }
2811                                 vnap->vna_other = vip->vi_overndx;
2812 
2813                                 /*
2814                                  * If version A inherits version B, then
2815                                  * B is implicit in A. It suffices for ld.so.1
2816                                  * to verify A at runtime and skip B. The
2817                                  * version normalization process sets the INFO
2818                                  * flag for the versions we want ld.so.1 to
2819                                  * skip.
2820                                  */
2821                                 if (vip->vi_flags & VER_FLG_INFO)
2822                                         vnap->vna_flags |= VER_FLG_INFO;
2823 
2824                                 _vnap = vnap;
2825                                 vnap++, cnt++;
2826                                 _vnap->vna_next =
2827                                     /* LINTED */
2828                                     (Word)((uintptr_t)vnap - (uintptr_t)_vnap);
2829                         }
2830                 }
2831 
2832                 _vnap->vna_next = 0;
2833 
2834                 /*
2835                  * Record the versions auxiliary array offset and
2836                  * the associated dependency count.
2837                  */
2838                 /* LINTED */
2839                 vnd->vn_aux = (Word)((uintptr_t)(vnd + 1) - (uintptr_t)vnd);
2840                 /* LINTED */
2841                 vnd->vn_cnt = (Half)cnt;
2842 
2843                 /*
2844                  * Record the next versions offset and update the version
2845                  * pointer.  Remember the previous version offset as the very
2846                  * last structures next pointer should be null.
2847                  */
2848                 _vnd = vnd;
2849                 vnd = (Verneed *)vnap, num++;
2850                 /* LINTED */
2851                 _vnd->vn_next = (Word)((uintptr_t)vnd - (uintptr_t)_vnd);
2852         }
2853         _vnd->vn_next = 0;
2854 
2855         /*
2856          * Use sh_link to record the associated string table section, and
2857          * sh_info to indicate the number of entries contained in the section.
2858          */
2859         /* LINTED */
2860         ofl->ofl_osverneed->os_shdr->sh_link = (Word)elf_ndxscn(strosp->os_scn);
2861         ofl->ofl_osverneed->os_shdr->sh_info = num;
2862 
2863         return (1);
2864 }
2865 
2866 /*
2867  * Update syminfo section.
2868  */
2869 static uintptr_t
2870 update_osyminfo(Ofl_desc *ofl)
2871 {
2872         Os_desc         *symosp, *infosp = ofl->ofl_ossyminfo;
2873         Syminfo         *sip = infosp->os_outdata->d_buf;
2874         Shdr            *shdr = infosp->os_shdr;
2875         char            *strtab;
2876         Aliste          idx;
2877         Sym_desc        *sdp;
2878         Sfltr_desc      *sftp;
2879 
2880         if (ofl->ofl_flags & FLG_OF_RELOBJ) {
2881                 symosp = ofl->ofl_ossymtab;
2882                 strtab = ofl->ofl_osstrtab->os_outdata->d_buf;
2883         } else {
2884                 symosp = ofl->ofl_osdynsym;
2885                 strtab = ofl->ofl_osdynstr->os_outdata->d_buf;
2886         }
2887 
2888         /* LINTED */
2889         infosp->os_shdr->sh_link = (Word)elf_ndxscn(symosp->os_scn);
2890         if (ofl->ofl_osdynamic)
2891                 infosp->os_shdr->sh_info =
2892                     /* LINTED */
2893                     (Word)elf_ndxscn(ofl->ofl_osdynamic->os_scn);
2894 
2895         /*
2896          * Update any references with the index into the dynamic table.
2897          */
2898         for (APLIST_TRAVERSE(ofl->ofl_symdtent, idx, sdp))
2899                 sip[sdp->sd_symndx].si_boundto = sdp->sd_file->ifl_neededndx;
2900 
2901         /*
2902          * Update any filtee references with the index into the dynamic table.
2903          */
2904         for (ALIST_TRAVERSE(ofl->ofl_symfltrs, idx, sftp)) {
2905                 Dfltr_desc      *dftp;
2906 
2907                 dftp = alist_item(ofl->ofl_dtsfltrs, sftp->sft_idx);
2908                 sip[sftp->sft_sdp->sd_symndx].si_boundto = dftp->dft_ndx;
2909         }
2910 
2911         /*
2912          * Display debugging information about section.
2913          */
2914         DBG_CALL(Dbg_syminfo_title(ofl->ofl_lml));
2915         if (DBG_ENABLED) {
2916                 Word    _cnt, cnt = shdr->sh_size / shdr->sh_entsize;
2917                 Sym     *symtab = symosp->os_outdata->d_buf;
2918                 Dyn     *dyn;
2919 
2920                 if (ofl->ofl_osdynamic)
2921                         dyn = ofl->ofl_osdynamic->os_outdata->d_buf;
2922                 else
2923                         dyn = NULL;
2924 
2925                 for (_cnt = 1; _cnt < cnt; _cnt++) {
2926                         if (sip[_cnt].si_flags || sip[_cnt].si_boundto)
2927                                 /* LINTED */
2928                                 DBG_CALL(Dbg_syminfo_entry(ofl->ofl_lml, _cnt,
2929                                     &sip[_cnt], &symtab[_cnt], strtab, dyn));
2930                 }
2931         }
2932         return (1);
2933 }
2934 
2935 /*
2936  * Build the output elf header.
2937  */
2938 static uintptr_t
2939 update_oehdr(Ofl_desc * ofl)
2940 {
2941         Ehdr    *ehdr = ofl->ofl_nehdr;
2942 
2943         /*
2944          * If an entry point symbol has already been established (refer
2945          * sym_validate()) simply update the elf header entry point with the
2946          * symbols value.  If no entry point is defined it will have been filled
2947          * with the start address of the first section within the text segment
2948          * (refer update_outfile()).
2949          */
2950         if (ofl->ofl_entry)
2951                 ehdr->e_entry =
2952                     ((Sym_desc *)(ofl->ofl_entry))->sd_sym->st_value;
2953 
2954         ehdr->e_ident[EI_DATA] = ld_targ.t_m.m_data;
2955         ehdr->e_version = ofl->ofl_dehdr->e_version;
2956 
2957         /*
2958          * When generating a relocatable object under -z symbolcap, set the
2959          * e_machine to be generic, and remove any e_flags.  Input relocatable
2960          * objects may identify alternative e_machine (m.machplus) and e_flags
2961          * values.  However, the functions within the created output object
2962          * are selected at runtime using the capabilities mechanism, which
2963          * supersedes the e-machine and e_flags information.  Therefore,
2964          * e_machine and e_flag values are not propagated to the output object,
2965          * as these values might prevent the kernel from loading the object
2966          * before the runtime linker gets control.
2967          */
2968         if (ofl->ofl_flags & FLG_OF_OTOSCAP) {
2969                 ehdr->e_machine = ld_targ.t_m.m_mach;
2970                 ehdr->e_flags = 0;
2971         } else {
2972                 /*
2973                  * Note. it may be necessary to update the e_flags field in the
2974                  * machine dependent section.
2975                  */
2976                 ehdr->e_machine = ofl->ofl_dehdr->e_machine;
2977                 ehdr->e_flags = ofl->ofl_dehdr->e_flags;
2978 
2979                 if (ehdr->e_machine != ld_targ.t_m.m_mach) {
2980                         if (ehdr->e_machine != ld_targ.t_m.m_machplus)
2981                                 return (S_ERROR);
2982                         if ((ehdr->e_flags & ld_targ.t_m.m_flagsplus) == 0)
2983                                 return (S_ERROR);
2984                 }
2985         }
2986 
2987         if (ofl->ofl_flags & FLG_OF_SHAROBJ)
2988                 ehdr->e_type = ET_DYN;
2989         else if (ofl->ofl_flags & FLG_OF_RELOBJ)
2990                 ehdr->e_type = ET_REL;
2991         else
2992                 ehdr->e_type = ET_EXEC;
2993 
2994         return (1);
2995 }
2996 
2997 /*
2998  * Perform move table expansion.
2999  */
3000 static void
3001 expand_move(Ofl_desc *ofl, Sym_desc *sdp, Move *mvp)
3002 {
3003         Os_desc         *osp;
3004         uchar_t         *taddr, *taddr0;
3005         Sxword          offset;
3006         Half            cnt;
3007         uint_t          stride;
3008 
3009         osp = ofl->ofl_isparexpn->is_osdesc;
3010         offset = sdp->sd_sym->st_value - osp->os_shdr->sh_addr;
3011 
3012         taddr0 = taddr = osp->os_outdata->d_buf;
3013         taddr += offset;
3014         taddr = taddr + mvp->m_poffset;
3015 
3016         for (cnt = 0; cnt < mvp->m_repeat; cnt++) {
3017                 /* LINTED */
3018                 DBG_CALL(Dbg_move_expand(ofl->ofl_lml, mvp,
3019                     (Addr)(taddr - taddr0)));
3020                 stride = (uint_t)mvp->m_stride + 1;
3021 
3022                 /*
3023                  * Update the target address based upon the move entry size.
3024                  * This size was validated in ld_process_move().
3025                  */
3026                 /* LINTED */
3027                 switch (ELF_M_SIZE(mvp->m_info)) {
3028                 case 1:
3029                         /* LINTED */
3030                         *taddr = (uchar_t)mvp->m_value;
3031                         taddr += stride;
3032                         break;
3033                 case 2:
3034                         /* LINTED */
3035                         *((Half *)taddr) = (Half)mvp->m_value;
3036                         taddr += 2 * stride;
3037                         break;
3038                 case 4:
3039                         /* LINTED */
3040                         *((Word *)taddr) = (Word)mvp->m_value;
3041                         taddr += 4 * stride;
3042                         break;
3043                 case 8:
3044                         /* LINTED */
3045                         *((u_longlong_t *)taddr) = mvp->m_value;
3046                         taddr += 8 * stride;
3047                         break;
3048                 }
3049         }
3050 }
3051 
3052 /*
3053  * Update Move sections.
3054  */
3055 static void
3056 update_move(Ofl_desc *ofl)
3057 {
3058         Word            ndx = 0;
3059         ofl_flag_t      flags = ofl->ofl_flags;
3060         Move            *omvp;
3061         Aliste          idx1;
3062         Sym_desc        *sdp;
3063 
3064         /*
3065          * Determine the index of the symbol table that will be referenced by
3066          * the Move section.
3067          */
3068         if (OFL_ALLOW_DYNSYM(ofl))
3069                 /* LINTED */
3070                 ndx = (Word) elf_ndxscn(ofl->ofl_osdynsym->os_scn);
3071         else if (!(flags & FLG_OF_STRIP) || (flags & FLG_OF_RELOBJ))
3072                 /* LINTED */
3073                 ndx = (Word) elf_ndxscn(ofl->ofl_ossymtab->os_scn);
3074 
3075         /*
3076          * Update sh_link of the Move section, and point to the new Move data.
3077          */
3078         if (ofl->ofl_osmove) {
3079                 ofl->ofl_osmove->os_shdr->sh_link = ndx;
3080                 omvp = (Move *)ofl->ofl_osmove->os_outdata->d_buf;
3081         }
3082 
3083         /*
3084          * Update symbol entry index
3085          */
3086         for (APLIST_TRAVERSE(ofl->ofl_parsyms, idx1, sdp)) {
3087                 Aliste          idx2;
3088                 Mv_desc         *mdp;
3089 
3090                 /*
3091                  * Expand move table
3092                  */
3093                 if (sdp->sd_flags & FLG_SY_PAREXPN) {
3094                         const char      *str;
3095 
3096                         if (flags & FLG_OF_STATIC)
3097                                 str = MSG_INTL(MSG_PSYM_EXPREASON1);
3098                         else if (ofl->ofl_flags1 & FLG_OF1_NOPARTI)
3099                                 str = MSG_INTL(MSG_PSYM_EXPREASON2);
3100                         else
3101                                 str = MSG_INTL(MSG_PSYM_EXPREASON3);
3102 
3103                         DBG_CALL(Dbg_move_parexpn(ofl->ofl_lml,
3104                             sdp->sd_name, str));
3105 
3106                         for (ALIST_TRAVERSE(sdp->sd_move, idx2, mdp)) {
3107                                 DBG_CALL(Dbg_move_entry1(ofl->ofl_lml, 0,
3108                                     mdp->md_move, sdp));
3109                                 expand_move(ofl, sdp, mdp->md_move);
3110                         }
3111                         continue;
3112                 }
3113 
3114                 /*
3115                  * Process move table
3116                  */
3117                 DBG_CALL(Dbg_move_outmove(ofl->ofl_lml, sdp->sd_name));
3118 
3119                 for (ALIST_TRAVERSE(sdp->sd_move, idx2, mdp)) {
3120                         Move    *imvp;
3121                         int     idx = 1;
3122                         Sym     *sym;
3123 
3124                         imvp = mdp->md_move;
3125                         sym = sdp->sd_sym;
3126 
3127                         DBG_CALL(Dbg_move_entry1(ofl->ofl_lml, 1, imvp, sdp));
3128 
3129                         *omvp = *imvp;
3130                         if ((flags & FLG_OF_RELOBJ) == 0) {
3131                                 if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) {
3132                                         Os_desc *osp = sdp->sd_isc->is_osdesc;
3133                                         Word    ndx = osp->os_identndx;
3134 
3135                                         omvp->m_info =
3136                                             /* LINTED */
3137                                             ELF_M_INFO(ndx, imvp->m_info);
3138 
3139                                         if (ELF_ST_TYPE(sym->st_info) !=
3140                                             STT_SECTION) {
3141                                                 omvp->m_poffset =
3142                                                     sym->st_value -
3143                                                     osp->os_shdr->sh_addr +
3144                                                     imvp->m_poffset;
3145                                         }
3146                                 } else {
3147                                         omvp->m_info =
3148                                             /* LINTED */
3149                                             ELF_M_INFO(sdp->sd_symndx,
3150                                             imvp->m_info);
3151                                 }
3152                         } else {
3153                                 Boolean         isredloc = FALSE;
3154 
3155                                 if ((ELF_ST_BIND(sym->st_info) == STB_LOCAL) &&
3156                                     (ofl->ofl_flags & FLG_OF_REDLSYM))
3157                                         isredloc = TRUE;
3158 
3159                                 if (isredloc && !(sdp->sd_move)) {
3160                                         Os_desc *osp = sdp->sd_isc->is_osdesc;
3161                                         Word    ndx = osp->os_identndx;
3162 
3163                                         omvp->m_info =
3164                                             /* LINTED */
3165                                             ELF_M_INFO(ndx, imvp->m_info);
3166 
3167                                         omvp->m_poffset += sym->st_value;
3168                                 } else {
3169                                         if (isredloc)
3170                                                 DBG_CALL(Dbg_syms_reduce(ofl,
3171                                                     DBG_SYM_REDUCE_RETAIN,
3172                                                     sdp, idx,
3173                                                     ofl->ofl_osmove->os_name));
3174 
3175                                         omvp->m_info =
3176                                             /* LINTED */
3177                                             ELF_M_INFO(sdp->sd_symndx,
3178                                             imvp->m_info);
3179                                 }
3180                         }
3181 
3182                         DBG_CALL(Dbg_move_entry1(ofl->ofl_lml, 0, omvp, sdp));
3183                         omvp++;
3184                         idx++;
3185                 }
3186         }
3187 }
3188 
3189 /*
3190  * Scan through the SHT_GROUP output sections.  Update their sh_link/sh_info
3191  * fields as well as the section contents.
3192  */
3193 static uintptr_t
3194 update_ogroup(Ofl_desc *ofl)
3195 {
3196         Aliste          idx;
3197         Os_desc         *osp;
3198         uintptr_t       error = 0;
3199 
3200         for (APLIST_TRAVERSE(ofl->ofl_osgroups, idx, osp)) {
3201                 Is_desc         *isp;
3202                 Ifl_desc        *ifl;
3203                 Shdr            *shdr = osp->os_shdr;
3204                 Sym_desc        *sdp;
3205                 Xword           i, grpcnt;
3206                 Word            *gdata;
3207 
3208                 /*
3209                  * Since input GROUP sections always create unique
3210                  * output GROUP sections - we know there is only one
3211                  * item on the list.
3212                  */
3213                 isp = ld_os_first_isdesc(osp);
3214 
3215                 ifl = isp->is_file;
3216                 sdp = ifl->ifl_oldndx[isp->is_shdr->sh_info];
3217                 shdr->sh_link = (Word)elf_ndxscn(ofl->ofl_ossymtab->os_scn);
3218                 shdr->sh_info = sdp->sd_symndx;
3219 
3220                 /*
3221                  * Scan through the group data section and update
3222                  * all of the links to new values.
3223                  */
3224                 grpcnt = shdr->sh_size / shdr->sh_entsize;
3225                 gdata = (Word *)osp->os_outdata->d_buf;
3226 
3227                 for (i = 1; i < grpcnt; i++) {
3228                         Os_desc *_osp;
3229                         Is_desc *_isp = ifl->ifl_isdesc[gdata[i]];
3230 
3231                         /*
3232                          * If the referenced section didn't make it to the
3233                          * output file - just zero out the entry.
3234                          */
3235                         if ((_osp = _isp->is_osdesc) == NULL)
3236                                 gdata[i] = 0;
3237                         else
3238                                 gdata[i] = (Word)elf_ndxscn(_osp->os_scn);
3239                 }
3240         }
3241         return (error);
3242 }
3243 
3244 static void
3245 update_ostrtab(Os_desc *osp, Str_tbl *stp, uint_t extra)
3246 {
3247         Elf_Data        *data;
3248 
3249         if (osp == NULL)
3250                 return;
3251 
3252         data = osp->os_outdata;
3253         assert(data->d_size == (st_getstrtab_sz(stp) + extra));
3254         (void) st_setstrbuf(stp, data->d_buf, data->d_size - extra);
3255         /* If leaving an extra hole at the end, zero it */
3256         if (extra > 0)
3257                 (void) memset((char *)data->d_buf + data->d_size - extra,
3258                     0x0, extra);
3259 }
3260 
3261 /*
3262  * Update capabilities information.
3263  *
3264  * If string table capabilities exist, then the associated string must be
3265  * translated into an offset into the string table.
3266  */
3267 static void
3268 update_oscap(Ofl_desc *ofl)
3269 {
3270         Os_desc         *strosp, *cosp;
3271         Cap             *cap;
3272         Str_tbl         *strtbl;
3273         Capstr          *capstr;
3274         size_t          stoff;
3275         Aliste          idx1;
3276 
3277         /*
3278          * Determine which symbol table or string table is appropriate.
3279          */
3280         if (OFL_IS_STATIC_OBJ(ofl)) {
3281                 strosp = ofl->ofl_osstrtab;
3282                 strtbl = ofl->ofl_strtab;
3283         } else {
3284                 strosp = ofl->ofl_osdynstr;
3285                 strtbl = ofl->ofl_dynstrtab;
3286         }
3287 
3288         /*
3289          * If symbol capabilities exist, set the sh_link field of the .SUNW_cap
3290          * section to the .SUNW_capinfo section.
3291          */
3292         if (ofl->ofl_oscapinfo) {
3293                 cosp = ofl->ofl_oscap;
3294                 cosp->os_shdr->sh_link =
3295                     (Word)elf_ndxscn(ofl->ofl_oscapinfo->os_scn);
3296         }
3297 
3298         /*
3299          * If there are capability strings to process, set the sh_info
3300          * field of the .SUNW_cap section to the associated string table, and
3301          * proceed to process any CA_SUNW_PLAT entries.
3302          */
3303         if ((ofl->ofl_flags & FLG_OF_CAPSTRS) == 0)
3304                 return;
3305 
3306         cosp = ofl->ofl_oscap;
3307         cosp->os_shdr->sh_info = (Word)elf_ndxscn(strosp->os_scn);
3308 
3309         cap = ofl->ofl_oscap->os_outdata->d_buf;
3310 
3311         /*
3312          * Determine whether an object capability identifier, or object
3313          * machine/platform capabilities exists.
3314          */
3315         capstr = &ofl->ofl_ocapset.oc_id;
3316         if (capstr->cs_str) {
3317                 (void) st_setstring(strtbl, capstr->cs_str, &stoff);
3318                 cap[capstr->cs_ndx].c_un.c_ptr = stoff;
3319         }
3320         for (ALIST_TRAVERSE(ofl->ofl_ocapset.oc_plat.cl_val, idx1, capstr)) {
3321                 (void) st_setstring(strtbl, capstr->cs_str, &stoff);
3322                 cap[capstr->cs_ndx].c_un.c_ptr = stoff;
3323         }
3324         for (ALIST_TRAVERSE(ofl->ofl_ocapset.oc_mach.cl_val, idx1, capstr)) {
3325                 (void) st_setstring(strtbl, capstr->cs_str, &stoff);
3326                 cap[capstr->cs_ndx].c_un.c_ptr = stoff;
3327         }
3328 
3329         /*
3330          * Determine any symbol capability identifiers, or machine/platform
3331          * capabilities.
3332          */
3333         if (ofl->ofl_capgroups) {
3334                 Cap_group       *cgp;
3335 
3336                 for (APLIST_TRAVERSE(ofl->ofl_capgroups, idx1, cgp)) {
3337                         Objcapset       *ocapset = &cgp->cg_set;
3338                         Aliste          idx2;
3339 
3340                         capstr = &ocapset->oc_id;
3341                         if (capstr->cs_str) {
3342                                 (void) st_setstring(strtbl, capstr->cs_str,
3343                                     &stoff);
3344                                 cap[capstr->cs_ndx].c_un.c_ptr = stoff;
3345                         }
3346                         for (ALIST_TRAVERSE(ocapset->oc_plat.cl_val, idx2,
3347                             capstr)) {
3348                                 (void) st_setstring(strtbl, capstr->cs_str,
3349                                     &stoff);
3350                                 cap[capstr->cs_ndx].c_un.c_ptr = stoff;
3351                         }
3352                         for (ALIST_TRAVERSE(ocapset->oc_mach.cl_val, idx2,
3353                             capstr)) {
3354                                 (void) st_setstring(strtbl, capstr->cs_str,
3355                                     &stoff);
3356                                 cap[capstr->cs_ndx].c_un.c_ptr = stoff;
3357                         }
3358                 }
3359         }
3360 }
3361 
3362 /*
3363  * Update the .SUNW_capinfo, and possibly the .SUNW_capchain sections.
3364  */
3365 static void
3366 update_oscapinfo(Ofl_desc *ofl)
3367 {
3368         Os_desc         *symosp, *ciosp, *ccosp = NULL;
3369         Capinfo         *ocapinfo;
3370         Capchain        *ocapchain;
3371         Cap_avlnode     *cav;
3372         Word            chainndx = 0;
3373 
3374         /*
3375          * Determine which symbol table is appropriate.
3376          */
3377         if (OFL_IS_STATIC_OBJ(ofl))
3378                 symosp = ofl->ofl_ossymtab;
3379         else
3380                 symosp = ofl->ofl_osdynsym;
3381 
3382         /*
3383          * Update the .SUNW_capinfo sh_link to point to the appropriate symbol
3384          * table section.  If we're creating a dynamic object, the
3385          * .SUNW_capinfo sh_info is updated to point to the .SUNW_capchain
3386          * section.
3387          */
3388         ciosp = ofl->ofl_oscapinfo;
3389         ciosp->os_shdr->sh_link = (Word)elf_ndxscn(symosp->os_scn);
3390 
3391         if (OFL_IS_STATIC_OBJ(ofl) == 0) {
3392                 ccosp = ofl->ofl_oscapchain;
3393                 ciosp->os_shdr->sh_info = (Word)elf_ndxscn(ccosp->os_scn);
3394         }
3395 
3396         /*
3397          * Establish the data for each section.  The first element of each
3398          * section defines the section's version number.
3399          */
3400         ocapinfo = ciosp->os_outdata->d_buf;
3401         ocapinfo[0] = CAPINFO_CURRENT;
3402         if (ccosp) {
3403                 ocapchain = ccosp->os_outdata->d_buf;
3404                 ocapchain[chainndx++] = CAPCHAIN_CURRENT;
3405         }
3406 
3407         /*
3408          * Traverse all capabilities families.  Each member has a .SUNW_capinfo
3409          * assignment.  The .SUNW_capinfo entry differs for relocatable objects
3410          * and dynamic objects.
3411          *
3412          * Relocatable objects:
3413          *                      ELF_C_GROUP             ELF_C_SYM
3414          *
3415          * Family lead:         CAPINFO_SUNW_GLOB       lead symbol index
3416          * Family lead alias:   CAPINFO_SUNW_GLOB       lead symbol index
3417          * Family member:       .SUNW_cap index         lead symbol index
3418          *
3419          * Dynamic objects:
3420          *                      ELF_C_GROUP             ELF_C_SYM
3421          *
3422          * Family lead:         CAPINFO_SUNW_GLOB       .SUNW_capchain index
3423          * Family lead alias:   CAPINFO_SUNW_GLOB       .SUNW_capchain index
3424          * Family member:       .SUNW_cap index         lead symbol index
3425          *
3426          * The ELF_C_GROUP field identifies a capabilities symbol.  Lead
3427          * capability symbols, and lead capability aliases are identified by
3428          * a CAPINFO_SUNW_GLOB group identifier.  For family members, the
3429          * ELF_C_GROUP provides an index to the associate capabilities group
3430          * (i.e, an index into the SUNW_cap section that defines a group).
3431          *
3432          * For relocatable objects, the ELF_C_SYM field identifies the lead
3433          * capability symbol.  For the lead symbol itself, the .SUNW_capinfo
3434          * index is the same as the ELF_C_SYM value.  For lead alias symbols,
3435          * the .SUNW_capinfo index differs from the ELF_C_SYM value.  This
3436          * differentiation of CAPINFO_SUNW_GLOB symbols allows ld(1) to
3437          * identify, and propagate lead alias symbols.  For example, the lead
3438          * capability symbol memcpy() would have the ELF_C_SYM for memcpy(),
3439          * and the lead alias _memcpy() would also have the ELF_C_SYM for
3440          * memcpy().
3441          *
3442          * For dynamic objects, both a lead capability symbol, and alias symbol
3443          * would have a ELF_C_SYM value that represents the same capability
3444          * chain index.  The capability chain allows ld.so.1 to traverse a
3445          * family chain for a given lead symbol, and select the most appropriate
3446          * family member.  The .SUNW_capchain array contains a series of symbol
3447          * indexes for each family member:
3448          *
3449          *    chaincap[n]  chaincap[n + 1]  chaincap[n + 2]  chaincap[n + x]
3450          *      foo() ndx    foo%x() ndx        foo%y() ndx     0
3451          *
3452          * For family members, the ELF_C_SYM value associates the capability
3453          * members with their family lead symbol.  This association, although
3454          * unused within a dynamic object, allows ld(1) to identify, and
3455          * propagate family members when processing relocatable objects.
3456          */
3457         for (cav = avl_first(ofl->ofl_capfamilies); cav;
3458             cav = AVL_NEXT(ofl->ofl_capfamilies, cav)) {
3459                 Cap_sym         *csp;
3460                 Aliste          idx;
3461                 Sym_desc        *asdp, *lsdp = cav->cn_symavlnode.sav_sdp;
3462 
3463                 if (ccosp) {
3464                         /*
3465                          * For a dynamic object, identify this lead symbol, and
3466                          * point it to the head of a capability chain.  Set the
3467                          * head of the capability chain to the same lead symbol.
3468                          */
3469                         ocapinfo[lsdp->sd_symndx] =
3470                             ELF_C_INFO(chainndx, CAPINFO_SUNW_GLOB);
3471                         ocapchain[chainndx] = lsdp->sd_symndx;
3472                 } else {
3473                         /*
3474                          * For a relocatable object, identify this lead symbol,
3475                          * and set the lead symbol index to itself.
3476                          */
3477                         ocapinfo[lsdp->sd_symndx] =
3478                             ELF_C_INFO(lsdp->sd_symndx, CAPINFO_SUNW_GLOB);
3479                 }
3480 
3481                 /*
3482                  * Gather any lead symbol aliases.
3483                  */
3484                 for (APLIST_TRAVERSE(cav->cn_aliases, idx, asdp)) {
3485                         if (ccosp) {
3486                                 /*
3487                                  * For a dynamic object, identify this lead
3488                                  * alias symbol, and point it to the same
3489                                  * capability chain index as the lead symbol.
3490                                  */
3491                                 ocapinfo[asdp->sd_symndx] =
3492                                     ELF_C_INFO(chainndx, CAPINFO_SUNW_GLOB);
3493                         } else {
3494                                 /*
3495                                  * For a relocatable object, identify this lead
3496                                  * alias symbol, and set the lead symbol index
3497                                  * to the lead symbol.
3498                                  */
3499                                 ocapinfo[asdp->sd_symndx] =
3500                                     ELF_C_INFO(lsdp->sd_symndx,
3501                                     CAPINFO_SUNW_GLOB);
3502                         }
3503                 }
3504 
3505                 chainndx++;
3506 
3507                 /*
3508                  * Gather the family members.
3509                  */
3510                 for (APLIST_TRAVERSE(cav->cn_members, idx, csp)) {
3511                         Sym_desc        *msdp = csp->cs_sdp;
3512 
3513                         /*
3514                          * Identify the members capability group, and the lead
3515                          * symbol of the family this symbol is a member of.
3516                          */
3517                         ocapinfo[msdp->sd_symndx] =
3518                             ELF_C_INFO(lsdp->sd_symndx, csp->cs_group->cg_ndx);
3519                         if (ccosp) {
3520                                 /*
3521                                  * For a dynamic object, set the next capability
3522                                  * chain to point to this family member.
3523                                  */
3524                                 ocapchain[chainndx++] = msdp->sd_symndx;
3525                         }
3526                 }
3527 
3528                 /*
3529                  * Any chain of family members is terminated with a 0 element.
3530                  */
3531                 if (ccosp)
3532                         ocapchain[chainndx++] = 0;
3533         }
3534 }
3535 
3536 /*
3537  * Translate the shdr->sh_{link, info} from its input section value to that
3538  * of the corresponding shdr->sh_{link, info} output section value.
3539  */
3540 static Word
3541 translate_link(Ofl_desc *ofl, Os_desc *osp, Word link, const char *msg)
3542 {
3543         Is_desc         *isp;
3544         Ifl_desc        *ifl;
3545 
3546         /*
3547          * Don't translate the special section numbers.
3548          */
3549         if (link >= SHN_LORESERVE)
3550                 return (link);
3551 
3552         /*
3553          * Does this output section translate back to an input file.  If not
3554          * then there is no translation to do.  In this case we will assume that
3555          * if sh_link has a value, it's the right value.
3556          */
3557         isp = ld_os_first_isdesc(osp);
3558         if ((ifl = isp->is_file) == NULL)
3559                 return (link);
3560 
3561         /*
3562          * Sanity check to make sure that the sh_{link, info} value
3563          * is within range for the input file.
3564          */
3565         if (link >= ifl->ifl_shnum) {
3566                 ld_eprintf(ofl, ERR_WARNING, msg, ifl->ifl_name,
3567                     EC_WORD(isp->is_scnndx), isp->is_name, EC_XWORD(link));
3568                 return (link);
3569         }
3570 
3571         /*
3572          * Follow the link to the input section.
3573          */
3574         if ((isp = ifl->ifl_isdesc[link]) == NULL)
3575                 return (0);
3576         if ((osp = isp->is_osdesc) == NULL)
3577                 return (0);
3578 
3579         /* LINTED */
3580         return ((Word)elf_ndxscn(osp->os_scn));
3581 }
3582 
3583 /*
3584  * Having created all of the necessary sections, segments, and associated
3585  * headers, fill in the program headers and update any other data in the
3586  * output image.  Some general rules:
3587  *
3588  *  -   If an interpreter is required always generate a PT_PHDR entry as
3589  *      well.  It is this entry that triggers the kernel into passing the
3590  *      interpreter an aux vector instead of just a file descriptor.
3591  *
3592  *  -   When generating an image that will be interpreted (ie. a dynamic
3593  *      executable, a shared object, or a static executable that has been
3594  *      provided with an interpreter - weird, but possible), make the initial
3595  *      loadable segment include both the ehdr and phdr[].  Both of these
3596  *      tables are used by the interpreter therefore it seems more intuitive
3597  *      to explicitly defined them as part of the mapped image rather than
3598  *      relying on page rounding by the interpreter to allow their access.
3599  *
3600  *  -   When generating a static image that does not require an interpreter
3601  *      have the first loadable segment indicate the address of the first
3602  *      .section as the start address (things like /kernel/unix and ufsboot
3603  *      expect this behavior).
3604  */
3605 uintptr_t
3606 ld_update_outfile(Ofl_desc *ofl)
3607 {
3608         Addr            size, etext, vaddr;
3609         Sg_desc         *sgp;
3610         Sg_desc         *dtracesgp = NULL, *capsgp = NULL, *intpsgp = NULL;
3611         Os_desc         *osp;
3612         int             phdrndx = 0, segndx = -1, secndx, intppndx, intpsndx;
3613         int             dtracepndx, dtracesndx, cappndx, capsndx;
3614         Ehdr            *ehdr = ofl->ofl_nehdr;
3615         Shdr            *hshdr;
3616         Phdr            *_phdr = NULL;
3617         Word            phdrsz = (ehdr->e_phnum * ehdr->e_phentsize), shscnndx;
3618         ofl_flag_t      flags = ofl->ofl_flags;
3619         Word            ehdrsz = ehdr->e_ehsize;
3620         Boolean         nobits;
3621         Off             offset;
3622         Aliste          idx1;
3623 
3624         /*
3625          * Initialize the starting address for the first segment.  Executables
3626          * have different starting addresses depending upon the target ABI,
3627          * where as shared objects have a starting address of 0.  If this is
3628          * a 64-bit executable that is being constructed to run in a restricted
3629          * address space, use an alternative origin that will provide more free
3630          * address space for the the eventual process.
3631          */
3632         if (ofl->ofl_flags & FLG_OF_EXEC) {
3633 #if     defined(_ELF64)
3634                 if (ofl->ofl_ocapset.oc_sf_1.cm_val & SF1_SUNW_ADDR32)
3635                         vaddr = ld_targ.t_m.m_segm_aorigin;
3636                 else
3637 #endif
3638                         vaddr = ld_targ.t_m.m_segm_origin;
3639         } else
3640                 vaddr = 0;
3641 
3642         /*
3643          * Loop through the segment descriptors and pick out what we need.
3644          */
3645         DBG_CALL(Dbg_seg_title(ofl->ofl_lml));
3646         for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp)) {
3647                 Phdr            *phdr = &(sgp->sg_phdr);
3648                 Xword           p_align;
3649                 Aliste          idx2;
3650                 Sym_desc        *sdp;
3651 
3652                 segndx++;
3653 
3654                 /*
3655                  * If an interpreter is required generate a PT_INTERP and
3656                  * PT_PHDR program header entry.  The PT_PHDR entry describes
3657                  * the program header table itself.  This information will be
3658                  * passed via the aux vector to the interpreter (ld.so.1).
3659                  * The program header array is actually part of the first
3660                  * loadable segment (and the PT_PHDR entry is the first entry),
3661                  * therefore its virtual address isn't known until the first
3662                  * loadable segment is processed.
3663                  */
3664                 if (phdr->p_type == PT_PHDR) {
3665                         if (ofl->ofl_osinterp) {
3666                                 phdr->p_offset = ehdr->e_phoff;
3667                                 phdr->p_filesz = phdr->p_memsz = phdrsz;
3668 
3669                                 DBG_CALL(Dbg_seg_entry(ofl, segndx, sgp));
3670                                 ofl->ofl_phdr[phdrndx++] = *phdr;
3671                         }
3672                         continue;
3673                 }
3674                 if (phdr->p_type == PT_INTERP) {
3675                         if (ofl->ofl_osinterp) {
3676                                 intpsgp = sgp;
3677                                 intpsndx = segndx;
3678                                 intppndx = phdrndx++;
3679                         }
3680                         continue;
3681                 }
3682 
3683                 /*
3684                  * If we are creating a PT_SUNWDTRACE segment, remember where
3685                  * the program header is.  The header values are assigned after
3686                  * update_osym() has completed and the symbol table addresses
3687                  * have been updated.
3688                  */
3689                 if (phdr->p_type == PT_SUNWDTRACE) {
3690                         if (ofl->ofl_dtracesym &&
3691                             ((flags & FLG_OF_RELOBJ) == 0)) {
3692                                 dtracesgp = sgp;
3693                                 dtracesndx = segndx;
3694                                 dtracepndx = phdrndx++;
3695                         }
3696                         continue;
3697                 }
3698 
3699                 /*
3700                  * If a hardware/software capabilities section is required,
3701                  * generate the PT_SUNWCAP header.  Note, as this comes before
3702                  * the first loadable segment, we don't yet know its real
3703                  * virtual address.  This is updated later.
3704                  */
3705                 if (phdr->p_type == PT_SUNWCAP) {
3706                         if (ofl->ofl_oscap && (ofl->ofl_flags & FLG_OF_PTCAP) &&
3707                             ((flags & FLG_OF_RELOBJ) == 0)) {
3708                                 capsgp = sgp;
3709                                 capsndx = segndx;
3710                                 cappndx = phdrndx++;
3711                         }
3712                         continue;
3713                 }
3714 
3715                 /*
3716                  * As the dynamic program header occurs after the loadable
3717                  * headers in the segment descriptor table, all the address
3718                  * information for the .dynamic output section will have been
3719                  * figured out by now.
3720                  */
3721                 if (phdr->p_type == PT_DYNAMIC) {
3722                         if (OFL_ALLOW_DYNSYM(ofl)) {
3723                                 Shdr    *shdr = ofl->ofl_osdynamic->os_shdr;
3724 
3725                                 phdr->p_vaddr = shdr->sh_addr;
3726                                 phdr->p_offset = shdr->sh_offset;
3727                                 phdr->p_filesz = shdr->sh_size;
3728                                 phdr->p_flags = ld_targ.t_m.m_dataseg_perm;
3729 
3730                                 DBG_CALL(Dbg_seg_entry(ofl, segndx, sgp));
3731                                 ofl->ofl_phdr[phdrndx++] = *phdr;
3732                         }
3733                         continue;
3734                 }
3735 
3736                 /*
3737                  * As the unwind (.eh_frame_hdr) program header occurs after
3738                  * the loadable headers in the segment descriptor table, all
3739                  * the address information for the .eh_frame output section
3740                  * will have been figured out by now.
3741                  */
3742                 if (phdr->p_type == PT_SUNW_UNWIND) {
3743                         Shdr        *shdr;
3744 
3745                         if (ofl->ofl_unwindhdr == NULL)
3746                                 continue;
3747 
3748                         shdr = ofl->ofl_unwindhdr->os_shdr;
3749 
3750                         phdr->p_flags = PF_R;
3751                         phdr->p_vaddr = shdr->sh_addr;
3752                         phdr->p_memsz = shdr->sh_size;
3753                         phdr->p_filesz = shdr->sh_size;
3754                         phdr->p_offset = shdr->sh_offset;
3755                         phdr->p_align = shdr->sh_addralign;
3756                         phdr->p_paddr = 0;
3757                         ofl->ofl_phdr[phdrndx++] = *phdr;
3758                         continue;
3759                 }
3760 
3761                 /*
3762                  * The sunwstack program is used to convey non-default
3763                  * flags for the process stack. Only emit it if it would
3764                  * change the default.
3765                  */
3766                 if (phdr->p_type == PT_SUNWSTACK) {
3767                         if (((flags & FLG_OF_RELOBJ) == 0) &&
3768                             ((sgp->sg_flags & FLG_SG_DISABLED) == 0))
3769                                 ofl->ofl_phdr[phdrndx++] = *phdr;
3770                         continue;
3771                 }
3772 
3773                 /*
3774                  * As the TLS program header occurs after the loadable
3775                  * headers in the segment descriptor table, all the address
3776                  * information for the .tls output section will have been
3777                  * figured out by now.
3778                  */
3779                 if (phdr->p_type == PT_TLS) {
3780                         Os_desc         *tlsosp;
3781                         Shdr            *lastfileshdr = NULL;
3782                         Shdr            *firstshdr = NULL, *lastshdr;
3783                         Aliste          idx;
3784 
3785                         if (ofl->ofl_ostlsseg == NULL)
3786                                 continue;
3787 
3788                         /*
3789                          * Scan the output sections that have contributed TLS.
3790                          * Remember the first and last so as to determine the
3791                          * TLS memory size requirement.  Remember the last
3792                          * progbits section to determine the TLS data
3793                          * contribution, which determines the TLS program
3794                          * header filesz.
3795                          */
3796                         for (APLIST_TRAVERSE(ofl->ofl_ostlsseg, idx, tlsosp)) {
3797                                 Shdr    *tlsshdr = tlsosp->os_shdr;
3798 
3799                                 if (firstshdr == NULL)
3800                                         firstshdr = tlsshdr;
3801                                 if (tlsshdr->sh_type != SHT_NOBITS)
3802                                         lastfileshdr = tlsshdr;
3803                                 lastshdr = tlsshdr;
3804                         }
3805 
3806                         phdr->p_flags = PF_R | PF_W;
3807                         phdr->p_vaddr = firstshdr->sh_addr;
3808                         phdr->p_offset = firstshdr->sh_offset;
3809                         phdr->p_align = firstshdr->sh_addralign;
3810 
3811                         /*
3812                          * Determine the initialized TLS data size.  This
3813                          * address range is from the start of the TLS segment
3814                          * to the end of the last piece of initialized data.
3815                          */
3816                         if (lastfileshdr)
3817                                 phdr->p_filesz = lastfileshdr->sh_offset +
3818                                     lastfileshdr->sh_size - phdr->p_offset;
3819                         else
3820                                 phdr->p_filesz = 0;
3821 
3822                         /*
3823                          * Determine the total TLS memory size.  This includes
3824                          * all TLS data and TLS uninitialized data.  This
3825                          * address range is from the start of the TLS segment
3826                          * to the memory address of the last piece of
3827                          * uninitialized data.
3828                          */
3829                         phdr->p_memsz = lastshdr->sh_addr +
3830                             lastshdr->sh_size - phdr->p_vaddr;
3831 
3832                         DBG_CALL(Dbg_seg_entry(ofl, segndx, sgp));
3833                         ofl->ofl_phdr[phdrndx] = *phdr;
3834                         ofl->ofl_tlsphdr = &ofl->ofl_phdr[phdrndx++];
3835                         continue;
3836                 }
3837 
3838                 /*
3839                  * If this is an empty segment declaration, it will occur after
3840                  * all other loadable segments.  As empty segments can be
3841                  * defined with fixed addresses, make sure that no loadable
3842                  * segments overlap.  This might occur as the object evolves
3843                  * and the loadable segments grow, thus encroaching upon an
3844                  * existing segment reservation.
3845                  *
3846                  * Segments are only created for dynamic objects, thus this
3847                  * checking can be skipped when building a relocatable object.
3848                  */
3849                 if (!(flags & FLG_OF_RELOBJ) &&
3850                     (sgp->sg_flags & FLG_SG_EMPTY)) {
3851                         int     i;
3852                         Addr    v_e;
3853 
3854                         vaddr = phdr->p_vaddr;
3855                         phdr->p_memsz = sgp->sg_length;
3856                         DBG_CALL(Dbg_seg_entry(ofl, segndx, sgp));
3857                         ofl->ofl_phdr[phdrndx++] = *phdr;
3858 
3859                         if (phdr->p_type != PT_LOAD)
3860                                 continue;
3861 
3862                         v_e = vaddr + phdr->p_memsz;
3863 
3864                         /*
3865                          * Check overlaps
3866                          */
3867                         for (i = 0; i < phdrndx - 1; i++) {
3868                                 Addr    p_s = (ofl->ofl_phdr[i]).p_vaddr;
3869                                 Addr    p_e;
3870 
3871                                 if ((ofl->ofl_phdr[i]).p_type != PT_LOAD)
3872                                         continue;
3873 
3874                                 p_e = p_s + (ofl->ofl_phdr[i]).p_memsz;
3875                                 if (((p_s <= vaddr) && (p_e > vaddr)) ||
3876                                     ((vaddr <= p_s) && (v_e > p_s)))
3877                                         ld_eprintf(ofl, ERR_WARNING,
3878                                             MSG_INTL(MSG_UPD_SEGOVERLAP),
3879                                             ofl->ofl_name, EC_ADDR(p_e),
3880                                             sgp->sg_name, EC_ADDR(vaddr));
3881                         }
3882                         continue;
3883                 }
3884 
3885                 /*
3886                  * Having processed any of the special program headers any
3887                  * remaining headers will be built to express individual
3888                  * segments.  Segments are only built if they have output
3889                  * section descriptors associated with them (ie. some form of
3890                  * input section has been matched to this segment).
3891                  */
3892                 if (sgp->sg_osdescs == NULL)
3893                         continue;
3894 
3895                 /*
3896                  * Determine the segments offset and size from the section
3897                  * information provided from elf_update().
3898                  * Allow for multiple NOBITS sections.
3899                  */
3900                 osp = sgp->sg_osdescs->apl_data[0];
3901                 hshdr = osp->os_shdr;
3902 
3903                 phdr->p_filesz = 0;
3904                 phdr->p_memsz = 0;
3905                 phdr->p_offset = offset = hshdr->sh_offset;
3906 
3907                 nobits = ((hshdr->sh_type == SHT_NOBITS) &&
3908                     ((sgp->sg_flags & FLG_SG_PHREQ) == 0));
3909 
3910                 for (APLIST_TRAVERSE(sgp->sg_osdescs, idx2, osp)) {
3911                         Shdr    *shdr = osp->os_shdr;
3912 
3913                         p_align = 0;
3914                         if (shdr->sh_addralign > p_align)
3915                                 p_align = shdr->sh_addralign;
3916 
3917                         offset = (Off)S_ROUND(offset, shdr->sh_addralign);
3918                         offset += shdr->sh_size;
3919 
3920                         if (shdr->sh_type != SHT_NOBITS) {
3921                                 if (nobits) {
3922                                         ld_eprintf(ofl, ERR_FATAL,
3923                                             MSG_INTL(MSG_UPD_NOBITS));
3924                                         return (S_ERROR);
3925                                 }
3926                                 phdr->p_filesz = offset - phdr->p_offset;
3927                         } else if ((sgp->sg_flags & FLG_SG_PHREQ) == 0)
3928                                 nobits = TRUE;
3929                 }
3930                 phdr->p_memsz = offset - hshdr->sh_offset;
3931 
3932                 /*
3933                  * If this is the first loadable segment of a dynamic object,
3934                  * or an interpreter has been specified (a static object built
3935                  * with an interpreter will still be given a PT_HDR entry), then
3936                  * compensate for the elf header and program header array.  Both
3937                  * of these are actually part of the loadable segment as they
3938                  * may be inspected by the interpreter.  Adjust the segments
3939                  * size and offset accordingly.
3940                  */
3941                 if ((_phdr == NULL) && (phdr->p_type == PT_LOAD) &&
3942                     ((ofl->ofl_osinterp) || (flags & FLG_OF_DYNAMIC)) &&
3943                     (!(ofl->ofl_dtflags_1 & DF_1_NOHDR))) {
3944                         size = (Addr)S_ROUND((phdrsz + ehdrsz),
3945                             hshdr->sh_addralign);
3946                         phdr->p_offset -= size;
3947                         phdr->p_filesz += size;
3948                         phdr->p_memsz += size;
3949                 }
3950 
3951                 /*
3952                  * If segment size symbols are required (specified via a
3953                  * mapfile) update their value.
3954                  */
3955                 for (APLIST_TRAVERSE(sgp->sg_sizesym, idx2, sdp))
3956                         sdp->sd_sym->st_value = phdr->p_memsz;
3957 
3958                 /*
3959                  * If no file content has been assigned to this segment (it
3960                  * only contains no-bits sections), then reset the offset for
3961                  * consistency.
3962                  */
3963                 if (phdr->p_filesz == 0)
3964                         phdr->p_offset = 0;
3965 
3966                 /*
3967                  * If a virtual address has been specified for this segment
3968                  * from a mapfile use it and make sure the previous segment
3969                  * does not run into this segment.
3970                  */
3971                 if (phdr->p_type == PT_LOAD) {
3972                         if ((sgp->sg_flags & FLG_SG_P_VADDR)) {
3973                                 if (_phdr && (vaddr > phdr->p_vaddr) &&
3974                                     (phdr->p_type == PT_LOAD))
3975                                         ld_eprintf(ofl, ERR_WARNING,
3976                                             MSG_INTL(MSG_UPD_SEGOVERLAP),
3977                                             ofl->ofl_name, EC_ADDR(vaddr),
3978                                             sgp->sg_name,
3979                                             EC_ADDR(phdr->p_vaddr));
3980                                 vaddr = phdr->p_vaddr;
3981                                 phdr->p_align = 0;
3982                         } else {
3983                                 vaddr = phdr->p_vaddr =
3984                                     (Addr)S_ROUND(vaddr, phdr->p_align);
3985                         }
3986                 }
3987 
3988                 /*
3989                  * Adjust the address offset and p_align if needed.
3990                  */
3991                 if (((sgp->sg_flags & FLG_SG_P_VADDR) == 0) &&
3992                     ((ofl->ofl_dtflags_1 & DF_1_NOHDR) == 0)) {
3993                         if (phdr->p_align != 0)
3994                                 vaddr += phdr->p_offset % phdr->p_align;
3995                         else
3996                                 vaddr += phdr->p_offset;
3997                         phdr->p_vaddr = vaddr;
3998                 }
3999 
4000                 /*
4001                  * If an interpreter is required set the virtual address of the
4002                  * PT_PHDR program header now that we know the virtual address
4003                  * of the loadable segment that contains it.  Update the
4004                  * PT_SUNWCAP header similarly.
4005                  */
4006                 if ((_phdr == NULL) && (phdr->p_type == PT_LOAD)) {
4007                         _phdr = phdr;
4008 
4009                         if ((ofl->ofl_dtflags_1 & DF_1_NOHDR) == 0) {
4010                                 if (ofl->ofl_osinterp)
4011                                         ofl->ofl_phdr[0].p_vaddr =
4012                                             vaddr + ehdrsz;
4013 
4014                                 /*
4015                                  * Finally, if we're creating a dynamic object
4016                                  * (or a static object in which an interpreter
4017                                  * is specified) update the vaddr to reflect
4018                                  * the address of the first section within this
4019                                  * segment.
4020                                  */
4021                                 if ((ofl->ofl_osinterp) ||
4022                                     (flags & FLG_OF_DYNAMIC))
4023                                         vaddr += size;
4024                         } else {
4025                                 /*
4026                                  * If the DF_1_NOHDR flag was set, and an
4027                                  * interpreter is being generated, the PT_PHDR
4028                                  * will not be part of any loadable segment.
4029                                  */
4030                                 if (ofl->ofl_osinterp) {
4031                                         ofl->ofl_phdr[0].p_vaddr = 0;
4032                                         ofl->ofl_phdr[0].p_memsz = 0;
4033                                         ofl->ofl_phdr[0].p_flags = 0;
4034                                 }
4035                         }
4036                 }
4037 
4038                 /*
4039                  * Ensure the ELF entry point defaults to zero.  Typically, this
4040                  * value is overridden in update_oehdr() to one of the standard
4041                  * entry points.  Historically, this default was set to the
4042                  * address of first executable section, but this has since been
4043                  * found to be more confusing than it is helpful.
4044                  */
4045                 ehdr->e_entry = 0;
4046 
4047                 DBG_CALL(Dbg_seg_entry(ofl, segndx, sgp));
4048 
4049                 /*
4050                  * Traverse the output section descriptors for this segment so
4051                  * that we can update the section headers addresses.  We've
4052                  * calculated the virtual address of the initial section within
4053                  * this segment, so each successive section can be calculated
4054                  * based on their offsets from each other.
4055                  */
4056                 secndx = 0;
4057                 hshdr = 0;
4058                 for (APLIST_TRAVERSE(sgp->sg_osdescs, idx2, osp)) {
4059                         Shdr    *shdr = osp->os_shdr;
4060 
4061                         if (shdr->sh_link)
4062                                 shdr->sh_link = translate_link(ofl, osp,
4063                                     shdr->sh_link, MSG_INTL(MSG_FIL_INVSHLINK));
4064 
4065                         if (shdr->sh_info && (shdr->sh_flags & SHF_INFO_LINK))
4066                                 shdr->sh_info = translate_link(ofl, osp,
4067                                     shdr->sh_info, MSG_INTL(MSG_FIL_INVSHINFO));
4068 
4069                         if (!(flags & FLG_OF_RELOBJ) &&
4070                             (phdr->p_type == PT_LOAD)) {
4071                                 if (hshdr)
4072                                         vaddr += (shdr->sh_offset -
4073                                             hshdr->sh_offset);
4074 
4075                                 shdr->sh_addr = vaddr;
4076                                 hshdr = shdr;
4077                         }
4078 
4079                         DBG_CALL(Dbg_seg_os(ofl, osp, secndx));
4080                         secndx++;
4081                 }
4082 
4083                 /*
4084                  * Establish the virtual address of the end of the last section
4085                  * in this segment so that the next segments offset can be
4086                  * calculated from this.
4087                  */
4088                 if (hshdr)
4089                         vaddr += hshdr->sh_size;
4090 
4091                 /*
4092                  * Output sections for this segment complete.  Adjust the
4093                  * virtual offset for the last sections size, and make sure we
4094                  * haven't exceeded any maximum segment length specification.
4095                  */
4096                 if ((sgp->sg_length != 0) && (sgp->sg_length < phdr->p_memsz)) {
4097                         ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_UPD_LARGSIZE),
4098                             ofl->ofl_name, sgp->sg_name,
4099                             EC_XWORD(phdr->p_memsz), EC_XWORD(sgp->sg_length));
4100                         return (S_ERROR);
4101                 }
4102 
4103                 if (phdr->p_type == PT_NOTE) {
4104                         phdr->p_vaddr = 0;
4105                         phdr->p_paddr = 0;
4106                         phdr->p_align = 0;
4107                         phdr->p_memsz = 0;
4108                 }
4109 
4110                 if ((phdr->p_type != PT_NULL) && !(flags & FLG_OF_RELOBJ))
4111                         ofl->ofl_phdr[phdrndx++] = *phdr;
4112         }
4113 
4114         /*
4115          * Update any new output sections.  When building the initial output
4116          * image, a number of sections were created but left uninitialized (eg.
4117          * .dynsym, .dynstr, .symtab, .symtab, etc.).  Here we update these
4118          * sections with the appropriate data.  Other sections may still be
4119          * modified via reloc_process().
4120          *
4121          * Copy the interpreter name into the .interp section.
4122          */
4123         if (ofl->ofl_interp)
4124                 (void) strcpy((char *)ofl->ofl_osinterp->os_outdata->d_buf,
4125                     ofl->ofl_interp);
4126 
4127         /*
4128          * Update the .shstrtab, .strtab and .dynstr sections.
4129          */
4130         update_ostrtab(ofl->ofl_osshstrtab, ofl->ofl_shdrsttab, 0);
4131         update_ostrtab(ofl->ofl_osstrtab, ofl->ofl_strtab, 0);
4132         update_ostrtab(ofl->ofl_osdynstr, ofl->ofl_dynstrtab, DYNSTR_EXTRA_PAD);
4133 
4134         /*
4135          * Build any output symbol tables, the symbols information is copied
4136          * and updated into the new output image.
4137          */
4138         if ((etext = update_osym(ofl)) == (Addr)S_ERROR)
4139                 return (S_ERROR);
4140 
4141         /*
4142          * If we have an PT_INTERP phdr, update it now from the associated
4143          * section information.
4144          */
4145         if (intpsgp) {
4146                 Phdr    *phdr = &(intpsgp->sg_phdr);
4147                 Shdr    *shdr = ofl->ofl_osinterp->os_shdr;
4148 
4149                 phdr->p_vaddr = shdr->sh_addr;
4150                 phdr->p_offset = shdr->sh_offset;
4151                 phdr->p_memsz = phdr->p_filesz = shdr->sh_size;
4152                 phdr->p_flags = PF_R;
4153 
4154                 DBG_CALL(Dbg_seg_entry(ofl, intpsndx, intpsgp));
4155                 ofl->ofl_phdr[intppndx] = *phdr;
4156         }
4157 
4158         /*
4159          * If we have a PT_SUNWDTRACE phdr, update it now with the address of
4160          * the symbol.  It's only now been updated via update_sym().
4161          */
4162         if (dtracesgp) {
4163                 Phdr            *aphdr, *phdr = &(dtracesgp->sg_phdr);
4164                 Sym_desc        *sdp = ofl->ofl_dtracesym;
4165 
4166                 phdr->p_vaddr = sdp->sd_sym->st_value;
4167                 phdr->p_memsz = sdp->sd_sym->st_size;
4168 
4169                 /*
4170                  * Take permissions from the segment that the symbol is
4171                  * associated with.
4172                  */
4173                 aphdr = &sdp->sd_isc->is_osdesc->os_sgdesc->sg_phdr;
4174                 assert(aphdr);
4175                 phdr->p_flags = aphdr->p_flags;
4176 
4177                 DBG_CALL(Dbg_seg_entry(ofl, dtracesndx, dtracesgp));
4178                 ofl->ofl_phdr[dtracepndx] = *phdr;
4179         }
4180 
4181         /*
4182          * If we have a PT_SUNWCAP phdr, update it now from the associated
4183          * section information.
4184          */
4185         if (capsgp) {
4186                 Phdr    *phdr = &(capsgp->sg_phdr);
4187                 Shdr    *shdr = ofl->ofl_oscap->os_shdr;
4188 
4189                 phdr->p_vaddr = shdr->sh_addr;
4190                 phdr->p_offset = shdr->sh_offset;
4191                 phdr->p_memsz = phdr->p_filesz = shdr->sh_size;
4192                 phdr->p_flags = PF_R;
4193 
4194                 DBG_CALL(Dbg_seg_entry(ofl, capsndx, capsgp));
4195                 ofl->ofl_phdr[cappndx] = *phdr;
4196         }
4197 
4198         /*
4199          * Update the GROUP sections.
4200          */
4201         if (update_ogroup(ofl) == S_ERROR)
4202                 return (S_ERROR);
4203 
4204         /*
4205          * Update Move Table.
4206          */
4207         if (ofl->ofl_osmove || ofl->ofl_isparexpn)
4208                 update_move(ofl);
4209 
4210         /*
4211          * Build any output headers, version information, dynamic structure and
4212          * syminfo structure.
4213          */
4214         if (update_oehdr(ofl) == S_ERROR)
4215                 return (S_ERROR);
4216         if (!(flags & FLG_OF_NOVERSEC)) {
4217                 if ((flags & FLG_OF_VERDEF) &&
4218                     (update_overdef(ofl) == S_ERROR))
4219                         return (S_ERROR);
4220                 if ((flags & FLG_OF_VERNEED) &&
4221                     (update_overneed(ofl) == S_ERROR))
4222                         return (S_ERROR);
4223                 if (flags & (FLG_OF_VERNEED | FLG_OF_VERDEF))
4224                         update_oversym(ofl);
4225         }
4226         if (flags & FLG_OF_DYNAMIC) {
4227                 if (update_odynamic(ofl) == S_ERROR)
4228                         return (S_ERROR);
4229         }
4230         if (ofl->ofl_ossyminfo) {
4231                 if (update_osyminfo(ofl) == S_ERROR)
4232                         return (S_ERROR);
4233         }
4234 
4235         /*
4236          * Update capabilities information if required.
4237          */
4238         if (ofl->ofl_oscap)
4239                 update_oscap(ofl);
4240         if (ofl->ofl_oscapinfo)
4241                 update_oscapinfo(ofl);
4242 
4243         /*
4244          * Sanity test: the first and last data byte of a string table
4245          * must be NULL.
4246          */
4247         assert((ofl->ofl_osshstrtab == NULL) ||
4248             (*((char *)ofl->ofl_osshstrtab->os_outdata->d_buf) == '\0'));
4249         assert((ofl->ofl_osshstrtab == NULL) ||
4250             (*(((char *)ofl->ofl_osshstrtab->os_outdata->d_buf) +
4251             ofl->ofl_osshstrtab->os_outdata->d_size - 1) == '\0'));
4252 
4253         assert((ofl->ofl_osstrtab == NULL) ||
4254             (*((char *)ofl->ofl_osstrtab->os_outdata->d_buf) == '\0'));
4255         assert((ofl->ofl_osstrtab == NULL) ||
4256             (*(((char *)ofl->ofl_osstrtab->os_outdata->d_buf) +
4257             ofl->ofl_osstrtab->os_outdata->d_size - 1) == '\0'));
4258 
4259         assert((ofl->ofl_osdynstr == NULL) ||
4260             (*((char *)ofl->ofl_osdynstr->os_outdata->d_buf) == '\0'));
4261         assert((ofl->ofl_osdynstr == NULL) ||
4262             (*(((char *)ofl->ofl_osdynstr->os_outdata->d_buf) +
4263             ofl->ofl_osdynstr->os_outdata->d_size - DYNSTR_EXTRA_PAD - 1) ==
4264             '\0'));
4265 
4266         /*
4267          * Emit Strtab diagnostics.
4268          */
4269         DBG_CALL(Dbg_sec_strtab(ofl->ofl_lml, ofl->ofl_osshstrtab,
4270             ofl->ofl_shdrsttab));
4271         DBG_CALL(Dbg_sec_strtab(ofl->ofl_lml, ofl->ofl_osstrtab,
4272             ofl->ofl_strtab));
4273         DBG_CALL(Dbg_sec_strtab(ofl->ofl_lml, ofl->ofl_osdynstr,
4274             ofl->ofl_dynstrtab));
4275 
4276         /*
4277          * Initialize the section headers string table index within the elf
4278          * header.
4279          */
4280         /* LINTED */
4281         if ((shscnndx = elf_ndxscn(ofl->ofl_osshstrtab->os_scn)) <
4282             SHN_LORESERVE) {
4283                 ofl->ofl_nehdr->e_shstrndx =
4284                     /* LINTED */
4285                     (Half)shscnndx;
4286         } else {
4287                 /*
4288                  * If the STRTAB section index doesn't fit into
4289                  * e_shstrndx, then we store it in 'shdr[0].st_link'.
4290                  */
4291                 Elf_Scn *scn;
4292                 Shdr    *shdr0;
4293 
4294                 if ((scn = elf_getscn(ofl->ofl_elf, 0)) == NULL) {
4295                         ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETSCN),
4296                             ofl->ofl_name);
4297                         return (S_ERROR);
4298                 }
4299                 if ((shdr0 = elf_getshdr(scn)) == NULL) {
4300                         ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETSHDR),
4301                             ofl->ofl_name);
4302                         return (S_ERROR);
4303                 }
4304                 ofl->ofl_nehdr->e_shstrndx = SHN_XINDEX;
4305                 shdr0->sh_link = shscnndx;
4306         }
4307 
4308         return ((uintptr_t)etext);
4309 }