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                         case SDAUX_ID_SECBOUND_START:
1772                                 sym->st_value = sap->sa_boundsec->
1773                                     os_shdr->sh_addr;
1774                                 sectndx = elf_ndxscn(sap->sa_boundsec->os_scn);
1775                                 sdp->sd_flags &= ~FLG_SY_SPECSEC;
1776                                 break;
1777                         case SDAUX_ID_SECBOUND_STOP:
1778                                 sym->st_value = sap->sa_boundsec->
1779                                     os_shdr->sh_addr +
1780                                     sap->sa_boundsec->os_shdr->sh_size;
1781                                 sectndx = elf_ndxscn(sap->sa_boundsec->os_scn);
1782                                 sdp->sd_flags &= ~FLG_SY_SPECSEC;
1783                                 break;
1784                         default:
1785                                 /* NOTHING */
1786                                 ;
1787                         }
1788                 }
1789 
1790                 /*
1791                  * If a plt index has been assigned to an undefined function,
1792                  * update the symbols value to the appropriate .plt address.
1793                  */
1794                 if ((flags & FLG_OF_DYNAMIC) && (flags & FLG_OF_EXEC) &&
1795                     (sdp->sd_file) &&
1796                     (sdp->sd_file->ifl_ehdr->e_type == ET_DYN) &&
1797                     (ELF_ST_TYPE(sym->st_info) == STT_FUNC) &&
1798                     !(flags & FLG_OF_BFLAG)) {
1799                         if (sap->sa_PLTndx)
1800                                 sym->st_value =
1801                                     (*ld_targ.t_mr.mr_calc_plt_addr)(sdp, ofl);
1802                 }
1803 
1804                 /*
1805                  * Finish updating the symbols.
1806                  */
1807 
1808                 /*
1809                  * Sym Update: if scoped local - set local binding
1810                  */
1811                 if (local)
1812                         sym->st_info = ELF_ST_INFO(STB_LOCAL,
1813                             ELF_ST_TYPE(sym->st_info));
1814 
1815                 /*
1816                  * Sym Updated: If both the .symtab and .dynsym
1817                  * are present then we've actually updated the information in
1818                  * the .dynsym, therefore copy this same information to the
1819                  * .symtab entry.
1820                  */
1821                 sdp->sd_shndx = sectndx;
1822                 if (enter_in_symtab && dynsym && (!local || dynlocal)) {
1823                         Word _symndx = dynlocal ? scopesym_ndx : symtab_ndx;
1824 
1825                         symtab[_symndx].st_value = sym->st_value;
1826                         symtab[_symndx].st_size = sym->st_size;
1827                         symtab[_symndx].st_info = sym->st_info;
1828                         symtab[_symndx].st_other = sym->st_other;
1829                 }
1830 
1831                 if (enter_in_symtab) {
1832                         Word    _symndx;
1833 
1834                         if (local)
1835                                 _symndx = scopesym_ndx++;
1836                         else
1837                                 _symndx = symtab_ndx++;
1838                         if (((sdp->sd_flags & FLG_SY_SPECSEC) == 0) &&
1839                             (sectndx >= SHN_LORESERVE)) {
1840                                 assert(symshndx != NULL);
1841                                 symshndx[_symndx] = sectndx;
1842                                 symtab[_symndx].st_shndx = SHN_XINDEX;
1843                         } else {
1844                                 /* LINTED */
1845                                 symtab[_symndx].st_shndx = (Half)sectndx;
1846                         }
1847                 }
1848 
1849                 if (dynsym && (!local || dynlocal)) {
1850                         /*
1851                          * dynsym and ldynsym are distinct tables, so
1852                          * we use indirection to access the right one
1853                          * and the related extended section index array.
1854                          */
1855                         Word    _symndx;
1856                         Sym     *_dynsym;
1857                         Word    *_dynshndx;
1858 
1859                         if (!local) {
1860                                 _symndx = dynsym_ndx++;
1861                                 _dynsym = dynsym;
1862                                 _dynshndx = dynshndx;
1863                         } else {
1864                                 _symndx = ldynscopesym_ndx++;
1865                                 _dynsym = ldynsym;
1866                                 _dynshndx = ldynshndx;
1867                         }
1868                         if (((sdp->sd_flags & FLG_SY_SPECSEC) == 0) &&
1869                             (sectndx >= SHN_LORESERVE)) {
1870                                 assert(_dynshndx != NULL);
1871                                 _dynshndx[_symndx] = sectndx;
1872                                 _dynsym[_symndx].st_shndx = SHN_XINDEX;
1873                         } else {
1874                                 /* LINTED */
1875                                 _dynsym[_symndx].st_shndx = (Half)sectndx;
1876                         }
1877                 }
1878 
1879                 DBG_CALL(Dbg_syms_new(ofl, sym, sdp));
1880         }
1881 
1882         /*
1883          * Now that all the symbols have been processed update any weak symbols
1884          * information (ie. copy all information except `st_name').  As both
1885          * symbols will be represented in the output, return the weak symbol to
1886          * its correct type.
1887          */
1888         for (ALIST_TRAVERSE(weak, idx1, wkp)) {
1889                 Sym_desc        *sdp, *_sdp;
1890                 Sym             *sym, *_sym, *__sym;
1891                 uchar_t         bind;
1892 
1893                 sdp = wkp->wk_weak;
1894                 _sdp = wkp->wk_alias;
1895                 _sym = __sym = _sdp->sd_sym;
1896 
1897                 sdp->sd_flags |= FLG_SY_WEAKDEF;
1898 
1899                 /*
1900                  * If the symbol definition has been scoped then assign it to
1901                  * be local, otherwise if it's from a shared object then we need
1902                  * to maintain the binding of the original reference.
1903                  */
1904                 if (SYM_IS_HIDDEN(sdp)) {
1905                         if (flags & FLG_OF_PROCRED)
1906                                 bind = STB_LOCAL;
1907                         else
1908                                 bind = STB_WEAK;
1909                 } else if ((sdp->sd_ref == REF_DYN_NEED) &&
1910                     (sdp->sd_flags & FLG_SY_GLOBREF))
1911                         bind = STB_GLOBAL;
1912                 else
1913                         bind = STB_WEAK;
1914 
1915                 DBG_CALL(Dbg_syms_old(ofl, sdp));
1916                 if ((sym = wkp->wk_symtab) != NULL) {
1917                         sym->st_value = _sym->st_value;
1918                         sym->st_size = _sym->st_size;
1919                         sym->st_other = _sym->st_other;
1920                         sym->st_shndx = _sym->st_shndx;
1921                         sym->st_info = ELF_ST_INFO(bind,
1922                             ELF_ST_TYPE(sym->st_info));
1923                         __sym = sym;
1924                 }
1925                 if ((sym = wkp->wk_dynsym) != NULL) {
1926                         sym->st_value = _sym->st_value;
1927                         sym->st_size = _sym->st_size;
1928                         sym->st_other = _sym->st_other;
1929                         sym->st_shndx = _sym->st_shndx;
1930                         sym->st_info = ELF_ST_INFO(bind,
1931                             ELF_ST_TYPE(sym->st_info));
1932                         __sym = sym;
1933                 }
1934                 DBG_CALL(Dbg_syms_new(ofl, __sym, sdp));
1935         }
1936 
1937         /*
1938          * Now display GOT debugging information if required.
1939          */
1940         DBG_CALL(Dbg_got_display(ofl, 0, 0,
1941             ld_targ.t_m.m_got_xnumber, ld_targ.t_m.m_got_entsize));
1942 
1943         /*
1944          * Update the section headers information. sh_info is
1945          * supposed to contain the offset at which the first
1946          * global symbol resides in the symbol table, while
1947          * sh_link contains the section index of the associated
1948          * string table.
1949          */
1950         if (symtab) {
1951                 Shdr    *shdr = ofl->ofl_ossymtab->os_shdr;
1952 
1953                 shdr->sh_info = symtab_gbl_bndx;
1954                 /* LINTED */
1955                 shdr->sh_link = (Word)elf_ndxscn(ofl->ofl_osstrtab->os_scn);
1956                 if (symshndx)
1957                         ofl->ofl_ossymshndx->os_shdr->sh_link =
1958                             (Word)elf_ndxscn(ofl->ofl_ossymtab->os_scn);
1959 
1960                 /*
1961                  * Ensure that the expected number of symbols
1962                  * were entered into the right spots:
1963                  *      - Scoped symbols in the right range
1964                  *      - Globals start at the right spot
1965                  *              (correct number of locals entered)
1966                  *      - The table is exactly filled
1967                  *              (correct number of globals entered)
1968                  */
1969                 assert((scopesym_bndx + ofl->ofl_scopecnt) == scopesym_ndx);
1970                 assert(shdr->sh_info == SYMTAB_LOC_CNT(ofl));
1971                 assert((shdr->sh_info + ofl->ofl_globcnt) == symtab_ndx);
1972         }
1973         if (dynsym) {
1974                 Shdr    *shdr = ofl->ofl_osdynsym->os_shdr;
1975 
1976                 shdr->sh_info = DYNSYM_LOC_CNT(ofl);
1977                 /* LINTED */
1978                 shdr->sh_link = (Word)elf_ndxscn(ofl->ofl_osdynstr->os_scn);
1979 
1980                 ofl->ofl_oshash->os_shdr->sh_link =
1981                     /* LINTED */
1982                     (Word)elf_ndxscn(ofl->ofl_osdynsym->os_scn);
1983                 if (dynshndx) {
1984                         shdr = ofl->ofl_osdynshndx->os_shdr;
1985                         shdr->sh_link =
1986                             (Word)elf_ndxscn(ofl->ofl_osdynsym->os_scn);
1987                 }
1988         }
1989         if (ldynsym) {
1990                 Shdr    *shdr = ofl->ofl_osldynsym->os_shdr;
1991 
1992                 /* ldynsym has no globals, so give index one past the end */
1993                 shdr->sh_info = ldynsym_ndx;
1994 
1995                 /*
1996                  * The ldynsym and dynsym must be adjacent. The
1997                  * idea is that rtld should be able to start with
1998                  * the ldynsym and march straight through the end
1999                  * of dynsym, seeing them as a single symbol table,
2000                  * despite the fact that they are in distinct sections.
2001                  * Ensure that this happened correctly.
2002                  *
2003                  * Note that I use ldynsym_ndx here instead of the
2004                  * computation I used to set the section size
2005                  * (found in ldynsym_cnt). The two will agree, unless
2006                  * we somehow miscounted symbols or failed to insert them
2007                  * all. Using ldynsym_ndx here catches that error in
2008                  * addition to checking for adjacency.
2009                  */
2010                 assert(dynsym == (ldynsym + ldynsym_ndx));
2011 
2012 
2013                 /* LINTED */
2014                 shdr->sh_link = (Word)elf_ndxscn(ofl->ofl_osdynstr->os_scn);
2015 
2016                 if (ldynshndx) {
2017                         shdr = ofl->ofl_osldynshndx->os_shdr;
2018                         shdr->sh_link =
2019                             (Word)elf_ndxscn(ofl->ofl_osldynsym->os_scn);
2020                 }
2021 
2022                 /*
2023                  * The presence of .SUNW_ldynsym means that there may be
2024                  * associated sort sections, one for regular symbols
2025                  * and the other for TLS. Each sort section needs the
2026                  * following done:
2027                  *      - Section header link references .SUNW_ldynsym
2028                  *      - Should have received the expected # of items
2029                  *      - Sorted by increasing address
2030                  */
2031                 if (ofl->ofl_osdynsymsort) { /* .SUNW_dynsymsort */
2032                         ofl->ofl_osdynsymsort->os_shdr->sh_link =
2033                             (Word)elf_ndxscn(ofl->ofl_osldynsym->os_scn);
2034                         assert(ofl->ofl_dynsymsortcnt == dynsymsort_ndx);
2035 
2036                         if (dynsymsort_ndx > 1) {
2037                                 dynsort_compare_syms = ldynsym;
2038                                 qsort(dynsymsort, dynsymsort_ndx,
2039                                     sizeof (*dynsymsort), dynsort_compare);
2040                                 dynsort_dupwarn(ofl, ldynsym,
2041                                     st_getstrbuf(dynstr),
2042                                     dynsymsort, dynsymsort_ndx,
2043                                     MSG_ORIG(MSG_SCN_DYNSYMSORT));
2044                         }
2045                 }
2046                 if (ofl->ofl_osdyntlssort) { /* .SUNW_dyntlssort */
2047                         ofl->ofl_osdyntlssort->os_shdr->sh_link =
2048                             (Word)elf_ndxscn(ofl->ofl_osldynsym->os_scn);
2049                         assert(ofl->ofl_dyntlssortcnt == dyntlssort_ndx);
2050 
2051                         if (dyntlssort_ndx > 1) {
2052                                 dynsort_compare_syms = ldynsym;
2053                                 qsort(dyntlssort, dyntlssort_ndx,
2054                                     sizeof (*dyntlssort), dynsort_compare);
2055                                 dynsort_dupwarn(ofl, ldynsym,
2056                                     st_getstrbuf(dynstr),
2057                                     dyntlssort, dyntlssort_ndx,
2058                                     MSG_ORIG(MSG_SCN_DYNTLSSORT));
2059                         }
2060                 }
2061         }
2062 
2063         /*
2064          * Used by ld.so.1 only.
2065          */
2066         return (etext);
2067 
2068 #undef ADD_TO_DYNSORT
2069 }
2070 
2071 /*
2072  * Build the dynamic section.
2073  *
2074  * This routine must be maintained in parallel with make_dynamic()
2075  * in sections.c
2076  */
2077 static int
2078 update_odynamic(Ofl_desc *ofl)
2079 {
2080         Aliste          idx;
2081         Ifl_desc        *ifl;
2082         Sym_desc        *sdp;
2083         Shdr            *shdr;
2084         Dyn             *_dyn = (Dyn *)ofl->ofl_osdynamic->os_outdata->d_buf;
2085         Dyn             *dyn;
2086         Os_desc         *symosp, *strosp;
2087         Str_tbl         *strtbl;
2088         size_t          stoff;
2089         ofl_flag_t      flags = ofl->ofl_flags;
2090         int             not_relobj = !(flags & FLG_OF_RELOBJ);
2091         Word            cnt;
2092 
2093         /*
2094          * Relocatable objects can be built with -r and -dy to trigger the
2095          * creation of a .dynamic section.  This model is used to create kernel
2096          * device drivers.  The .dynamic section provides a subset of userland
2097          * .dynamic entries, typically entries such as DT_NEEDED and DT_RUNPATH.
2098          *
2099          * Within a dynamic object, any .dynamic string references are to the
2100          * .dynstr table.  Within a relocatable object, these strings can reside
2101          * within the .strtab.
2102          */
2103         if (OFL_IS_STATIC_OBJ(ofl)) {
2104                 symosp = ofl->ofl_ossymtab;
2105                 strosp = ofl->ofl_osstrtab;
2106                 strtbl = ofl->ofl_strtab;
2107         } else {
2108                 symosp = ofl->ofl_osdynsym;
2109                 strosp = ofl->ofl_osdynstr;
2110                 strtbl = ofl->ofl_dynstrtab;
2111         }
2112 
2113         /* LINTED */
2114         ofl->ofl_osdynamic->os_shdr->sh_link = (Word)elf_ndxscn(strosp->os_scn);
2115 
2116         dyn = _dyn;
2117 
2118         for (APLIST_TRAVERSE(ofl->ofl_sos, idx, ifl)) {
2119                 if ((ifl->ifl_flags &
2120                     (FLG_IF_IGNORE | FLG_IF_DEPREQD)) == FLG_IF_IGNORE)
2121                         continue;
2122 
2123                 /*
2124                  * Create and set up the DT_POSFLAG_1 entry here if required.
2125                  */
2126                 if ((ifl->ifl_flags & MSK_IF_POSFLAG1) &&
2127                     (ifl->ifl_flags & FLG_IF_NEEDED) && not_relobj) {
2128                         dyn->d_tag = DT_POSFLAG_1;
2129                         if (ifl->ifl_flags & FLG_IF_LAZYLD)
2130                                 dyn->d_un.d_val = DF_P1_LAZYLOAD;
2131                         if (ifl->ifl_flags & FLG_IF_GRPPRM)
2132                                 dyn->d_un.d_val |= DF_P1_GROUPPERM;
2133                         if (ifl->ifl_flags & FLG_IF_DEFERRED)
2134                                 dyn->d_un.d_val |= DF_P1_DEFERRED;
2135                         dyn++;
2136                 }
2137 
2138                 if (ifl->ifl_flags & (FLG_IF_NEEDED | FLG_IF_NEEDSTR))
2139                         dyn->d_tag = DT_NEEDED;
2140                 else
2141                         continue;
2142 
2143                 (void) st_setstring(strtbl, ifl->ifl_soname, &stoff);
2144                 dyn->d_un.d_val = stoff;
2145                 /* LINTED */
2146                 ifl->ifl_neededndx = (Half)(((uintptr_t)dyn - (uintptr_t)_dyn) /
2147                     sizeof (Dyn));
2148                 dyn++;
2149         }
2150 
2151         if (not_relobj) {
2152                 if (ofl->ofl_dtsfltrs != NULL) {
2153                         Dfltr_desc      *dftp;
2154 
2155                         for (ALIST_TRAVERSE(ofl->ofl_dtsfltrs, idx, dftp)) {
2156                                 if (dftp->dft_flag == FLG_SY_AUXFLTR)
2157                                         dyn->d_tag = DT_SUNW_AUXILIARY;
2158                                 else
2159                                         dyn->d_tag = DT_SUNW_FILTER;
2160 
2161                                 (void) st_setstring(strtbl, dftp->dft_str,
2162                                     &stoff);
2163                                 dyn->d_un.d_val = stoff;
2164                                 dftp->dft_ndx = (Half)(((uintptr_t)dyn -
2165                                     (uintptr_t)_dyn) / sizeof (Dyn));
2166                                 dyn++;
2167                         }
2168                 }
2169                 if (((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_INIT_U),
2170                     SYM_NOHASH, 0, ofl)) != NULL) &&
2171                     (sdp->sd_ref == REF_REL_NEED) &&
2172                     (sdp->sd_sym->st_shndx != SHN_UNDEF)) {
2173                         dyn->d_tag = DT_INIT;
2174                         dyn->d_un.d_ptr = sdp->sd_sym->st_value;
2175                         dyn++;
2176                 }
2177                 if (((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_FINI_U),
2178                     SYM_NOHASH, 0, ofl)) != NULL) &&
2179                     (sdp->sd_ref == REF_REL_NEED) &&
2180                     (sdp->sd_sym->st_shndx != SHN_UNDEF)) {
2181                         dyn->d_tag = DT_FINI;
2182                         dyn->d_un.d_ptr = sdp->sd_sym->st_value;
2183                         dyn++;
2184                 }
2185                 if (ofl->ofl_soname) {
2186                         dyn->d_tag = DT_SONAME;
2187                         (void) st_setstring(strtbl, ofl->ofl_soname, &stoff);
2188                         dyn->d_un.d_val = stoff;
2189                         dyn++;
2190                 }
2191                 if (ofl->ofl_filtees) {
2192                         if (flags & FLG_OF_AUX) {
2193                                 dyn->d_tag = DT_AUXILIARY;
2194                         } else {
2195                                 dyn->d_tag = DT_FILTER;
2196                         }
2197                         (void) st_setstring(strtbl, ofl->ofl_filtees, &stoff);
2198                         dyn->d_un.d_val = stoff;
2199                         dyn++;
2200                 }
2201         }
2202 
2203         if (ofl->ofl_rpath) {
2204                 (void) st_setstring(strtbl, ofl->ofl_rpath, &stoff);
2205                 dyn->d_tag = DT_RUNPATH;
2206                 dyn->d_un.d_val = stoff;
2207                 dyn++;
2208                 dyn->d_tag = DT_RPATH;
2209                 dyn->d_un.d_val = stoff;
2210                 dyn++;
2211         }
2212 
2213         if (not_relobj) {
2214                 Aliste  idx;
2215                 Sg_desc *sgp;
2216 
2217                 if (ofl->ofl_config) {
2218                         dyn->d_tag = DT_CONFIG;
2219                         (void) st_setstring(strtbl, ofl->ofl_config, &stoff);
2220                         dyn->d_un.d_val = stoff;
2221                         dyn++;
2222                 }
2223                 if (ofl->ofl_depaudit) {
2224                         dyn->d_tag = DT_DEPAUDIT;
2225                         (void) st_setstring(strtbl, ofl->ofl_depaudit, &stoff);
2226                         dyn->d_un.d_val = stoff;
2227                         dyn++;
2228                 }
2229                 if (ofl->ofl_audit) {
2230                         dyn->d_tag = DT_AUDIT;
2231                         (void) st_setstring(strtbl, ofl->ofl_audit, &stoff);
2232                         dyn->d_un.d_val = stoff;
2233                         dyn++;
2234                 }
2235 
2236                 dyn->d_tag = DT_HASH;
2237                 dyn->d_un.d_ptr = ofl->ofl_oshash->os_shdr->sh_addr;
2238                 dyn++;
2239 
2240                 shdr = strosp->os_shdr;
2241                 dyn->d_tag = DT_STRTAB;
2242                 dyn->d_un.d_ptr = shdr->sh_addr;
2243                 dyn++;
2244 
2245                 dyn->d_tag = DT_STRSZ;
2246                 dyn->d_un.d_ptr = shdr->sh_size;
2247                 dyn++;
2248 
2249                 /*
2250                  * Note, the shdr is set and used in the ofl->ofl_osldynsym case
2251                  * that follows.
2252                  */
2253                 shdr = symosp->os_shdr;
2254                 dyn->d_tag = DT_SYMTAB;
2255                 dyn->d_un.d_ptr = shdr->sh_addr;
2256                 dyn++;
2257 
2258                 dyn->d_tag = DT_SYMENT;
2259                 dyn->d_un.d_ptr = shdr->sh_entsize;
2260                 dyn++;
2261 
2262                 if (ofl->ofl_osldynsym) {
2263                         Shdr    *lshdr = ofl->ofl_osldynsym->os_shdr;
2264 
2265                         /*
2266                          * We have arranged for the .SUNW_ldynsym data to be
2267                          * immediately in front of the .dynsym data.
2268                          * This means that you could start at the top
2269                          * of .SUNW_ldynsym and see the data for both tables
2270                          * without a break. This is the view we want to
2271                          * provide for DT_SUNW_SYMTAB, which is why we
2272                          * add the lengths together.
2273                          */
2274                         dyn->d_tag = DT_SUNW_SYMTAB;
2275                         dyn->d_un.d_ptr = lshdr->sh_addr;
2276                         dyn++;
2277 
2278                         dyn->d_tag = DT_SUNW_SYMSZ;
2279                         dyn->d_un.d_val = lshdr->sh_size + shdr->sh_size;
2280                         dyn++;
2281                 }
2282 
2283                 if (ofl->ofl_osdynsymsort || ofl->ofl_osdyntlssort) {
2284                         dyn->d_tag = DT_SUNW_SORTENT;
2285                         dyn->d_un.d_val = sizeof (Word);
2286                         dyn++;
2287                 }
2288 
2289                 if (ofl->ofl_osdynsymsort) {
2290                         shdr = ofl->ofl_osdynsymsort->os_shdr;
2291 
2292                         dyn->d_tag = DT_SUNW_SYMSORT;
2293                         dyn->d_un.d_ptr = shdr->sh_addr;
2294                         dyn++;
2295 
2296                         dyn->d_tag = DT_SUNW_SYMSORTSZ;
2297                         dyn->d_un.d_val = shdr->sh_size;
2298                         dyn++;
2299                 }
2300 
2301                 if (ofl->ofl_osdyntlssort) {
2302                         shdr = ofl->ofl_osdyntlssort->os_shdr;
2303 
2304                         dyn->d_tag = DT_SUNW_TLSSORT;
2305                         dyn->d_un.d_ptr = shdr->sh_addr;
2306                         dyn++;
2307 
2308                         dyn->d_tag = DT_SUNW_TLSSORTSZ;
2309                         dyn->d_un.d_val = shdr->sh_size;
2310                         dyn++;
2311                 }
2312 
2313                 /*
2314                  * Reserve the DT_CHECKSUM entry.  Its value will be filled in
2315                  * after the complete image is built.
2316                  */
2317                 dyn->d_tag = DT_CHECKSUM;
2318                 ofl->ofl_checksum = &dyn->d_un.d_val;
2319                 dyn++;
2320 
2321                 /*
2322                  * Versioning sections: DT_VERDEF and DT_VERNEED.
2323                  *
2324                  * The Solaris ld does not produce DT_VERSYM, but the GNU ld
2325                  * does, in order to support their style of versioning, which
2326                  * differs from ours:
2327                  *
2328                  *      - The top bit of the 16-bit Versym index is
2329                  *              not part of the version, but is interpreted
2330                  *              as a "hidden bit".
2331                  *
2332                  *      - External (SHN_UNDEF) symbols can have non-zero
2333                  *              Versym values, which specify versions in
2334                  *              referenced objects, via the Verneed section.
2335                  *
2336                  *      - The vna_other field of the Vernaux structures
2337                  *              found in the Verneed section are not zero as
2338                  *              with Solaris, but instead contain the version
2339                  *              index to be used by Versym indices to reference
2340                  *              the given external version.
2341                  *
2342                  * The Solaris ld, rtld, and elfdump programs all interpret the
2343                  * presence of DT_VERSYM as meaning that GNU versioning rules
2344                  * apply to the given file. If DT_VERSYM is not present,
2345                  * then Solaris versioning rules apply. If we should ever need
2346                  * to change our ld so that it does issue DT_VERSYM, then
2347                  * this rule for detecting GNU versioning will no longer work.
2348                  * In that case, we will have to invent a way to explicitly
2349                  * specify the style of versioning in use, perhaps via a
2350                  * new dynamic entry named something like DT_SUNW_VERSIONSTYLE,
2351                  * where the d_un.d_val value specifies which style is to be
2352                  * used.
2353                  */
2354                 if ((flags & (FLG_OF_VERDEF | FLG_OF_NOVERSEC)) ==
2355                     FLG_OF_VERDEF) {
2356                         shdr = ofl->ofl_osverdef->os_shdr;
2357 
2358                         dyn->d_tag = DT_VERDEF;
2359                         dyn->d_un.d_ptr = shdr->sh_addr;
2360                         dyn++;
2361                         dyn->d_tag = DT_VERDEFNUM;
2362                         dyn->d_un.d_ptr = shdr->sh_info;
2363                         dyn++;
2364                 }
2365                 if ((flags & (FLG_OF_VERNEED | FLG_OF_NOVERSEC)) ==
2366                     FLG_OF_VERNEED) {
2367                         shdr = ofl->ofl_osverneed->os_shdr;
2368 
2369                         dyn->d_tag = DT_VERNEED;
2370                         dyn->d_un.d_ptr = shdr->sh_addr;
2371                         dyn++;
2372                         dyn->d_tag = DT_VERNEEDNUM;
2373                         dyn->d_un.d_ptr = shdr->sh_info;
2374                         dyn++;
2375                 }
2376 
2377                 if ((flags & FLG_OF_COMREL) && ofl->ofl_relocrelcnt) {
2378                         dyn->d_tag = ld_targ.t_m.m_rel_dt_count;
2379                         dyn->d_un.d_val = ofl->ofl_relocrelcnt;
2380                         dyn++;
2381                 }
2382                 if (flags & FLG_OF_TEXTREL) {
2383                         /*
2384                          * Only the presence of this entry is used in this
2385                          * implementation, not the value stored.
2386                          */
2387                         dyn->d_tag = DT_TEXTREL;
2388                         dyn->d_un.d_val = 0;
2389                         dyn++;
2390                 }
2391 
2392                 if (ofl->ofl_osfiniarray) {
2393                         shdr = ofl->ofl_osfiniarray->os_shdr;
2394 
2395                         dyn->d_tag = DT_FINI_ARRAY;
2396                         dyn->d_un.d_ptr = shdr->sh_addr;
2397                         dyn++;
2398 
2399                         dyn->d_tag = DT_FINI_ARRAYSZ;
2400                         dyn->d_un.d_val = shdr->sh_size;
2401                         dyn++;
2402                 }
2403 
2404                 if (ofl->ofl_osinitarray) {
2405                         shdr = ofl->ofl_osinitarray->os_shdr;
2406 
2407                         dyn->d_tag = DT_INIT_ARRAY;
2408                         dyn->d_un.d_ptr = shdr->sh_addr;
2409                         dyn++;
2410 
2411                         dyn->d_tag = DT_INIT_ARRAYSZ;
2412                         dyn->d_un.d_val = shdr->sh_size;
2413                         dyn++;
2414                 }
2415 
2416                 if (ofl->ofl_ospreinitarray) {
2417                         shdr = ofl->ofl_ospreinitarray->os_shdr;
2418 
2419                         dyn->d_tag = DT_PREINIT_ARRAY;
2420                         dyn->d_un.d_ptr = shdr->sh_addr;
2421                         dyn++;
2422 
2423                         dyn->d_tag = DT_PREINIT_ARRAYSZ;
2424                         dyn->d_un.d_val = shdr->sh_size;
2425                         dyn++;
2426                 }
2427 
2428                 if (ofl->ofl_pltcnt) {
2429                         shdr = ofl->ofl_osplt->os_relosdesc->os_shdr;
2430 
2431                         dyn->d_tag = DT_PLTRELSZ;
2432                         dyn->d_un.d_ptr = shdr->sh_size;
2433                         dyn++;
2434                         dyn->d_tag = DT_PLTREL;
2435                         dyn->d_un.d_ptr = ld_targ.t_m.m_rel_dt_type;
2436                         dyn++;
2437                         dyn->d_tag = DT_JMPREL;
2438                         dyn->d_un.d_ptr = shdr->sh_addr;
2439                         dyn++;
2440                 }
2441                 if (ofl->ofl_pltpad) {
2442                         shdr = ofl->ofl_osplt->os_shdr;
2443 
2444                         dyn->d_tag = DT_PLTPAD;
2445                         if (ofl->ofl_pltcnt) {
2446                                 dyn->d_un.d_ptr = shdr->sh_addr +
2447                                     ld_targ.t_m.m_plt_reservsz +
2448                                     ofl->ofl_pltcnt * ld_targ.t_m.m_plt_entsize;
2449                         } else
2450                                 dyn->d_un.d_ptr = shdr->sh_addr;
2451                         dyn++;
2452                         dyn->d_tag = DT_PLTPADSZ;
2453                         dyn->d_un.d_val = ofl->ofl_pltpad *
2454                             ld_targ.t_m.m_plt_entsize;
2455                         dyn++;
2456                 }
2457                 if (ofl->ofl_relocsz) {
2458                         shdr = ofl->ofl_osrelhead->os_shdr;
2459 
2460                         dyn->d_tag = ld_targ.t_m.m_rel_dt_type;
2461                         dyn->d_un.d_ptr = shdr->sh_addr;
2462                         dyn++;
2463                         dyn->d_tag = ld_targ.t_m.m_rel_dt_size;
2464                         dyn->d_un.d_ptr = ofl->ofl_relocsz;
2465                         dyn++;
2466                         dyn->d_tag = ld_targ.t_m.m_rel_dt_ent;
2467                         if (shdr->sh_type == SHT_REL)
2468                                 dyn->d_un.d_ptr = sizeof (Rel);
2469                         else
2470                                 dyn->d_un.d_ptr = sizeof (Rela);
2471                         dyn++;
2472                 }
2473                 if (ofl->ofl_ossyminfo) {
2474                         shdr = ofl->ofl_ossyminfo->os_shdr;
2475 
2476                         dyn->d_tag = DT_SYMINFO;
2477                         dyn->d_un.d_ptr = shdr->sh_addr;
2478                         dyn++;
2479                         dyn->d_tag = DT_SYMINSZ;
2480                         dyn->d_un.d_val = shdr->sh_size;
2481                         dyn++;
2482                         dyn->d_tag = DT_SYMINENT;
2483                         dyn->d_un.d_val = sizeof (Syminfo);
2484                         dyn++;
2485                 }
2486                 if (ofl->ofl_osmove) {
2487                         shdr = ofl->ofl_osmove->os_shdr;
2488 
2489                         dyn->d_tag = DT_MOVETAB;
2490                         dyn->d_un.d_val = shdr->sh_addr;
2491                         dyn++;
2492                         dyn->d_tag = DT_MOVESZ;
2493                         dyn->d_un.d_val = shdr->sh_size;
2494                         dyn++;
2495                         dyn->d_tag = DT_MOVEENT;
2496                         dyn->d_un.d_val = shdr->sh_entsize;
2497                         dyn++;
2498                 }
2499                 if (ofl->ofl_regsymcnt) {
2500                         int     ndx;
2501 
2502                         for (ndx = 0; ndx < ofl->ofl_regsymsno; ndx++) {
2503                                 if ((sdp = ofl->ofl_regsyms[ndx]) == NULL)
2504                                         continue;
2505 
2506                                 dyn->d_tag = ld_targ.t_m.m_dt_register;
2507                                 dyn->d_un.d_val = sdp->sd_symndx;
2508                                 dyn++;
2509                         }
2510                 }
2511 
2512                 for (APLIST_TRAVERSE(ofl->ofl_rtldinfo, idx, sdp)) {
2513                         dyn->d_tag = DT_SUNW_RTLDINF;
2514                         dyn->d_un.d_ptr = sdp->sd_sym->st_value;
2515                         dyn++;
2516                 }
2517 
2518                 if (((sgp = ofl->ofl_osdynamic->os_sgdesc) != NULL) &&
2519                     (sgp->sg_phdr.p_flags & PF_W) && ofl->ofl_osinterp) {
2520                         dyn->d_tag = DT_DEBUG;
2521                         dyn->d_un.d_ptr = 0;
2522                         dyn++;
2523                 }
2524 
2525                 if (ofl->ofl_oscap) {
2526                         dyn->d_tag = DT_SUNW_CAP;
2527                         dyn->d_un.d_val = ofl->ofl_oscap->os_shdr->sh_addr;
2528                         dyn++;
2529                 }
2530                 if (ofl->ofl_oscapinfo) {
2531                         dyn->d_tag = DT_SUNW_CAPINFO;
2532                         dyn->d_un.d_val = ofl->ofl_oscapinfo->os_shdr->sh_addr;
2533                         dyn++;
2534                 }
2535                 if (ofl->ofl_oscapchain) {
2536                         shdr = ofl->ofl_oscapchain->os_shdr;
2537 
2538                         dyn->d_tag = DT_SUNW_CAPCHAIN;
2539                         dyn->d_un.d_val = shdr->sh_addr;
2540                         dyn++;
2541                         dyn->d_tag = DT_SUNW_CAPCHAINSZ;
2542                         dyn->d_un.d_val = shdr->sh_size;
2543                         dyn++;
2544                         dyn->d_tag = DT_SUNW_CAPCHAINENT;
2545                         dyn->d_un.d_val = shdr->sh_entsize;
2546                         dyn++;
2547                 }
2548 
2549                 if (ofl->ofl_aslr != 0) {
2550                         dyn->d_tag = DT_SUNW_ASLR;
2551                         dyn->d_un.d_val = (ofl->ofl_aslr == 1);
2552                         dyn++;
2553                 }
2554 
2555                 if (flags & FLG_OF_SYMBOLIC) {
2556                         dyn->d_tag = DT_SYMBOLIC;
2557                         dyn->d_un.d_val = 0;
2558                         dyn++;
2559                 }
2560         }
2561 
2562         dyn->d_tag = DT_FLAGS;
2563         dyn->d_un.d_val = ofl->ofl_dtflags;
2564         dyn++;
2565 
2566         /*
2567          * If -Bdirect was specified, but some NODIRECT symbols were specified
2568          * via a mapfile, or -znodirect was used on the command line, then
2569          * clear the DF_1_DIRECT flag.  The resultant object will use per-symbol
2570          * direct bindings rather than be enabled for global direct bindings.
2571          *
2572          * If any no-direct bindings exist within this object, set the
2573          * DF_1_NODIRECT flag.  ld(1) recognizes this flag when processing
2574          * dependencies, and performs extra work to ensure that no direct
2575          * bindings are established to the no-direct symbols that exist
2576          * within these dependencies.
2577          */
2578         if (ofl->ofl_flags1 & FLG_OF1_NGLBDIR)
2579                 ofl->ofl_dtflags_1 &= ~DF_1_DIRECT;
2580         if (ofl->ofl_flags1 & FLG_OF1_NDIRECT)
2581                 ofl->ofl_dtflags_1 |= DF_1_NODIRECT;
2582 
2583         dyn->d_tag = DT_FLAGS_1;
2584         dyn->d_un.d_val = ofl->ofl_dtflags_1;
2585         dyn++;
2586 
2587         dyn->d_tag = DT_SUNW_STRPAD;
2588         dyn->d_un.d_val = DYNSTR_EXTRA_PAD;
2589         dyn++;
2590 
2591         dyn->d_tag = DT_SUNW_LDMACH;
2592         dyn->d_un.d_val = ld_sunw_ldmach();
2593         dyn++;
2594 
2595         if (ofl->ofl_flags & FLG_OF_KMOD) {
2596                 dyn->d_tag = DT_SUNW_KMOD;
2597                 dyn->d_un.d_val = 1;
2598                 dyn++;
2599         }
2600 
2601         (*ld_targ.t_mr.mr_mach_update_odynamic)(ofl, &dyn);
2602 
2603         for (cnt = 1 + DYNAMIC_EXTRA_ELTS; cnt--; dyn++) {
2604                 dyn->d_tag = DT_NULL;
2605                 dyn->d_un.d_val = 0;
2606         }
2607 
2608         /*
2609          * Ensure that we wrote the right number of entries. If not, we either
2610          * miscounted in make_dynamic(), or we did something wrong in this
2611          * function.
2612          */
2613         assert((ofl->ofl_osdynamic->os_shdr->sh_size /
2614             ofl->ofl_osdynamic->os_shdr->sh_entsize) ==
2615             ((uintptr_t)dyn - (uintptr_t)_dyn) / sizeof (*dyn));
2616 
2617         return (1);
2618 }
2619 
2620 /*
2621  * Build the version definition section
2622  */
2623 static int
2624 update_overdef(Ofl_desc *ofl)
2625 {
2626         Aliste          idx1;
2627         Ver_desc        *vdp, *_vdp;
2628         Verdef          *vdf, *_vdf;
2629         int             num = 0;
2630         Os_desc         *strosp;
2631         Str_tbl         *strtbl;
2632 
2633         /*
2634          * Determine which string table to use.
2635          */
2636         if (OFL_IS_STATIC_OBJ(ofl)) {
2637                 strtbl = ofl->ofl_strtab;
2638                 strosp = ofl->ofl_osstrtab;
2639         } else {
2640                 strtbl = ofl->ofl_dynstrtab;
2641                 strosp = ofl->ofl_osdynstr;
2642         }
2643 
2644         /*
2645          * Traverse the version descriptors and update the version structures
2646          * to point to the dynstr name in preparation for building the version
2647          * section structure.
2648          */
2649         for (APLIST_TRAVERSE(ofl->ofl_verdesc, idx1, vdp)) {
2650                 Sym_desc        *sdp;
2651 
2652                 if (vdp->vd_flags & VER_FLG_BASE) {
2653                         const char      *name = vdp->vd_name;
2654                         size_t          stoff;
2655 
2656                         /*
2657                          * Create a new string table entry to represent the base
2658                          * version name (there is no corresponding symbol for
2659                          * this).
2660                          */
2661                         (void) st_setstring(strtbl, name, &stoff);
2662                         /* LINTED */
2663                         vdp->vd_name = (const char *)stoff;
2664                 } else {
2665                         sdp = ld_sym_find(vdp->vd_name, vdp->vd_hash, 0, ofl);
2666                         /* LINTED */
2667                         vdp->vd_name = (const char *)
2668                             (uintptr_t)sdp->sd_sym->st_name;
2669                 }
2670         }
2671 
2672         _vdf = vdf = (Verdef *)ofl->ofl_osverdef->os_outdata->d_buf;
2673 
2674         /*
2675          * Traverse the version descriptors and update the version section to
2676          * reflect each version and its associated dependencies.
2677          */
2678         for (APLIST_TRAVERSE(ofl->ofl_verdesc, idx1, vdp)) {
2679                 Aliste          idx2;
2680                 Half            cnt = 1;
2681                 Verdaux         *vdap, *_vdap;
2682 
2683                 _vdap = vdap = (Verdaux *)(vdf + 1);
2684 
2685                 vdf->vd_version = VER_DEF_CURRENT;
2686                 vdf->vd_flags        = vdp->vd_flags & MSK_VER_USER;
2687                 vdf->vd_ndx  = vdp->vd_ndx;
2688                 vdf->vd_hash = vdp->vd_hash;
2689 
2690                 /* LINTED */
2691                 vdap->vda_name = (uintptr_t)vdp->vd_name;
2692                 vdap++;
2693                 /* LINTED */
2694                 _vdap->vda_next = (Word)((uintptr_t)vdap - (uintptr_t)_vdap);
2695 
2696                 /*
2697                  * Traverse this versions dependency list generating the
2698                  * appropriate version dependency entries.
2699                  */
2700                 for (APLIST_TRAVERSE(vdp->vd_deps, idx2, _vdp)) {
2701                         /* LINTED */
2702                         vdap->vda_name = (uintptr_t)_vdp->vd_name;
2703                         _vdap = vdap;
2704                         vdap++, cnt++;
2705                         /* LINTED */
2706                         _vdap->vda_next = (Word)((uintptr_t)vdap -
2707                             (uintptr_t)_vdap);
2708                 }
2709                 _vdap->vda_next = 0;
2710 
2711                 /*
2712                  * Record the versions auxiliary array offset and the associated
2713                  * dependency count.
2714                  */
2715                 /* LINTED */
2716                 vdf->vd_aux = (Word)((uintptr_t)(vdf + 1) - (uintptr_t)vdf);
2717                 vdf->vd_cnt = cnt;
2718 
2719                 /*
2720                  * Record the next versions offset and update the version
2721                  * pointer.  Remember the previous version offset as the very
2722                  * last structures next pointer should be null.
2723                  */
2724                 _vdf = vdf;
2725                 vdf = (Verdef *)vdap, num++;
2726                 /* LINTED */
2727                 _vdf->vd_next = (Word)((uintptr_t)vdf - (uintptr_t)_vdf);
2728         }
2729         _vdf->vd_next = 0;
2730 
2731         /*
2732          * Record the string table association with the version definition
2733          * section, and the symbol table associated with the version symbol
2734          * table (the actual contents of the version symbol table are filled
2735          * in during symbol update).
2736          */
2737         /* LINTED */
2738         ofl->ofl_osverdef->os_shdr->sh_link = (Word)elf_ndxscn(strosp->os_scn);
2739 
2740         /*
2741          * The version definition sections `info' field is used to indicate the
2742          * number of entries in this section.
2743          */
2744         ofl->ofl_osverdef->os_shdr->sh_info = num;
2745 
2746         return (1);
2747 }
2748 
2749 /*
2750  * Finish the version symbol index section
2751  */
2752 static void
2753 update_oversym(Ofl_desc *ofl)
2754 {
2755         Os_desc         *osp;
2756 
2757         /*
2758          * Record the symbol table associated with the version symbol table.
2759          * The contents of the version symbol table are filled in during
2760          * symbol update.
2761          */
2762         if (OFL_IS_STATIC_OBJ(ofl))
2763                 osp = ofl->ofl_ossymtab;
2764         else
2765                 osp = ofl->ofl_osdynsym;
2766 
2767         /* LINTED */
2768         ofl->ofl_osversym->os_shdr->sh_link = (Word)elf_ndxscn(osp->os_scn);
2769 }
2770 
2771 /*
2772  * Build the version needed section
2773  */
2774 static int
2775 update_overneed(Ofl_desc *ofl)
2776 {
2777         Aliste          idx1;
2778         Ifl_desc        *ifl;
2779         Verneed         *vnd, *_vnd;
2780         Os_desc         *strosp;
2781         Str_tbl         *strtbl;
2782         Word            num = 0;
2783 
2784         _vnd = vnd = (Verneed *)ofl->ofl_osverneed->os_outdata->d_buf;
2785 
2786         /*
2787          * Determine which string table is appropriate.
2788          */
2789         if (OFL_IS_STATIC_OBJ(ofl)) {
2790                 strosp = ofl->ofl_osstrtab;
2791                 strtbl = ofl->ofl_strtab;
2792         } else {
2793                 strosp = ofl->ofl_osdynstr;
2794                 strtbl = ofl->ofl_dynstrtab;
2795         }
2796 
2797         /*
2798          * Traverse the shared object list looking for dependencies that have
2799          * versions defined within them.
2800          */
2801         for (APLIST_TRAVERSE(ofl->ofl_sos, idx1, ifl)) {
2802                 Half            _cnt;
2803                 Word            cnt = 0;
2804                 Vernaux         *_vnap, *vnap;
2805                 size_t          stoff;
2806 
2807                 if (!(ifl->ifl_flags & FLG_IF_VERNEED))
2808                         continue;
2809 
2810                 vnd->vn_version = VER_NEED_CURRENT;
2811 
2812                 (void) st_setstring(strtbl, ifl->ifl_soname, &stoff);
2813                 vnd->vn_file = stoff;
2814 
2815                 _vnap = vnap = (Vernaux *)(vnd + 1);
2816 
2817                 /*
2818                  * Traverse the version index list recording
2819                  * each version as a needed dependency.
2820                  */
2821                 for (_cnt = 0; _cnt <= ifl->ifl_vercnt; _cnt++) {
2822                         Ver_index       *vip = &ifl->ifl_verndx[_cnt];
2823 
2824                         if (vip->vi_flags & FLG_VER_REFER) {
2825                                 (void) st_setstring(strtbl, vip->vi_name,
2826                                     &stoff);
2827                                 vnap->vna_name = stoff;
2828 
2829                                 if (vip->vi_desc) {
2830                                         vnap->vna_hash = vip->vi_desc->vd_hash;
2831                                         vnap->vna_flags =
2832                                             vip->vi_desc->vd_flags;
2833                                 } else {
2834                                         vnap->vna_hash = 0;
2835                                         vnap->vna_flags = 0;
2836                                 }
2837                                 vnap->vna_other = vip->vi_overndx;
2838 
2839                                 /*
2840                                  * If version A inherits version B, then
2841                                  * B is implicit in A. It suffices for ld.so.1
2842                                  * to verify A at runtime and skip B. The
2843                                  * version normalization process sets the INFO
2844                                  * flag for the versions we want ld.so.1 to
2845                                  * skip.
2846                                  */
2847                                 if (vip->vi_flags & VER_FLG_INFO)
2848                                         vnap->vna_flags |= VER_FLG_INFO;
2849 
2850                                 _vnap = vnap;
2851                                 vnap++, cnt++;
2852                                 _vnap->vna_next =
2853                                     /* LINTED */
2854                                     (Word)((uintptr_t)vnap - (uintptr_t)_vnap);
2855                         }
2856                 }
2857 
2858                 _vnap->vna_next = 0;
2859 
2860                 /*
2861                  * Record the versions auxiliary array offset and
2862                  * the associated dependency count.
2863                  */
2864                 /* LINTED */
2865                 vnd->vn_aux = (Word)((uintptr_t)(vnd + 1) - (uintptr_t)vnd);
2866                 /* LINTED */
2867                 vnd->vn_cnt = (Half)cnt;
2868 
2869                 /*
2870                  * Record the next versions offset and update the version
2871                  * pointer.  Remember the previous version offset as the very
2872                  * last structures next pointer should be null.
2873                  */
2874                 _vnd = vnd;
2875                 vnd = (Verneed *)vnap, num++;
2876                 /* LINTED */
2877                 _vnd->vn_next = (Word)((uintptr_t)vnd - (uintptr_t)_vnd);
2878         }
2879         _vnd->vn_next = 0;
2880 
2881         /*
2882          * Use sh_link to record the associated string table section, and
2883          * sh_info to indicate the number of entries contained in the section.
2884          */
2885         /* LINTED */
2886         ofl->ofl_osverneed->os_shdr->sh_link = (Word)elf_ndxscn(strosp->os_scn);
2887         ofl->ofl_osverneed->os_shdr->sh_info = num;
2888 
2889         return (1);
2890 }
2891 
2892 /*
2893  * Update syminfo section.
2894  */
2895 static uintptr_t
2896 update_osyminfo(Ofl_desc *ofl)
2897 {
2898         Os_desc         *symosp, *infosp = ofl->ofl_ossyminfo;
2899         Syminfo         *sip = infosp->os_outdata->d_buf;
2900         Shdr            *shdr = infosp->os_shdr;
2901         char            *strtab;
2902         Aliste          idx;
2903         Sym_desc        *sdp;
2904         Sfltr_desc      *sftp;
2905 
2906         if (ofl->ofl_flags & FLG_OF_RELOBJ) {
2907                 symosp = ofl->ofl_ossymtab;
2908                 strtab = ofl->ofl_osstrtab->os_outdata->d_buf;
2909         } else {
2910                 symosp = ofl->ofl_osdynsym;
2911                 strtab = ofl->ofl_osdynstr->os_outdata->d_buf;
2912         }
2913 
2914         /* LINTED */
2915         infosp->os_shdr->sh_link = (Word)elf_ndxscn(symosp->os_scn);
2916         if (ofl->ofl_osdynamic)
2917                 infosp->os_shdr->sh_info =
2918                     /* LINTED */
2919                     (Word)elf_ndxscn(ofl->ofl_osdynamic->os_scn);
2920 
2921         /*
2922          * Update any references with the index into the dynamic table.
2923          */
2924         for (APLIST_TRAVERSE(ofl->ofl_symdtent, idx, sdp))
2925                 sip[sdp->sd_symndx].si_boundto = sdp->sd_file->ifl_neededndx;
2926 
2927         /*
2928          * Update any filtee references with the index into the dynamic table.
2929          */
2930         for (ALIST_TRAVERSE(ofl->ofl_symfltrs, idx, sftp)) {
2931                 Dfltr_desc      *dftp;
2932 
2933                 dftp = alist_item(ofl->ofl_dtsfltrs, sftp->sft_idx);
2934                 sip[sftp->sft_sdp->sd_symndx].si_boundto = dftp->dft_ndx;
2935         }
2936 
2937         /*
2938          * Display debugging information about section.
2939          */
2940         DBG_CALL(Dbg_syminfo_title(ofl->ofl_lml));
2941         if (DBG_ENABLED) {
2942                 Word    _cnt, cnt = shdr->sh_size / shdr->sh_entsize;
2943                 Sym     *symtab = symosp->os_outdata->d_buf;
2944                 Dyn     *dyn;
2945 
2946                 if (ofl->ofl_osdynamic)
2947                         dyn = ofl->ofl_osdynamic->os_outdata->d_buf;
2948                 else
2949                         dyn = NULL;
2950 
2951                 for (_cnt = 1; _cnt < cnt; _cnt++) {
2952                         if (sip[_cnt].si_flags || sip[_cnt].si_boundto)
2953                                 /* LINTED */
2954                                 DBG_CALL(Dbg_syminfo_entry(ofl->ofl_lml, _cnt,
2955                                     &sip[_cnt], &symtab[_cnt], strtab, dyn));
2956                 }
2957         }
2958         return (1);
2959 }
2960 
2961 /*
2962  * Build the output elf header.
2963  */
2964 static uintptr_t
2965 update_oehdr(Ofl_desc * ofl)
2966 {
2967         Ehdr    *ehdr = ofl->ofl_nehdr;
2968 
2969         /*
2970          * If an entry point symbol has already been established (refer
2971          * sym_validate()) simply update the elf header entry point with the
2972          * symbols value.  If no entry point is defined it will have been filled
2973          * with the start address of the first section within the text segment
2974          * (refer update_outfile()).
2975          */
2976         if (ofl->ofl_entry)
2977                 ehdr->e_entry =
2978                     ((Sym_desc *)(ofl->ofl_entry))->sd_sym->st_value;
2979 
2980         ehdr->e_ident[EI_DATA] = ld_targ.t_m.m_data;
2981         ehdr->e_version = ofl->ofl_dehdr->e_version;
2982 
2983         /*
2984          * When generating a relocatable object under -z symbolcap, set the
2985          * e_machine to be generic, and remove any e_flags.  Input relocatable
2986          * objects may identify alternative e_machine (m.machplus) and e_flags
2987          * values.  However, the functions within the created output object
2988          * are selected at runtime using the capabilities mechanism, which
2989          * supersedes the e-machine and e_flags information.  Therefore,
2990          * e_machine and e_flag values are not propagated to the output object,
2991          * as these values might prevent the kernel from loading the object
2992          * before the runtime linker gets control.
2993          */
2994         if (ofl->ofl_flags & FLG_OF_OTOSCAP) {
2995                 ehdr->e_machine = ld_targ.t_m.m_mach;
2996                 ehdr->e_flags = 0;
2997         } else {
2998                 /*
2999                  * Note. it may be necessary to update the e_flags field in the
3000                  * machine dependent section.
3001                  */
3002                 ehdr->e_machine = ofl->ofl_dehdr->e_machine;
3003                 ehdr->e_flags = ofl->ofl_dehdr->e_flags;
3004 
3005                 if (ehdr->e_machine != ld_targ.t_m.m_mach) {
3006                         if (ehdr->e_machine != ld_targ.t_m.m_machplus)
3007                                 return (S_ERROR);
3008                         if ((ehdr->e_flags & ld_targ.t_m.m_flagsplus) == 0)
3009                                 return (S_ERROR);
3010                 }
3011         }
3012 
3013         if (ofl->ofl_flags & FLG_OF_SHAROBJ)
3014                 ehdr->e_type = ET_DYN;
3015         else if (ofl->ofl_flags & FLG_OF_RELOBJ)
3016                 ehdr->e_type = ET_REL;
3017         else
3018                 ehdr->e_type = ET_EXEC;
3019 
3020         return (1);
3021 }
3022 
3023 /*
3024  * Perform move table expansion.
3025  */
3026 static void
3027 expand_move(Ofl_desc *ofl, Sym_desc *sdp, Move *mvp)
3028 {
3029         Os_desc         *osp;
3030         uchar_t         *taddr, *taddr0;
3031         Sxword          offset;
3032         Half            cnt;
3033         uint_t          stride;
3034 
3035         osp = ofl->ofl_isparexpn->is_osdesc;
3036         offset = sdp->sd_sym->st_value - osp->os_shdr->sh_addr;
3037 
3038         taddr0 = taddr = osp->os_outdata->d_buf;
3039         taddr += offset;
3040         taddr = taddr + mvp->m_poffset;
3041 
3042         for (cnt = 0; cnt < mvp->m_repeat; cnt++) {
3043                 /* LINTED */
3044                 DBG_CALL(Dbg_move_expand(ofl->ofl_lml, mvp,
3045                     (Addr)(taddr - taddr0)));
3046                 stride = (uint_t)mvp->m_stride + 1;
3047 
3048                 /*
3049                  * Update the target address based upon the move entry size.
3050                  * This size was validated in ld_process_move().
3051                  */
3052                 /* LINTED */
3053                 switch (ELF_M_SIZE(mvp->m_info)) {
3054                 case 1:
3055                         /* LINTED */
3056                         *taddr = (uchar_t)mvp->m_value;
3057                         taddr += stride;
3058                         break;
3059                 case 2:
3060                         /* LINTED */
3061                         *((Half *)taddr) = (Half)mvp->m_value;
3062                         taddr += 2 * stride;
3063                         break;
3064                 case 4:
3065                         /* LINTED */
3066                         *((Word *)taddr) = (Word)mvp->m_value;
3067                         taddr += 4 * stride;
3068                         break;
3069                 case 8:
3070                         /* LINTED */
3071                         *((u_longlong_t *)taddr) = mvp->m_value;
3072                         taddr += 8 * stride;
3073                         break;
3074                 }
3075         }
3076 }
3077 
3078 /*
3079  * Update Move sections.
3080  */
3081 static void
3082 update_move(Ofl_desc *ofl)
3083 {
3084         Word            ndx = 0;
3085         ofl_flag_t      flags = ofl->ofl_flags;
3086         Move            *omvp;
3087         Aliste          idx1;
3088         Sym_desc        *sdp;
3089 
3090         /*
3091          * Determine the index of the symbol table that will be referenced by
3092          * the Move section.
3093          */
3094         if (OFL_ALLOW_DYNSYM(ofl))
3095                 /* LINTED */
3096                 ndx = (Word) elf_ndxscn(ofl->ofl_osdynsym->os_scn);
3097         else if (!(flags & FLG_OF_STRIP) || (flags & FLG_OF_RELOBJ))
3098                 /* LINTED */
3099                 ndx = (Word) elf_ndxscn(ofl->ofl_ossymtab->os_scn);
3100 
3101         /*
3102          * Update sh_link of the Move section, and point to the new Move data.
3103          */
3104         if (ofl->ofl_osmove) {
3105                 ofl->ofl_osmove->os_shdr->sh_link = ndx;
3106                 omvp = (Move *)ofl->ofl_osmove->os_outdata->d_buf;
3107         }
3108 
3109         /*
3110          * Update symbol entry index
3111          */
3112         for (APLIST_TRAVERSE(ofl->ofl_parsyms, idx1, sdp)) {
3113                 Aliste          idx2;
3114                 Mv_desc         *mdp;
3115 
3116                 /*
3117                  * Expand move table
3118                  */
3119                 if (sdp->sd_flags & FLG_SY_PAREXPN) {
3120                         const char      *str;
3121 
3122                         if (flags & FLG_OF_STATIC)
3123                                 str = MSG_INTL(MSG_PSYM_EXPREASON1);
3124                         else if (ofl->ofl_flags1 & FLG_OF1_NOPARTI)
3125                                 str = MSG_INTL(MSG_PSYM_EXPREASON2);
3126                         else
3127                                 str = MSG_INTL(MSG_PSYM_EXPREASON3);
3128 
3129                         DBG_CALL(Dbg_move_parexpn(ofl->ofl_lml,
3130                             sdp->sd_name, str));
3131 
3132                         for (ALIST_TRAVERSE(sdp->sd_move, idx2, mdp)) {
3133                                 DBG_CALL(Dbg_move_entry1(ofl->ofl_lml, 0,
3134                                     mdp->md_move, sdp));
3135                                 expand_move(ofl, sdp, mdp->md_move);
3136                         }
3137                         continue;
3138                 }
3139 
3140                 /*
3141                  * Process move table
3142                  */
3143                 DBG_CALL(Dbg_move_outmove(ofl->ofl_lml, sdp->sd_name));
3144 
3145                 for (ALIST_TRAVERSE(sdp->sd_move, idx2, mdp)) {
3146                         Move    *imvp;
3147                         int     idx = 1;
3148                         Sym     *sym;
3149 
3150                         imvp = mdp->md_move;
3151                         sym = sdp->sd_sym;
3152 
3153                         DBG_CALL(Dbg_move_entry1(ofl->ofl_lml, 1, imvp, sdp));
3154 
3155                         *omvp = *imvp;
3156                         if ((flags & FLG_OF_RELOBJ) == 0) {
3157                                 if (ELF_ST_BIND(sym->st_info) == STB_LOCAL) {
3158                                         Os_desc *osp = sdp->sd_isc->is_osdesc;
3159                                         Word    ndx = osp->os_identndx;
3160 
3161                                         omvp->m_info =
3162                                             /* LINTED */
3163                                             ELF_M_INFO(ndx, imvp->m_info);
3164 
3165                                         if (ELF_ST_TYPE(sym->st_info) !=
3166                                             STT_SECTION) {
3167                                                 omvp->m_poffset =
3168                                                     sym->st_value -
3169                                                     osp->os_shdr->sh_addr +
3170                                                     imvp->m_poffset;
3171                                         }
3172                                 } else {
3173                                         omvp->m_info =
3174                                             /* LINTED */
3175                                             ELF_M_INFO(sdp->sd_symndx,
3176                                             imvp->m_info);
3177                                 }
3178                         } else {
3179                                 Boolean         isredloc = FALSE;
3180 
3181                                 if ((ELF_ST_BIND(sym->st_info) == STB_LOCAL) &&
3182                                     (ofl->ofl_flags & FLG_OF_REDLSYM))
3183                                         isredloc = TRUE;
3184 
3185                                 if (isredloc && !(sdp->sd_move)) {
3186                                         Os_desc *osp = sdp->sd_isc->is_osdesc;
3187                                         Word    ndx = osp->os_identndx;
3188 
3189                                         omvp->m_info =
3190                                             /* LINTED */
3191                                             ELF_M_INFO(ndx, imvp->m_info);
3192 
3193                                         omvp->m_poffset += sym->st_value;
3194                                 } else {
3195                                         if (isredloc)
3196                                                 DBG_CALL(Dbg_syms_reduce(ofl,
3197                                                     DBG_SYM_REDUCE_RETAIN,
3198                                                     sdp, idx,
3199                                                     ofl->ofl_osmove->os_name));
3200 
3201                                         omvp->m_info =
3202                                             /* LINTED */
3203                                             ELF_M_INFO(sdp->sd_symndx,
3204                                             imvp->m_info);
3205                                 }
3206                         }
3207 
3208                         DBG_CALL(Dbg_move_entry1(ofl->ofl_lml, 0, omvp, sdp));
3209                         omvp++;
3210                         idx++;
3211                 }
3212         }
3213 }
3214 
3215 /*
3216  * Scan through the SHT_GROUP output sections.  Update their sh_link/sh_info
3217  * fields as well as the section contents.
3218  */
3219 static uintptr_t
3220 update_ogroup(Ofl_desc *ofl)
3221 {
3222         Aliste          idx;
3223         Os_desc         *osp;
3224         uintptr_t       error = 0;
3225 
3226         for (APLIST_TRAVERSE(ofl->ofl_osgroups, idx, osp)) {
3227                 Is_desc         *isp;
3228                 Ifl_desc        *ifl;
3229                 Shdr            *shdr = osp->os_shdr;
3230                 Sym_desc        *sdp;
3231                 Xword           i, grpcnt;
3232                 Word            *gdata;
3233 
3234                 /*
3235                  * Since input GROUP sections always create unique
3236                  * output GROUP sections - we know there is only one
3237                  * item on the list.
3238                  */
3239                 isp = ld_os_first_isdesc(osp);
3240 
3241                 ifl = isp->is_file;
3242                 sdp = ifl->ifl_oldndx[isp->is_shdr->sh_info];
3243                 shdr->sh_link = (Word)elf_ndxscn(ofl->ofl_ossymtab->os_scn);
3244                 shdr->sh_info = sdp->sd_symndx;
3245 
3246                 /*
3247                  * Scan through the group data section and update
3248                  * all of the links to new values.
3249                  */
3250                 grpcnt = shdr->sh_size / shdr->sh_entsize;
3251                 gdata = (Word *)osp->os_outdata->d_buf;
3252 
3253                 for (i = 1; i < grpcnt; i++) {
3254                         Os_desc *_osp;
3255                         Is_desc *_isp = ifl->ifl_isdesc[gdata[i]];
3256 
3257                         /*
3258                          * If the referenced section didn't make it to the
3259                          * output file - just zero out the entry.
3260                          */
3261                         if ((_osp = _isp->is_osdesc) == NULL)
3262                                 gdata[i] = 0;
3263                         else
3264                                 gdata[i] = (Word)elf_ndxscn(_osp->os_scn);
3265                 }
3266         }
3267         return (error);
3268 }
3269 
3270 static void
3271 update_ostrtab(Os_desc *osp, Str_tbl *stp, uint_t extra)
3272 {
3273         Elf_Data        *data;
3274 
3275         if (osp == NULL)
3276                 return;
3277 
3278         data = osp->os_outdata;
3279         assert(data->d_size == (st_getstrtab_sz(stp) + extra));
3280         (void) st_setstrbuf(stp, data->d_buf, data->d_size - extra);
3281         /* If leaving an extra hole at the end, zero it */
3282         if (extra > 0)
3283                 (void) memset((char *)data->d_buf + data->d_size - extra,
3284                     0x0, extra);
3285 }
3286 
3287 /*
3288  * Update capabilities information.
3289  *
3290  * If string table capabilities exist, then the associated string must be
3291  * translated into an offset into the string table.
3292  */
3293 static void
3294 update_oscap(Ofl_desc *ofl)
3295 {
3296         Os_desc         *strosp, *cosp;
3297         Cap             *cap;
3298         Str_tbl         *strtbl;
3299         Capstr          *capstr;
3300         size_t          stoff;
3301         Aliste          idx1;
3302 
3303         /*
3304          * Determine which symbol table or string table is appropriate.
3305          */
3306         if (OFL_IS_STATIC_OBJ(ofl)) {
3307                 strosp = ofl->ofl_osstrtab;
3308                 strtbl = ofl->ofl_strtab;
3309         } else {
3310                 strosp = ofl->ofl_osdynstr;
3311                 strtbl = ofl->ofl_dynstrtab;
3312         }
3313 
3314         /*
3315          * If symbol capabilities exist, set the sh_link field of the .SUNW_cap
3316          * section to the .SUNW_capinfo section.
3317          */
3318         if (ofl->ofl_oscapinfo) {
3319                 cosp = ofl->ofl_oscap;
3320                 cosp->os_shdr->sh_link =
3321                     (Word)elf_ndxscn(ofl->ofl_oscapinfo->os_scn);
3322         }
3323 
3324         /*
3325          * If there are capability strings to process, set the sh_info
3326          * field of the .SUNW_cap section to the associated string table, and
3327          * proceed to process any CA_SUNW_PLAT entries.
3328          */
3329         if ((ofl->ofl_flags & FLG_OF_CAPSTRS) == 0)
3330                 return;
3331 
3332         cosp = ofl->ofl_oscap;
3333         cosp->os_shdr->sh_info = (Word)elf_ndxscn(strosp->os_scn);
3334 
3335         cap = ofl->ofl_oscap->os_outdata->d_buf;
3336 
3337         /*
3338          * Determine whether an object capability identifier, or object
3339          * machine/platform capabilities exists.
3340          */
3341         capstr = &ofl->ofl_ocapset.oc_id;
3342         if (capstr->cs_str) {
3343                 (void) st_setstring(strtbl, capstr->cs_str, &stoff);
3344                 cap[capstr->cs_ndx].c_un.c_ptr = stoff;
3345         }
3346         for (ALIST_TRAVERSE(ofl->ofl_ocapset.oc_plat.cl_val, idx1, capstr)) {
3347                 (void) st_setstring(strtbl, capstr->cs_str, &stoff);
3348                 cap[capstr->cs_ndx].c_un.c_ptr = stoff;
3349         }
3350         for (ALIST_TRAVERSE(ofl->ofl_ocapset.oc_mach.cl_val, idx1, capstr)) {
3351                 (void) st_setstring(strtbl, capstr->cs_str, &stoff);
3352                 cap[capstr->cs_ndx].c_un.c_ptr = stoff;
3353         }
3354 
3355         /*
3356          * Determine any symbol capability identifiers, or machine/platform
3357          * capabilities.
3358          */
3359         if (ofl->ofl_capgroups) {
3360                 Cap_group       *cgp;
3361 
3362                 for (APLIST_TRAVERSE(ofl->ofl_capgroups, idx1, cgp)) {
3363                         Objcapset       *ocapset = &cgp->cg_set;
3364                         Aliste          idx2;
3365 
3366                         capstr = &ocapset->oc_id;
3367                         if (capstr->cs_str) {
3368                                 (void) st_setstring(strtbl, capstr->cs_str,
3369                                     &stoff);
3370                                 cap[capstr->cs_ndx].c_un.c_ptr = stoff;
3371                         }
3372                         for (ALIST_TRAVERSE(ocapset->oc_plat.cl_val, idx2,
3373                             capstr)) {
3374                                 (void) st_setstring(strtbl, capstr->cs_str,
3375                                     &stoff);
3376                                 cap[capstr->cs_ndx].c_un.c_ptr = stoff;
3377                         }
3378                         for (ALIST_TRAVERSE(ocapset->oc_mach.cl_val, idx2,
3379                             capstr)) {
3380                                 (void) st_setstring(strtbl, capstr->cs_str,
3381                                     &stoff);
3382                                 cap[capstr->cs_ndx].c_un.c_ptr = stoff;
3383                         }
3384                 }
3385         }
3386 }
3387 
3388 /*
3389  * Update the .SUNW_capinfo, and possibly the .SUNW_capchain sections.
3390  */
3391 static void
3392 update_oscapinfo(Ofl_desc *ofl)
3393 {
3394         Os_desc         *symosp, *ciosp, *ccosp = NULL;
3395         Capinfo         *ocapinfo;
3396         Capchain        *ocapchain;
3397         Cap_avlnode     *cav;
3398         Word            chainndx = 0;
3399 
3400         /*
3401          * Determine which symbol table is appropriate.
3402          */
3403         if (OFL_IS_STATIC_OBJ(ofl))
3404                 symosp = ofl->ofl_ossymtab;
3405         else
3406                 symosp = ofl->ofl_osdynsym;
3407 
3408         /*
3409          * Update the .SUNW_capinfo sh_link to point to the appropriate symbol
3410          * table section.  If we're creating a dynamic object, the
3411          * .SUNW_capinfo sh_info is updated to point to the .SUNW_capchain
3412          * section.
3413          */
3414         ciosp = ofl->ofl_oscapinfo;
3415         ciosp->os_shdr->sh_link = (Word)elf_ndxscn(symosp->os_scn);
3416 
3417         if (OFL_IS_STATIC_OBJ(ofl) == 0) {
3418                 ccosp = ofl->ofl_oscapchain;
3419                 ciosp->os_shdr->sh_info = (Word)elf_ndxscn(ccosp->os_scn);
3420         }
3421 
3422         /*
3423          * Establish the data for each section.  The first element of each
3424          * section defines the section's version number.
3425          */
3426         ocapinfo = ciosp->os_outdata->d_buf;
3427         ocapinfo[0] = CAPINFO_CURRENT;
3428         if (ccosp) {
3429                 ocapchain = ccosp->os_outdata->d_buf;
3430                 ocapchain[chainndx++] = CAPCHAIN_CURRENT;
3431         }
3432 
3433         /*
3434          * Traverse all capabilities families.  Each member has a .SUNW_capinfo
3435          * assignment.  The .SUNW_capinfo entry differs for relocatable objects
3436          * and dynamic objects.
3437          *
3438          * Relocatable objects:
3439          *                      ELF_C_GROUP             ELF_C_SYM
3440          *
3441          * Family lead:         CAPINFO_SUNW_GLOB       lead symbol index
3442          * Family lead alias:   CAPINFO_SUNW_GLOB       lead symbol index
3443          * Family member:       .SUNW_cap index         lead symbol index
3444          *
3445          * Dynamic objects:
3446          *                      ELF_C_GROUP             ELF_C_SYM
3447          *
3448          * Family lead:         CAPINFO_SUNW_GLOB       .SUNW_capchain index
3449          * Family lead alias:   CAPINFO_SUNW_GLOB       .SUNW_capchain index
3450          * Family member:       .SUNW_cap index         lead symbol index
3451          *
3452          * The ELF_C_GROUP field identifies a capabilities symbol.  Lead
3453          * capability symbols, and lead capability aliases are identified by
3454          * a CAPINFO_SUNW_GLOB group identifier.  For family members, the
3455          * ELF_C_GROUP provides an index to the associate capabilities group
3456          * (i.e, an index into the SUNW_cap section that defines a group).
3457          *
3458          * For relocatable objects, the ELF_C_SYM field identifies the lead
3459          * capability symbol.  For the lead symbol itself, the .SUNW_capinfo
3460          * index is the same as the ELF_C_SYM value.  For lead alias symbols,
3461          * the .SUNW_capinfo index differs from the ELF_C_SYM value.  This
3462          * differentiation of CAPINFO_SUNW_GLOB symbols allows ld(1) to
3463          * identify, and propagate lead alias symbols.  For example, the lead
3464          * capability symbol memcpy() would have the ELF_C_SYM for memcpy(),
3465          * and the lead alias _memcpy() would also have the ELF_C_SYM for
3466          * memcpy().
3467          *
3468          * For dynamic objects, both a lead capability symbol, and alias symbol
3469          * would have a ELF_C_SYM value that represents the same capability
3470          * chain index.  The capability chain allows ld.so.1 to traverse a
3471          * family chain for a given lead symbol, and select the most appropriate
3472          * family member.  The .SUNW_capchain array contains a series of symbol
3473          * indexes for each family member:
3474          *
3475          *    chaincap[n]  chaincap[n + 1]  chaincap[n + 2]  chaincap[n + x]
3476          *      foo() ndx    foo%x() ndx        foo%y() ndx     0
3477          *
3478          * For family members, the ELF_C_SYM value associates the capability
3479          * members with their family lead symbol.  This association, although
3480          * unused within a dynamic object, allows ld(1) to identify, and
3481          * propagate family members when processing relocatable objects.
3482          */
3483         for (cav = avl_first(ofl->ofl_capfamilies); cav;
3484             cav = AVL_NEXT(ofl->ofl_capfamilies, cav)) {
3485                 Cap_sym         *csp;
3486                 Aliste          idx;
3487                 Sym_desc        *asdp, *lsdp = cav->cn_symavlnode.sav_sdp;
3488 
3489                 if (ccosp) {
3490                         /*
3491                          * For a dynamic object, identify this lead symbol, and
3492                          * point it to the head of a capability chain.  Set the
3493                          * head of the capability chain to the same lead symbol.
3494                          */
3495                         ocapinfo[lsdp->sd_symndx] =
3496                             ELF_C_INFO(chainndx, CAPINFO_SUNW_GLOB);
3497                         ocapchain[chainndx] = lsdp->sd_symndx;
3498                 } else {
3499                         /*
3500                          * For a relocatable object, identify this lead symbol,
3501                          * and set the lead symbol index to itself.
3502                          */
3503                         ocapinfo[lsdp->sd_symndx] =
3504                             ELF_C_INFO(lsdp->sd_symndx, CAPINFO_SUNW_GLOB);
3505                 }
3506 
3507                 /*
3508                  * Gather any lead symbol aliases.
3509                  */
3510                 for (APLIST_TRAVERSE(cav->cn_aliases, idx, asdp)) {
3511                         if (ccosp) {
3512                                 /*
3513                                  * For a dynamic object, identify this lead
3514                                  * alias symbol, and point it to the same
3515                                  * capability chain index as the lead symbol.
3516                                  */
3517                                 ocapinfo[asdp->sd_symndx] =
3518                                     ELF_C_INFO(chainndx, CAPINFO_SUNW_GLOB);
3519                         } else {
3520                                 /*
3521                                  * For a relocatable object, identify this lead
3522                                  * alias symbol, and set the lead symbol index
3523                                  * to the lead symbol.
3524                                  */
3525                                 ocapinfo[asdp->sd_symndx] =
3526                                     ELF_C_INFO(lsdp->sd_symndx,
3527                                     CAPINFO_SUNW_GLOB);
3528                         }
3529                 }
3530 
3531                 chainndx++;
3532 
3533                 /*
3534                  * Gather the family members.
3535                  */
3536                 for (APLIST_TRAVERSE(cav->cn_members, idx, csp)) {
3537                         Sym_desc        *msdp = csp->cs_sdp;
3538 
3539                         /*
3540                          * Identify the members capability group, and the lead
3541                          * symbol of the family this symbol is a member of.
3542                          */
3543                         ocapinfo[msdp->sd_symndx] =
3544                             ELF_C_INFO(lsdp->sd_symndx, csp->cs_group->cg_ndx);
3545                         if (ccosp) {
3546                                 /*
3547                                  * For a dynamic object, set the next capability
3548                                  * chain to point to this family member.
3549                                  */
3550                                 ocapchain[chainndx++] = msdp->sd_symndx;
3551                         }
3552                 }
3553 
3554                 /*
3555                  * Any chain of family members is terminated with a 0 element.
3556                  */
3557                 if (ccosp)
3558                         ocapchain[chainndx++] = 0;
3559         }
3560 }
3561 
3562 /*
3563  * Translate the shdr->sh_{link, info} from its input section value to that
3564  * of the corresponding shdr->sh_{link, info} output section value.
3565  */
3566 static Word
3567 translate_link(Ofl_desc *ofl, Os_desc *osp, Word link, const char *msg)
3568 {
3569         Is_desc         *isp;
3570         Ifl_desc        *ifl;
3571 
3572         /*
3573          * Don't translate the special section numbers.
3574          */
3575         if (link >= SHN_LORESERVE)
3576                 return (link);
3577 
3578         /*
3579          * Does this output section translate back to an input file.  If not
3580          * then there is no translation to do.  In this case we will assume that
3581          * if sh_link has a value, it's the right value.
3582          */
3583         isp = ld_os_first_isdesc(osp);
3584         if ((ifl = isp->is_file) == NULL)
3585                 return (link);
3586 
3587         /*
3588          * Sanity check to make sure that the sh_{link, info} value
3589          * is within range for the input file.
3590          */
3591         if (link >= ifl->ifl_shnum) {
3592                 ld_eprintf(ofl, ERR_WARNING, msg, ifl->ifl_name,
3593                     EC_WORD(isp->is_scnndx), isp->is_name, EC_XWORD(link));
3594                 return (link);
3595         }
3596 
3597         /*
3598          * Follow the link to the input section.
3599          */
3600         if ((isp = ifl->ifl_isdesc[link]) == NULL)
3601                 return (0);
3602         if ((osp = isp->is_osdesc) == NULL)
3603                 return (0);
3604 
3605         /* LINTED */
3606         return ((Word)elf_ndxscn(osp->os_scn));
3607 }
3608 
3609 /*
3610  * Having created all of the necessary sections, segments, and associated
3611  * headers, fill in the program headers and update any other data in the
3612  * output image.  Some general rules:
3613  *
3614  *  -   If an interpreter is required always generate a PT_PHDR entry as
3615  *      well.  It is this entry that triggers the kernel into passing the
3616  *      interpreter an aux vector instead of just a file descriptor.
3617  *
3618  *  -   When generating an image that will be interpreted (ie. a dynamic
3619  *      executable, a shared object, or a static executable that has been
3620  *      provided with an interpreter - weird, but possible), make the initial
3621  *      loadable segment include both the ehdr and phdr[].  Both of these
3622  *      tables are used by the interpreter therefore it seems more intuitive
3623  *      to explicitly defined them as part of the mapped image rather than
3624  *      relying on page rounding by the interpreter to allow their access.
3625  *
3626  *  -   When generating a static image that does not require an interpreter
3627  *      have the first loadable segment indicate the address of the first
3628  *      .section as the start address (things like /kernel/unix and ufsboot
3629  *      expect this behavior).
3630  */
3631 uintptr_t
3632 ld_update_outfile(Ofl_desc *ofl)
3633 {
3634         Addr            size, etext, vaddr;
3635         Sg_desc         *sgp;
3636         Sg_desc         *dtracesgp = NULL, *capsgp = NULL, *intpsgp = NULL;
3637         Os_desc         *osp;
3638         int             phdrndx = 0, segndx = -1, secndx, intppndx, intpsndx;
3639         int             dtracepndx, dtracesndx, cappndx, capsndx;
3640         Ehdr            *ehdr = ofl->ofl_nehdr;
3641         Shdr            *hshdr;
3642         Phdr            *_phdr = NULL;
3643         Word            phdrsz = (ehdr->e_phnum * ehdr->e_phentsize), shscnndx;
3644         ofl_flag_t      flags = ofl->ofl_flags;
3645         Word            ehdrsz = ehdr->e_ehsize;
3646         Boolean         nobits;
3647         Off             offset;
3648         Aliste          idx1;
3649 
3650         /*
3651          * Initialize the starting address for the first segment.  Executables
3652          * have different starting addresses depending upon the target ABI,
3653          * where as shared objects have a starting address of 0.  If this is
3654          * a 64-bit executable that is being constructed to run in a restricted
3655          * address space, use an alternative origin that will provide more free
3656          * address space for the the eventual process.
3657          */
3658         if (ofl->ofl_flags & FLG_OF_EXEC) {
3659 #if     defined(_ELF64)
3660                 if (ofl->ofl_ocapset.oc_sf_1.cm_val & SF1_SUNW_ADDR32)
3661                         vaddr = ld_targ.t_m.m_segm_aorigin;
3662                 else
3663 #endif
3664                         vaddr = ld_targ.t_m.m_segm_origin;
3665         } else
3666                 vaddr = 0;
3667 
3668         /*
3669          * Loop through the segment descriptors and pick out what we need.
3670          */
3671         DBG_CALL(Dbg_seg_title(ofl->ofl_lml));
3672         for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp)) {
3673                 Phdr            *phdr = &(sgp->sg_phdr);
3674                 Xword           p_align;
3675                 Aliste          idx2;
3676                 Sym_desc        *sdp;
3677 
3678                 segndx++;
3679 
3680                 /*
3681                  * If an interpreter is required generate a PT_INTERP and
3682                  * PT_PHDR program header entry.  The PT_PHDR entry describes
3683                  * the program header table itself.  This information will be
3684                  * passed via the aux vector to the interpreter (ld.so.1).
3685                  * The program header array is actually part of the first
3686                  * loadable segment (and the PT_PHDR entry is the first entry),
3687                  * therefore its virtual address isn't known until the first
3688                  * loadable segment is processed.
3689                  */
3690                 if (phdr->p_type == PT_PHDR) {
3691                         if (ofl->ofl_osinterp) {
3692                                 phdr->p_offset = ehdr->e_phoff;
3693                                 phdr->p_filesz = phdr->p_memsz = phdrsz;
3694 
3695                                 DBG_CALL(Dbg_seg_entry(ofl, segndx, sgp));
3696                                 ofl->ofl_phdr[phdrndx++] = *phdr;
3697                         }
3698                         continue;
3699                 }
3700                 if (phdr->p_type == PT_INTERP) {
3701                         if (ofl->ofl_osinterp) {
3702                                 intpsgp = sgp;
3703                                 intpsndx = segndx;
3704                                 intppndx = phdrndx++;
3705                         }
3706                         continue;
3707                 }
3708 
3709                 /*
3710                  * If we are creating a PT_SUNWDTRACE segment, remember where
3711                  * the program header is.  The header values are assigned after
3712                  * update_osym() has completed and the symbol table addresses
3713                  * have been updated.
3714                  */
3715                 if (phdr->p_type == PT_SUNWDTRACE) {
3716                         if (ofl->ofl_dtracesym &&
3717                             ((flags & FLG_OF_RELOBJ) == 0)) {
3718                                 dtracesgp = sgp;
3719                                 dtracesndx = segndx;
3720                                 dtracepndx = phdrndx++;
3721                         }
3722                         continue;
3723                 }
3724 
3725                 /*
3726                  * If a hardware/software capabilities section is required,
3727                  * generate the PT_SUNWCAP header.  Note, as this comes before
3728                  * the first loadable segment, we don't yet know its real
3729                  * virtual address.  This is updated later.
3730                  */
3731                 if (phdr->p_type == PT_SUNWCAP) {
3732                         if (ofl->ofl_oscap && (ofl->ofl_flags & FLG_OF_PTCAP) &&
3733                             ((flags & FLG_OF_RELOBJ) == 0)) {
3734                                 capsgp = sgp;
3735                                 capsndx = segndx;
3736                                 cappndx = phdrndx++;
3737                         }
3738                         continue;
3739                 }
3740 
3741                 /*
3742                  * As the dynamic program header occurs after the loadable
3743                  * headers in the segment descriptor table, all the address
3744                  * information for the .dynamic output section will have been
3745                  * figured out by now.
3746                  */
3747                 if (phdr->p_type == PT_DYNAMIC) {
3748                         if (OFL_ALLOW_DYNSYM(ofl)) {
3749                                 Shdr    *shdr = ofl->ofl_osdynamic->os_shdr;
3750 
3751                                 phdr->p_vaddr = shdr->sh_addr;
3752                                 phdr->p_offset = shdr->sh_offset;
3753                                 phdr->p_filesz = shdr->sh_size;
3754                                 phdr->p_flags = ld_targ.t_m.m_dataseg_perm;
3755 
3756                                 DBG_CALL(Dbg_seg_entry(ofl, segndx, sgp));
3757                                 ofl->ofl_phdr[phdrndx++] = *phdr;
3758                         }
3759                         continue;
3760                 }
3761 
3762                 /*
3763                  * As the unwind (.eh_frame_hdr) program header occurs after
3764                  * the loadable headers in the segment descriptor table, all
3765                  * the address information for the .eh_frame output section
3766                  * will have been figured out by now.
3767                  */
3768                 if (phdr->p_type == PT_SUNW_UNWIND) {
3769                         Shdr        *shdr;
3770 
3771                         if (ofl->ofl_unwindhdr == NULL)
3772                                 continue;
3773 
3774                         shdr = ofl->ofl_unwindhdr->os_shdr;
3775 
3776                         phdr->p_flags = PF_R;
3777                         phdr->p_vaddr = shdr->sh_addr;
3778                         phdr->p_memsz = shdr->sh_size;
3779                         phdr->p_filesz = shdr->sh_size;
3780                         phdr->p_offset = shdr->sh_offset;
3781                         phdr->p_align = shdr->sh_addralign;
3782                         phdr->p_paddr = 0;
3783                         ofl->ofl_phdr[phdrndx++] = *phdr;
3784                         continue;
3785                 }
3786 
3787                 /*
3788                  * The sunwstack program is used to convey non-default
3789                  * flags for the process stack. Only emit it if it would
3790                  * change the default.
3791                  */
3792                 if (phdr->p_type == PT_SUNWSTACK) {
3793                         if (((flags & FLG_OF_RELOBJ) == 0) &&
3794                             ((sgp->sg_flags & FLG_SG_DISABLED) == 0))
3795                                 ofl->ofl_phdr[phdrndx++] = *phdr;
3796                         continue;
3797                 }
3798 
3799                 /*
3800                  * As the TLS program header occurs after the loadable
3801                  * headers in the segment descriptor table, all the address
3802                  * information for the .tls output section will have been
3803                  * figured out by now.
3804                  */
3805                 if (phdr->p_type == PT_TLS) {
3806                         Os_desc         *tlsosp;
3807                         Shdr            *lastfileshdr = NULL;
3808                         Shdr            *firstshdr = NULL, *lastshdr;
3809                         Aliste          idx;
3810 
3811                         if (ofl->ofl_ostlsseg == NULL)
3812                                 continue;
3813 
3814                         /*
3815                          * Scan the output sections that have contributed TLS.
3816                          * Remember the first and last so as to determine the
3817                          * TLS memory size requirement.  Remember the last
3818                          * progbits section to determine the TLS data
3819                          * contribution, which determines the TLS program
3820                          * header filesz.
3821                          */
3822                         for (APLIST_TRAVERSE(ofl->ofl_ostlsseg, idx, tlsosp)) {
3823                                 Shdr    *tlsshdr = tlsosp->os_shdr;
3824 
3825                                 if (firstshdr == NULL)
3826                                         firstshdr = tlsshdr;
3827                                 if (tlsshdr->sh_type != SHT_NOBITS)
3828                                         lastfileshdr = tlsshdr;
3829                                 lastshdr = tlsshdr;
3830                         }
3831 
3832                         phdr->p_flags = PF_R | PF_W;
3833                         phdr->p_vaddr = firstshdr->sh_addr;
3834                         phdr->p_offset = firstshdr->sh_offset;
3835                         phdr->p_align = firstshdr->sh_addralign;
3836 
3837                         /*
3838                          * Determine the initialized TLS data size.  This
3839                          * address range is from the start of the TLS segment
3840                          * to the end of the last piece of initialized data.
3841                          */
3842                         if (lastfileshdr)
3843                                 phdr->p_filesz = lastfileshdr->sh_offset +
3844                                     lastfileshdr->sh_size - phdr->p_offset;
3845                         else
3846                                 phdr->p_filesz = 0;
3847 
3848                         /*
3849                          * Determine the total TLS memory size.  This includes
3850                          * all TLS data and TLS uninitialized data.  This
3851                          * address range is from the start of the TLS segment
3852                          * to the memory address of the last piece of
3853                          * uninitialized data.
3854                          */
3855                         phdr->p_memsz = lastshdr->sh_addr +
3856                             lastshdr->sh_size - phdr->p_vaddr;
3857 
3858                         DBG_CALL(Dbg_seg_entry(ofl, segndx, sgp));
3859                         ofl->ofl_phdr[phdrndx] = *phdr;
3860                         ofl->ofl_tlsphdr = &ofl->ofl_phdr[phdrndx++];
3861                         continue;
3862                 }
3863 
3864                 /*
3865                  * If this is an empty segment declaration, it will occur after
3866                  * all other loadable segments.  As empty segments can be
3867                  * defined with fixed addresses, make sure that no loadable
3868                  * segments overlap.  This might occur as the object evolves
3869                  * and the loadable segments grow, thus encroaching upon an
3870                  * existing segment reservation.
3871                  *
3872                  * Segments are only created for dynamic objects, thus this
3873                  * checking can be skipped when building a relocatable object.
3874                  */
3875                 if (!(flags & FLG_OF_RELOBJ) &&
3876                     (sgp->sg_flags & FLG_SG_EMPTY)) {
3877                         int     i;
3878                         Addr    v_e;
3879 
3880                         vaddr = phdr->p_vaddr;
3881                         phdr->p_memsz = sgp->sg_length;
3882                         DBG_CALL(Dbg_seg_entry(ofl, segndx, sgp));
3883                         ofl->ofl_phdr[phdrndx++] = *phdr;
3884 
3885                         if (phdr->p_type != PT_LOAD)
3886                                 continue;
3887 
3888                         v_e = vaddr + phdr->p_memsz;
3889 
3890                         /*
3891                          * Check overlaps
3892                          */
3893                         for (i = 0; i < phdrndx - 1; i++) {
3894                                 Addr    p_s = (ofl->ofl_phdr[i]).p_vaddr;
3895                                 Addr    p_e;
3896 
3897                                 if ((ofl->ofl_phdr[i]).p_type != PT_LOAD)
3898                                         continue;
3899 
3900                                 p_e = p_s + (ofl->ofl_phdr[i]).p_memsz;
3901                                 if (((p_s <= vaddr) && (p_e > vaddr)) ||
3902                                     ((vaddr <= p_s) && (v_e > p_s)))
3903                                         ld_eprintf(ofl, ERR_WARNING,
3904                                             MSG_INTL(MSG_UPD_SEGOVERLAP),
3905                                             ofl->ofl_name, EC_ADDR(p_e),
3906                                             sgp->sg_name, EC_ADDR(vaddr));
3907                         }
3908                         continue;
3909                 }
3910 
3911                 /*
3912                  * Having processed any of the special program headers any
3913                  * remaining headers will be built to express individual
3914                  * segments.  Segments are only built if they have output
3915                  * section descriptors associated with them (ie. some form of
3916                  * input section has been matched to this segment).
3917                  */
3918                 if (sgp->sg_osdescs == NULL)
3919                         continue;
3920 
3921                 /*
3922                  * Determine the segments offset and size from the section
3923                  * information provided from elf_update().
3924                  * Allow for multiple NOBITS sections.
3925                  */
3926                 osp = sgp->sg_osdescs->apl_data[0];
3927                 hshdr = osp->os_shdr;
3928 
3929                 phdr->p_filesz = 0;
3930                 phdr->p_memsz = 0;
3931                 phdr->p_offset = offset = hshdr->sh_offset;
3932 
3933                 nobits = ((hshdr->sh_type == SHT_NOBITS) &&
3934                     ((sgp->sg_flags & FLG_SG_PHREQ) == 0));
3935 
3936                 for (APLIST_TRAVERSE(sgp->sg_osdescs, idx2, osp)) {
3937                         Shdr    *shdr = osp->os_shdr;
3938 
3939                         p_align = 0;
3940                         if (shdr->sh_addralign > p_align)
3941                                 p_align = shdr->sh_addralign;
3942 
3943                         offset = (Off)S_ROUND(offset, shdr->sh_addralign);
3944                         offset += shdr->sh_size;
3945 
3946                         if (shdr->sh_type != SHT_NOBITS) {
3947                                 if (nobits) {
3948                                         ld_eprintf(ofl, ERR_FATAL,
3949                                             MSG_INTL(MSG_UPD_NOBITS));
3950                                         return (S_ERROR);
3951                                 }
3952                                 phdr->p_filesz = offset - phdr->p_offset;
3953                         } else if ((sgp->sg_flags & FLG_SG_PHREQ) == 0)
3954                                 nobits = TRUE;
3955                 }
3956                 phdr->p_memsz = offset - hshdr->sh_offset;
3957 
3958                 /*
3959                  * If this is the first loadable segment of a dynamic object,
3960                  * or an interpreter has been specified (a static object built
3961                  * with an interpreter will still be given a PT_HDR entry), then
3962                  * compensate for the elf header and program header array.  Both
3963                  * of these are actually part of the loadable segment as they
3964                  * may be inspected by the interpreter.  Adjust the segments
3965                  * size and offset accordingly.
3966                  */
3967                 if ((_phdr == NULL) && (phdr->p_type == PT_LOAD) &&
3968                     ((ofl->ofl_osinterp) || (flags & FLG_OF_DYNAMIC)) &&
3969                     (!(ofl->ofl_dtflags_1 & DF_1_NOHDR))) {
3970                         size = (Addr)S_ROUND((phdrsz + ehdrsz),
3971                             hshdr->sh_addralign);
3972                         phdr->p_offset -= size;
3973                         phdr->p_filesz += size;
3974                         phdr->p_memsz += size;
3975                 }
3976 
3977                 /*
3978                  * If segment size symbols are required (specified via a
3979                  * mapfile) update their value.
3980                  */
3981                 for (APLIST_TRAVERSE(sgp->sg_sizesym, idx2, sdp))
3982                         sdp->sd_sym->st_value = phdr->p_memsz;
3983 
3984                 /*
3985                  * If no file content has been assigned to this segment (it
3986                  * only contains no-bits sections), then reset the offset for
3987                  * consistency.
3988                  */
3989                 if (phdr->p_filesz == 0)
3990                         phdr->p_offset = 0;
3991 
3992                 /*
3993                  * If a virtual address has been specified for this segment
3994                  * from a mapfile use it and make sure the previous segment
3995                  * does not run into this segment.
3996                  */
3997                 if (phdr->p_type == PT_LOAD) {
3998                         if ((sgp->sg_flags & FLG_SG_P_VADDR)) {
3999                                 if (_phdr && (vaddr > phdr->p_vaddr) &&
4000                                     (phdr->p_type == PT_LOAD))
4001                                         ld_eprintf(ofl, ERR_WARNING,
4002                                             MSG_INTL(MSG_UPD_SEGOVERLAP),
4003                                             ofl->ofl_name, EC_ADDR(vaddr),
4004                                             sgp->sg_name,
4005                                             EC_ADDR(phdr->p_vaddr));
4006                                 vaddr = phdr->p_vaddr;
4007                                 phdr->p_align = 0;
4008                         } else {
4009                                 vaddr = phdr->p_vaddr =
4010                                     (Addr)S_ROUND(vaddr, phdr->p_align);
4011                         }
4012                 }
4013 
4014                 /*
4015                  * Adjust the address offset and p_align if needed.
4016                  */
4017                 if (((sgp->sg_flags & FLG_SG_P_VADDR) == 0) &&
4018                     ((ofl->ofl_dtflags_1 & DF_1_NOHDR) == 0)) {
4019                         if (phdr->p_align != 0)
4020                                 vaddr += phdr->p_offset % phdr->p_align;
4021                         else
4022                                 vaddr += phdr->p_offset;
4023                         phdr->p_vaddr = vaddr;
4024                 }
4025 
4026                 /*
4027                  * If an interpreter is required set the virtual address of the
4028                  * PT_PHDR program header now that we know the virtual address
4029                  * of the loadable segment that contains it.  Update the
4030                  * PT_SUNWCAP header similarly.
4031                  */
4032                 if ((_phdr == NULL) && (phdr->p_type == PT_LOAD)) {
4033                         _phdr = phdr;
4034 
4035                         if ((ofl->ofl_dtflags_1 & DF_1_NOHDR) == 0) {
4036                                 if (ofl->ofl_osinterp)
4037                                         ofl->ofl_phdr[0].p_vaddr =
4038                                             vaddr + ehdrsz;
4039 
4040                                 /*
4041                                  * Finally, if we're creating a dynamic object
4042                                  * (or a static object in which an interpreter
4043                                  * is specified) update the vaddr to reflect
4044                                  * the address of the first section within this
4045                                  * segment.
4046                                  */
4047                                 if ((ofl->ofl_osinterp) ||
4048                                     (flags & FLG_OF_DYNAMIC))
4049                                         vaddr += size;
4050                         } else {
4051                                 /*
4052                                  * If the DF_1_NOHDR flag was set, and an
4053                                  * interpreter is being generated, the PT_PHDR
4054                                  * will not be part of any loadable segment.
4055                                  */
4056                                 if (ofl->ofl_osinterp) {
4057                                         ofl->ofl_phdr[0].p_vaddr = 0;
4058                                         ofl->ofl_phdr[0].p_memsz = 0;
4059                                         ofl->ofl_phdr[0].p_flags = 0;
4060                                 }
4061                         }
4062                 }
4063 
4064                 /*
4065                  * Ensure the ELF entry point defaults to zero.  Typically, this
4066                  * value is overridden in update_oehdr() to one of the standard
4067                  * entry points.  Historically, this default was set to the
4068                  * address of first executable section, but this has since been
4069                  * found to be more confusing than it is helpful.
4070                  */
4071                 ehdr->e_entry = 0;
4072 
4073                 DBG_CALL(Dbg_seg_entry(ofl, segndx, sgp));
4074 
4075                 /*
4076                  * Traverse the output section descriptors for this segment so
4077                  * that we can update the section headers addresses.  We've
4078                  * calculated the virtual address of the initial section within
4079                  * this segment, so each successive section can be calculated
4080                  * based on their offsets from each other.
4081                  */
4082                 secndx = 0;
4083                 hshdr = 0;
4084                 for (APLIST_TRAVERSE(sgp->sg_osdescs, idx2, osp)) {
4085                         Shdr    *shdr = osp->os_shdr;
4086 
4087                         if (shdr->sh_link)
4088                                 shdr->sh_link = translate_link(ofl, osp,
4089                                     shdr->sh_link, MSG_INTL(MSG_FIL_INVSHLINK));
4090 
4091                         if (shdr->sh_info && (shdr->sh_flags & SHF_INFO_LINK))
4092                                 shdr->sh_info = translate_link(ofl, osp,
4093                                     shdr->sh_info, MSG_INTL(MSG_FIL_INVSHINFO));
4094 
4095                         if (!(flags & FLG_OF_RELOBJ) &&
4096                             (phdr->p_type == PT_LOAD)) {
4097                                 if (hshdr)
4098                                         vaddr += (shdr->sh_offset -
4099                                             hshdr->sh_offset);
4100 
4101                                 shdr->sh_addr = vaddr;
4102                                 hshdr = shdr;
4103                         }
4104 
4105                         DBG_CALL(Dbg_seg_os(ofl, osp, secndx));
4106                         secndx++;
4107                 }
4108 
4109                 /*
4110                  * Establish the virtual address of the end of the last section
4111                  * in this segment so that the next segments offset can be
4112                  * calculated from this.
4113                  */
4114                 if (hshdr)
4115                         vaddr += hshdr->sh_size;
4116 
4117                 /*
4118                  * Output sections for this segment complete.  Adjust the
4119                  * virtual offset for the last sections size, and make sure we
4120                  * haven't exceeded any maximum segment length specification.
4121                  */
4122                 if ((sgp->sg_length != 0) && (sgp->sg_length < phdr->p_memsz)) {
4123                         ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_UPD_LARGSIZE),
4124                             ofl->ofl_name, sgp->sg_name,
4125                             EC_XWORD(phdr->p_memsz), EC_XWORD(sgp->sg_length));
4126                         return (S_ERROR);
4127                 }
4128 
4129                 if (phdr->p_type == PT_NOTE) {
4130                         phdr->p_vaddr = 0;
4131                         phdr->p_paddr = 0;
4132                         phdr->p_align = 0;
4133                         phdr->p_memsz = 0;
4134                 }
4135 
4136                 if ((phdr->p_type != PT_NULL) && !(flags & FLG_OF_RELOBJ))
4137                         ofl->ofl_phdr[phdrndx++] = *phdr;
4138         }
4139 
4140         /*
4141          * Update any new output sections.  When building the initial output
4142          * image, a number of sections were created but left uninitialized (eg.
4143          * .dynsym, .dynstr, .symtab, .symtab, etc.).  Here we update these
4144          * sections with the appropriate data.  Other sections may still be
4145          * modified via reloc_process().
4146          *
4147          * Copy the interpreter name into the .interp section.
4148          */
4149         if (ofl->ofl_interp)
4150                 (void) strcpy((char *)ofl->ofl_osinterp->os_outdata->d_buf,
4151                     ofl->ofl_interp);
4152 
4153         /*
4154          * Update the .shstrtab, .strtab and .dynstr sections.
4155          */
4156         update_ostrtab(ofl->ofl_osshstrtab, ofl->ofl_shdrsttab, 0);
4157         update_ostrtab(ofl->ofl_osstrtab, ofl->ofl_strtab, 0);
4158         update_ostrtab(ofl->ofl_osdynstr, ofl->ofl_dynstrtab, DYNSTR_EXTRA_PAD);
4159 
4160         /*
4161          * Build any output symbol tables, the symbols information is copied
4162          * and updated into the new output image.
4163          */
4164         if ((etext = update_osym(ofl)) == (Addr)S_ERROR)
4165                 return (S_ERROR);
4166 
4167         /*
4168          * If we have an PT_INTERP phdr, update it now from the associated
4169          * section information.
4170          */
4171         if (intpsgp) {
4172                 Phdr    *phdr = &(intpsgp->sg_phdr);
4173                 Shdr    *shdr = ofl->ofl_osinterp->os_shdr;
4174 
4175                 phdr->p_vaddr = shdr->sh_addr;
4176                 phdr->p_offset = shdr->sh_offset;
4177                 phdr->p_memsz = phdr->p_filesz = shdr->sh_size;
4178                 phdr->p_flags = PF_R;
4179 
4180                 DBG_CALL(Dbg_seg_entry(ofl, intpsndx, intpsgp));
4181                 ofl->ofl_phdr[intppndx] = *phdr;
4182         }
4183 
4184         /*
4185          * If we have a PT_SUNWDTRACE phdr, update it now with the address of
4186          * the symbol.  It's only now been updated via update_sym().
4187          */
4188         if (dtracesgp) {
4189                 Phdr            *aphdr, *phdr = &(dtracesgp->sg_phdr);
4190                 Sym_desc        *sdp = ofl->ofl_dtracesym;
4191 
4192                 phdr->p_vaddr = sdp->sd_sym->st_value;
4193                 phdr->p_memsz = sdp->sd_sym->st_size;
4194 
4195                 /*
4196                  * Take permissions from the segment that the symbol is
4197                  * associated with.
4198                  */
4199                 aphdr = &sdp->sd_isc->is_osdesc->os_sgdesc->sg_phdr;
4200                 assert(aphdr);
4201                 phdr->p_flags = aphdr->p_flags;
4202 
4203                 DBG_CALL(Dbg_seg_entry(ofl, dtracesndx, dtracesgp));
4204                 ofl->ofl_phdr[dtracepndx] = *phdr;
4205         }
4206 
4207         /*
4208          * If we have a PT_SUNWCAP phdr, update it now from the associated
4209          * section information.
4210          */
4211         if (capsgp) {
4212                 Phdr    *phdr = &(capsgp->sg_phdr);
4213                 Shdr    *shdr = ofl->ofl_oscap->os_shdr;
4214 
4215                 phdr->p_vaddr = shdr->sh_addr;
4216                 phdr->p_offset = shdr->sh_offset;
4217                 phdr->p_memsz = phdr->p_filesz = shdr->sh_size;
4218                 phdr->p_flags = PF_R;
4219 
4220                 DBG_CALL(Dbg_seg_entry(ofl, capsndx, capsgp));
4221                 ofl->ofl_phdr[cappndx] = *phdr;
4222         }
4223 
4224         /*
4225          * Update the GROUP sections.
4226          */
4227         if (update_ogroup(ofl) == S_ERROR)
4228                 return (S_ERROR);
4229 
4230         /*
4231          * Update Move Table.
4232          */
4233         if (ofl->ofl_osmove || ofl->ofl_isparexpn)
4234                 update_move(ofl);
4235 
4236         /*
4237          * Build any output headers, version information, dynamic structure and
4238          * syminfo structure.
4239          */
4240         if (update_oehdr(ofl) == S_ERROR)
4241                 return (S_ERROR);
4242         if (!(flags & FLG_OF_NOVERSEC)) {
4243                 if ((flags & FLG_OF_VERDEF) &&
4244                     (update_overdef(ofl) == S_ERROR))
4245                         return (S_ERROR);
4246                 if ((flags & FLG_OF_VERNEED) &&
4247                     (update_overneed(ofl) == S_ERROR))
4248                         return (S_ERROR);
4249                 if (flags & (FLG_OF_VERNEED | FLG_OF_VERDEF))
4250                         update_oversym(ofl);
4251         }
4252         if (flags & FLG_OF_DYNAMIC) {
4253                 if (update_odynamic(ofl) == S_ERROR)
4254                         return (S_ERROR);
4255         }
4256         if (ofl->ofl_ossyminfo) {
4257                 if (update_osyminfo(ofl) == S_ERROR)
4258                         return (S_ERROR);
4259         }
4260 
4261         /*
4262          * Update capabilities information if required.
4263          */
4264         if (ofl->ofl_oscap)
4265                 update_oscap(ofl);
4266         if (ofl->ofl_oscapinfo)
4267                 update_oscapinfo(ofl);
4268 
4269         /*
4270          * Sanity test: the first and last data byte of a string table
4271          * must be NULL.
4272          */
4273         assert((ofl->ofl_osshstrtab == NULL) ||
4274             (*((char *)ofl->ofl_osshstrtab->os_outdata->d_buf) == '\0'));
4275         assert((ofl->ofl_osshstrtab == NULL) ||
4276             (*(((char *)ofl->ofl_osshstrtab->os_outdata->d_buf) +
4277             ofl->ofl_osshstrtab->os_outdata->d_size - 1) == '\0'));
4278 
4279         assert((ofl->ofl_osstrtab == NULL) ||
4280             (*((char *)ofl->ofl_osstrtab->os_outdata->d_buf) == '\0'));
4281         assert((ofl->ofl_osstrtab == NULL) ||
4282             (*(((char *)ofl->ofl_osstrtab->os_outdata->d_buf) +
4283             ofl->ofl_osstrtab->os_outdata->d_size - 1) == '\0'));
4284 
4285         assert((ofl->ofl_osdynstr == NULL) ||
4286             (*((char *)ofl->ofl_osdynstr->os_outdata->d_buf) == '\0'));
4287         assert((ofl->ofl_osdynstr == NULL) ||
4288             (*(((char *)ofl->ofl_osdynstr->os_outdata->d_buf) +
4289             ofl->ofl_osdynstr->os_outdata->d_size - DYNSTR_EXTRA_PAD - 1) ==
4290             '\0'));
4291 
4292         /*
4293          * Emit Strtab diagnostics.
4294          */
4295         DBG_CALL(Dbg_sec_strtab(ofl->ofl_lml, ofl->ofl_osshstrtab,
4296             ofl->ofl_shdrsttab));
4297         DBG_CALL(Dbg_sec_strtab(ofl->ofl_lml, ofl->ofl_osstrtab,
4298             ofl->ofl_strtab));
4299         DBG_CALL(Dbg_sec_strtab(ofl->ofl_lml, ofl->ofl_osdynstr,
4300             ofl->ofl_dynstrtab));
4301 
4302         /*
4303          * Initialize the section headers string table index within the elf
4304          * header.
4305          */
4306         /* LINTED */
4307         if ((shscnndx = elf_ndxscn(ofl->ofl_osshstrtab->os_scn)) <
4308             SHN_LORESERVE) {
4309                 ofl->ofl_nehdr->e_shstrndx =
4310                     /* LINTED */
4311                     (Half)shscnndx;
4312         } else {
4313                 /*
4314                  * If the STRTAB section index doesn't fit into
4315                  * e_shstrndx, then we store it in 'shdr[0].st_link'.
4316                  */
4317                 Elf_Scn *scn;
4318                 Shdr    *shdr0;
4319 
4320                 if ((scn = elf_getscn(ofl->ofl_elf, 0)) == NULL) {
4321                         ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETSCN),
4322                             ofl->ofl_name);
4323                         return (S_ERROR);
4324                 }
4325                 if ((shdr0 = elf_getshdr(scn)) == NULL) {
4326                         ld_eprintf(ofl, ERR_ELF, MSG_INTL(MSG_ELF_GETSHDR),
4327                             ofl->ofl_name);
4328                         return (S_ERROR);
4329                 }
4330                 ofl->ofl_nehdr->e_shstrndx = SHN_XINDEX;
4331                 shdr0->sh_link = shscnndx;
4332         }
4333 
4334         return ((uintptr_t)etext);
4335 }