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  * Copyright 2017 RackTop Systems.
  28  */
  29 
  30 /*
  31  * set-up for relocations
  32  */
  33 
  34 #define ELF_TARGET_AMD64
  35 #define ELF_TARGET_SPARC
  36 
  37 #include        <string.h>
  38 #include        <stdio.h>
  39 #include        <alloca.h>
  40 #include        <debug.h>
  41 #include        "msg.h"
  42 #include        "_libld.h"
  43 
  44 /*
  45  * Set up the relocation table flag test macros so that they use the
  46  * relocation table for the current target machine.
  47  */
  48 #define IS_PLT(X)       RELTAB_IS_PLT(X, ld_targ.t_mr.mr_reloc_table)
  49 #define IS_GOT_RELATIVE(X) \
  50         RELTAB_IS_GOT_RELATIVE(X, ld_targ.t_mr.mr_reloc_table)
  51 #define IS_GOT_PC(X)    RELTAB_IS_GOT_PC(X, ld_targ.t_mr.mr_reloc_table)
  52 #define IS_GOTPCREL(X)  RELTAB_IS_GOTPCREL(X, ld_targ.t_mr.mr_reloc_table)
  53 #define IS_GOT_BASED(X) RELTAB_IS_GOT_BASED(X, ld_targ.t_mr.mr_reloc_table)
  54 #define IS_GOT_OPINS(X) RELTAB_IS_GOT_OPINS(X, ld_targ.t_mr.mr_reloc_table)
  55 #define IS_GOT_REQUIRED(X) \
  56         RELTAB_IS_GOT_REQUIRED(X, ld_targ.t_mr.mr_reloc_table)
  57 #define IS_PC_RELATIVE(X) RELTAB_IS_PC_RELATIVE(X, ld_targ.t_mr.mr_reloc_table)
  58 #define IS_ADD_RELATIVE(X) \
  59         RELTAB_IS_ADD_RELATIVE(X, ld_targ.t_mr.mr_reloc_table)
  60 #define IS_REGISTER(X)  RELTAB_IS_REGISTER(X, ld_targ.t_mr.mr_reloc_table)
  61 #define IS_NOTSUP(X)    RELTAB_IS_NOTSUP(X, ld_targ.t_mr.mr_reloc_table)
  62 #define IS_SEG_RELATIVE(X) \
  63         RELTAB_IS_SEG_RELATIVE(X, ld_targ.t_mr.mr_reloc_table)
  64 #define IS_EXTOFFSET(X) RELTAB_IS_EXTOFFSET(X, ld_targ.t_mr.mr_reloc_table)
  65 #define IS_SEC_RELATIVE(X) \
  66         RELTAB_IS_SEC_RELATIVE(X, ld_targ.t_mr.mr_reloc_table)
  67 #define IS_TLS_INS(X)   RELTAB_IS_TLS_INS(X, ld_targ.t_mr.mr_reloc_table)
  68 #define IS_TLS_GD(X)    RELTAB_IS_TLS_GD(X, ld_targ.t_mr.mr_reloc_table)
  69 #define IS_TLS_LD(X)    RELTAB_IS_TLS_LD(X, ld_targ.t_mr.mr_reloc_table)
  70 #define IS_TLS_IE(X)    RELTAB_IS_TLS_IE(X, ld_targ.t_mr.mr_reloc_table)
  71 #define IS_TLS_LE(X)    RELTAB_IS_TLS_LE(X, ld_targ.t_mr.mr_reloc_table)
  72 #define IS_LOCALBND(X)  RELTAB_IS_LOCALBND(X, ld_targ.t_mr.mr_reloc_table)
  73 #define IS_SIZE(X)      RELTAB_IS_SIZE(X, ld_targ.t_mr.mr_reloc_table)
  74 
  75 /*
  76  * Structure to hold copy relocation items.
  77  */
  78 typedef struct copy_rel {
  79         Sym_desc        *c_sdp;         /* symbol descriptor to be copied */
  80         Addr            c_val;          /* original symbol value */
  81 } Copy_rel;
  82 
  83 /*
  84  * For each copy relocation symbol, determine if the symbol is:
  85  *      1) to be *disp* relocated at runtime
  86  *      2) a reference symbol for *disp* relocation
  87  *      3) possibly *disp* relocated at ld time.
  88  *
  89  * The first and the second are serious errors.
  90  */
  91 static void
  92 is_disp_copied(Ofl_desc *ofl, Copy_rel *crp)
  93 {
  94         Ifl_desc        *ifl = crp->c_sdp->sd_file;
  95         Sym_desc        *sdp = crp->c_sdp;
  96         Addr            symaddr = crp->c_val;
  97         Is_desc         *irel;
  98         Aliste          idx;
  99         Conv_inv_buf_t  inv_buf;
 100 
 101         /*
 102          * This symbol may not be *disp* relocated at run time, but could
 103          * already have been *disp* relocated when the shared object was
 104          * created.  Warn the user.
 105          */
 106         if ((ifl->ifl_flags & FLG_IF_DISPDONE) &&
 107             (ofl->ofl_flags & FLG_OF_VERBOSE))
 108                 ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_REL_DISPREL2),
 109                     conv_reloc_type(ifl->ifl_ehdr->e_machine,
 110                     ld_targ.t_m.m_r_copy, 0, &inv_buf),
 111                     ifl->ifl_name, demangle(sdp->sd_name));
 112 
 113         if ((ifl->ifl_flags & FLG_IF_DISPPEND) == 0)
 114                 return;
 115 
 116         /*
 117          * Traverse the input relocation sections.
 118          */
 119         for (APLIST_TRAVERSE(ifl->ifl_relsect, idx, irel)) {
 120                 Sym_desc        *rsdp;
 121                 Is_desc         *trel;
 122                 Rel             *rend, *reloc;
 123                 Xword           rsize, entsize;
 124 
 125                 trel = ifl->ifl_isdesc[irel->is_shdr->sh_info];
 126                 rsize = irel->is_shdr->sh_size;
 127                 entsize = irel->is_shdr->sh_entsize;
 128                 reloc = (Rel *)irel->is_indata->d_buf;
 129 
 130                 /*
 131                  * Decide entry size
 132                  */
 133                 if ((entsize == 0) || (entsize > rsize)) {
 134                         if (irel->is_shdr->sh_type == SHT_RELA)
 135                                 entsize = sizeof (Rela);
 136                         else
 137                                 entsize = sizeof (Rel);
 138                 }
 139 
 140                 /*
 141                  * Traverse the relocation entries.
 142                  */
 143                 for (rend = (Rel *)((uintptr_t)reloc + (uintptr_t)rsize);
 144                     reloc < rend;
 145                     reloc = (Rel *)((uintptr_t)reloc + (uintptr_t)entsize)) {
 146                         const char      *str;
 147                         Word            rstndx;
 148 
 149                         if (IS_PC_RELATIVE(ELF_R_TYPE(reloc->r_info,
 150                             ld_targ.t_m.m_mach)) == 0)
 151                                 continue;
 152 
 153                         /*
 154                          * Determine if symbol is referenced from a relocation.
 155                          */
 156                         rstndx = (Word) ELF_R_SYM(reloc->r_info);
 157                         rsdp = ifl->ifl_oldndx[rstndx];
 158                         if (rsdp == sdp) {
 159                                 if ((str = demangle(rsdp->sd_name)) !=
 160                                     rsdp->sd_name) {
 161                                         char    *_str = alloca(strlen(str) + 1);
 162                                         (void) strcpy(_str, str);
 163                                         str = (const char *)_str;
 164                                 }
 165                                 ld_eprintf(ofl, ERR_WARNING,
 166                                     MSG_INTL(MSG_REL_DISPREL1),
 167                                     conv_reloc_type(ifl->ifl_ehdr->e_machine,
 168                                     (uint_t)ELF_R_TYPE(reloc->r_info,
 169                                     ld_targ.t_m.m_mach),
 170                                     0, &inv_buf), ifl->ifl_name, str,
 171                                     MSG_INTL(MSG_STR_UNKNOWN),
 172                                     EC_XWORD(reloc->r_offset),
 173                                     demangle(sdp->sd_name));
 174                         }
 175 
 176                         /*
 177                          * Determine whether the relocation entry is relocating
 178                          * this symbol.
 179                          */
 180                         if ((sdp->sd_isc != trel) ||
 181                             (reloc->r_offset < symaddr) ||
 182                             (reloc->r_offset >=
 183                             (symaddr + sdp->sd_sym->st_size)))
 184                                 continue;
 185 
 186                         /*
 187                          * This symbol is truely *disp* relocated, so should
 188                          * really be fixed by user.
 189                          */
 190                         if ((str = demangle(sdp->sd_name)) != sdp->sd_name) {
 191                                 char    *_str = alloca(strlen(str) + 1);
 192                                 (void) strcpy(_str, str);
 193                                 str = (const char *)_str;
 194                         }
 195                         ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_REL_DISPREL1),
 196                             conv_reloc_type(ifl->ifl_ehdr->e_machine,
 197                             (uint_t)ELF_R_TYPE(reloc->r_info,
 198                             ld_targ.t_m.m_mach), 0, &inv_buf),
 199                             ifl->ifl_name, demangle(rsdp->sd_name), str,
 200                             EC_XWORD(reloc->r_offset), str);
 201                 }
 202         }
 203 }
 204 
 205 /*
 206  * The number of symbols provided by some objects can be very large.  Use a
 207  * binary search to match the associated value to a symbol table entry.
 208  */
 209 static int
 210 disp_bsearch(const void *key, const void *array)
 211 {
 212         Addr            kvalue, avalue;
 213         Ssv_desc        *ssvp = (Ssv_desc *)array;
 214 
 215         kvalue = *((Addr *)key);
 216         avalue = ssvp->ssv_value;
 217 
 218         if (avalue > kvalue)
 219                 return (-1);
 220         if ((avalue < kvalue) &&
 221             ((avalue + ssvp->ssv_sdp->sd_sym->st_size) <= kvalue))
 222                 return (1);
 223         return (0);
 224 }
 225 
 226 /*
 227  * Given a sorted list of symbols, look for a symbol in which the relocation
 228  * offset falls between the [sym.st_value - sym.st_value + sym.st_size].  Since
 229  * the symbol list is maintained in sorted order,  we can bail once the
 230  * relocation offset becomes less than the symbol values.  The symbol is
 231  * returned for use in error diagnostics.
 232  */
 233 static Sym_desc *
 234 disp_scansyms(Ifl_desc * ifl, Rel_desc *rld, Boolean rlocal, int inspect,
 235     Ofl_desc *ofl)
 236 {
 237         Sym_desc        *tsdp, *rsdp;
 238         Sym             *rsym, *tsym;
 239         Ssv_desc        *ssvp;
 240         uchar_t         rtype, ttype;
 241         Addr            value;
 242 
 243         /*
 244          * Sorted symbol values have been uniquified by adding their associated
 245          * section offset.  Uniquify the relocation offset by adding its
 246          * associated section offset, and search for the symbol.
 247          */
 248         value = rld->rel_roffset;
 249         if (rld->rel_isdesc->is_shdr)
 250                 value += rld->rel_isdesc->is_shdr->sh_offset;
 251 
 252         if ((ssvp = bsearch((void *)&value, (void *)ifl->ifl_sortsyms,
 253             ifl->ifl_sortcnt, sizeof (Ssv_desc), &disp_bsearch)) != 0)
 254                 tsdp = ssvp->ssv_sdp;
 255         else
 256                 tsdp = 0;
 257 
 258         if (inspect)
 259                 return (tsdp);
 260 
 261         /*
 262          * Determine the relocation reference symbol and its type.
 263          */
 264         rsdp = rld->rel_sym;
 265         rsym = rsdp->sd_sym;
 266         rtype = ELF_ST_TYPE(rsym->st_info);
 267 
 268         /*
 269          * If there is no target symbol to match the relocation offset, then the
 270          * offset is effectively local data.  If the relocation symbol is global
 271          * data we have a potential for this displacement relocation to be
 272          * invalidated should the global symbol be copied.
 273          */
 274         if (tsdp == 0) {
 275                 if ((rlocal == TRUE) ||
 276                     ((rtype != STT_OBJECT) && (rtype != STT_SECTION)))
 277                 return (tsdp);
 278         } else {
 279                 /*
 280                  * If both symbols are local, no copy relocations can occur to
 281                  * either symbol.  Note, this test is very similar to the test
 282                  * used in ld_sym_adjust_vis().
 283                  */
 284                 if ((rlocal == TRUE) && (SYM_IS_HIDDEN(tsdp) ||
 285                     (ELF_ST_BIND(tsdp->sd_sym->st_info) != STB_GLOBAL) ||
 286                     ((ofl->ofl_flags & (FLG_OF_AUTOLCL | FLG_OF_AUTOELM)) &&
 287                     ((tsdp->sd_flags & MSK_SY_NOAUTO) == 0))))
 288                         return (tsdp);
 289 
 290                 /*
 291                  * Determine the relocation target symbols type.
 292                  */
 293                 tsym = tsdp->sd_sym;
 294                 ttype = ELF_ST_TYPE(tsym->st_info);
 295 
 296                 /*
 297                  * If the reference symbol is local, and the target isn't a
 298                  * data element, then no copy relocations can occur to either
 299                  * symbol.  Note, this catches pc-relative relocations against
 300                  * the _GLOBAL_OFFSET_TABLE_, which is effectively treated as
 301                  * a local symbol.
 302                  */
 303                 if ((rlocal == TRUE) && (ttype != STT_OBJECT) &&
 304                     (ttype != STT_SECTION))
 305                         return (tsdp);
 306 
 307                 /*
 308                  * Finally, one of the symbols must reference a data element.
 309                  */
 310                 if ((rtype != STT_OBJECT) && (rtype != STT_SECTION) &&
 311                     (ttype != STT_OBJECT) && (ttype != STT_SECTION))
 312                         return (tsdp);
 313         }
 314 
 315         /*
 316          * We have two global symbols, at least one of which is a data item.
 317          * The last case where a displacement relocation can be ignored, is
 318          * if the reference symbol is included in the target symbol.
 319          */
 320         value = rsym->st_value;
 321         if ((rld->rel_flags & FLG_REL_RELA) == FLG_REL_RELA)
 322                 value += rld->rel_raddend;
 323 
 324         if ((rld->rel_roffset >= value) &&
 325             (rld->rel_roffset < (value + rsym->st_size)))
 326                 return (tsdp);
 327 
 328         /*
 329          * We have a displacement relocation that could be compromised by a
 330          * copy relocation of one of the associated data items.
 331          */
 332         rld->rel_flags |= FLG_REL_DISP;
 333         return (tsdp);
 334 }
 335 
 336 void
 337 ld_disp_errmsg(const char *msg, Rel_desc *rsp, Ofl_desc *ofl)
 338 {
 339         Sym_desc        *sdp;
 340         const char      *str;
 341         Ifl_desc        *ifl = rsp->rel_isdesc->is_file;
 342         Conv_inv_buf_t  inv_buf;
 343 
 344         if ((sdp = disp_scansyms(ifl, rsp, 0, 1, ofl)) != 0)
 345                 str = demangle(sdp->sd_name);
 346         else
 347                 str = MSG_INTL(MSG_STR_UNKNOWN);
 348 
 349         ld_eprintf(ofl, ERR_WARNING, msg,
 350             conv_reloc_type(ifl->ifl_ehdr->e_machine, rsp->rel_rtype,
 351             0, &inv_buf), ifl->ifl_name, ld_reloc_sym_name(rsp), str,
 352             EC_OFF(rsp->rel_roffset));
 353 }
 354 
 355 /*
 356  * qsort(3C) comparison routine used for the disp_sortsyms().
 357  */
 358 static int
 359 disp_qsort(const void * s1, const void * s2)
 360 {
 361         Ssv_desc        *ssvp1 = ((Ssv_desc *)s1);
 362         Ssv_desc        *ssvp2 = ((Ssv_desc *)s2);
 363         Addr            val1 = ssvp1->ssv_value;
 364         Addr            val2 = ssvp2->ssv_value;
 365 
 366         if (val1 > val2)
 367                 return (1);
 368         if (val1 < val2)
 369                 return (-1);
 370         return (0);
 371 }
 372 
 373 /*
 374  * Determine whether a displacement relocation is between a local and global
 375  * symbol pair.  One symbol is used to perform the relocation, and the other
 376  * is the destination offset of the relocation.
 377  */
 378 static uintptr_t
 379 disp_inspect(Ofl_desc *ofl, Rel_desc *rld, Boolean rlocal)
 380 {
 381         Is_desc         *isp = rld->rel_isdesc;
 382         Ifl_desc        *ifl = rld->rel_isdesc->is_file;
 383 
 384         /*
 385          * If the input files symbols haven't been sorted yet, do so.
 386          */
 387         if (ifl->ifl_sortsyms == 0) {
 388                 Word    ondx, nndx;
 389 
 390                 if ((ifl->ifl_sortsyms = libld_malloc((ifl->ifl_symscnt + 1) *
 391                     sizeof (Ssv_desc))) == 0)
 392                         return (S_ERROR);
 393 
 394                 for (ondx = 0, nndx = 0; ondx < ifl->ifl_symscnt; ondx++) {
 395                         Sym_desc        *sdp;
 396                         Addr            value;
 397 
 398                         /*
 399                          * As symbol resolution has already occurred, various
 400                          * symbols from this object may have been satisfied
 401                          * from other objects.  Only select symbols from this
 402                          * object.  For the displacement test, we only really
 403                          * need to observe data definitions, however, later as
 404                          * part of providing warning disgnostics, relating the
 405                          * relocation offset to a symbol is desirable.  Thus,
 406                          * collect all symbols that define a memory area.
 407                          */
 408                         if (((sdp = ifl->ifl_oldndx[ondx]) == 0) ||
 409                             (sdp->sd_sym->st_shndx == SHN_UNDEF) ||
 410                             (sdp->sd_sym->st_shndx >= SHN_LORESERVE) ||
 411                             (sdp->sd_ref != REF_REL_NEED) ||
 412                             (sdp->sd_file != ifl) ||
 413                             (sdp->sd_sym->st_size == 0))
 414                                 continue;
 415 
 416                         /*
 417                          * As a further optimization for later checking, mark
 418                          * this section if this a global data definition.
 419                          */
 420                         if (sdp->sd_isc && (ondx >= ifl->ifl_locscnt))
 421                                 sdp->sd_isc->is_flags |= FLG_IS_GDATADEF;
 422 
 423                         /*
 424                          * Capture the symbol.  Within relocatable objects, a
 425                          * symbols value is its offset within its associated
 426                          * section.  Add the section offset to this value to
 427                          * uniquify the symbol.
 428                          */
 429                         value = sdp->sd_sym->st_value;
 430                         if (sdp->sd_isc && sdp->sd_isc->is_shdr)
 431                                 value += sdp->sd_isc->is_shdr->sh_offset;
 432 
 433                         ifl->ifl_sortsyms[nndx].ssv_value = value;
 434                         ifl->ifl_sortsyms[nndx].ssv_sdp = sdp;
 435                         nndx++;
 436                 }
 437 
 438                 /*
 439                  * Sort the list based on the symbols value (address).
 440                  */
 441                 if ((ifl->ifl_sortcnt = nndx) != 0)
 442                         qsort(ifl->ifl_sortsyms, nndx, sizeof (Ssv_desc),
 443                             &disp_qsort);
 444         }
 445 
 446         /*
 447          * If the reference symbol is local, and the section being relocated
 448          * contains no global definitions, neither can be the target of a copy
 449          * relocation.
 450          */
 451         if ((rlocal == FALSE) && ((isp->is_flags & FLG_IS_GDATADEF) == 0))
 452                 return (1);
 453 
 454         /*
 455          * Otherwise determine whether this relocation symbol and its offset
 456          * could be candidates for a copy relocation.
 457          */
 458         if (ifl->ifl_sortcnt)
 459                 (void) disp_scansyms(ifl, rld, rlocal, 0, ofl);
 460         return (1);
 461 }
 462 
 463 /*
 464  * Return a Rel_cachebuf with an available Rel_desc entry from the
 465  * specified cache, allocating a cache buffer if necessary.
 466  *
 467  * entry:
 468  *      ofl - Output file descriptor
 469  *      rcp - Relocation cache to allocate the descriptor from.
 470  *              One of &ofl->ofl_actrels or &ofl->ofl_outrels.
 471  *
 472  * exit:
 473  *      Returns the allocated descriptor, or NULL if the allocation fails.
 474  */
 475 static Rel_cachebuf *
 476 ld_add_rel_cache(Ofl_desc *ofl, Rel_cache *rcp)
 477 {
 478         Rel_cachebuf    *rcbp;
 479         size_t          nelts, size, alloc_cnt;
 480 
 481         /*
 482          * If there is space available in the present cache bucket, return the
 483          * next free entry.
 484          */
 485         alloc_cnt = aplist_nitems(rcp->rc_list);
 486         if (rcp->rc_list &&
 487             ((rcbp = rcp->rc_list->apl_data[alloc_cnt - 1]) != NULL) &&
 488             (rcbp->rc_free < rcbp->rc_end))
 489                 return (rcbp);
 490 
 491         /*
 492          * Allocate a new bucket. As we cannot know the number of relocations
 493          * we'll have in the active and output cache until after the link is
 494          * complete, the size of the bucket is a heuristic.
 495          *
 496          * In general, if the output object is an executable, or a sharable
 497          * object, then the size of the active relocation list will be nearly
 498          * the same as the number of input relocations, and the output
 499          * relocation list will be very short. If the output object is a
 500          * relocatable object, then the reverse is true. Therefore, the initial
 501          * allocation for the appropriate list is sized to fit all the input
 502          * allocations in a single shot.
 503          *
 504          * All other allocations are done in units of REL_CACHEBUF_ALLOC,
 505          * which is chosen to be large enough to cover most common cases,
 506          * but small enough that not using it fully is inconsequential.
 507          *
 508          * In an ideal scenario, this results in one allocation on each list.
 509          */
 510         nelts = REL_CACHEBUF_ALLOC;
 511         if ((alloc_cnt == 0) && (ofl->ofl_relocincnt > REL_CACHEBUF_ALLOC)) {
 512                 Boolean is_rel = (ofl->ofl_flags & FLG_OF_RELOBJ) != 0;
 513 
 514                 if (((rcp == &ofl->ofl_actrels) && !is_rel) ||
 515                     ((rcp == &ofl->ofl_outrels) && is_rel))
 516                         nelts = ofl->ofl_relocincnt;
 517         }
 518 
 519         /*
 520          * Compute the total number of bytes to allocate. The first element
 521          * of the array is built into the Rel_cachebuf header, so we subtract
 522          * one from nelts.
 523          */
 524         size = sizeof (Rel_cachebuf) + ((nelts - 1) * sizeof (Rel_desc));
 525 
 526         if (((rcbp = libld_malloc(size)) == NULL) ||
 527             (aplist_append(&rcp->rc_list, rcbp, AL_CNT_OFL_RELS) == NULL))
 528                 return (NULL);
 529 
 530         rcbp->rc_free = rcbp->rc_arr;
 531         rcbp->rc_end = rcbp->rc_arr + nelts;
 532 
 533         return (rcbp);
 534 }
 535 
 536 /*
 537  * Allocate a Rel_aux descriptor and attach it to the given Rel_desc,
 538  * allocating an auxiliary cache buffer if necessary.
 539  *
 540  * entry:
 541  *      ofl - Output file descriptor
 542  *      rdp - Rel_desc descriptor that requires an auxiliary block
 543  *
 544  * exit:
 545  *      Returns TRUE on success, and FALSE if the allocation fails.
 546  *      On success, the caller is responsible for initializing the
 547  *      auxiliary block properly.
 548  */
 549 static Boolean
 550 ld_add_rel_aux(Ofl_desc *ofl, Rel_desc *rdesc)
 551 {
 552         Rel_aux_cachebuf        *racp = NULL;
 553         size_t                  size;
 554 
 555         /*
 556          * If there is space available in the present cache bucket, use it.
 557          * Otherwise, allocate a new bucket.
 558          */
 559         if (ofl->ofl_relaux) {
 560                 racp = ofl->ofl_relaux->apl_data[
 561                     ofl->ofl_relaux->apl_nitems - 1];
 562 
 563                 if (racp && (racp->rac_free >= racp->rac_end))
 564                         racp = NULL;
 565         }
 566         if (racp == NULL) {
 567                 /*
 568                  * Compute the total number of bytes to allocate. The first
 569                  * element of the array is built into the Rel_aux_cachebuf
 570                  * header, so we subtract one from the number of elements.
 571                  */
 572                 size = sizeof (Rel_aux_cachebuf) +
 573                     ((RELAUX_CACHEBUF_ALLOC - 1) * sizeof (Rel_aux));
 574                 if (((racp = libld_malloc(size)) == NULL) ||
 575                     (aplist_append(&ofl->ofl_relaux, racp, AL_CNT_OFL_RELS) ==
 576                     NULL))
 577                         return (FALSE);
 578 
 579                 racp->rac_free = racp->rac_arr;
 580                 racp->rac_end = racp->rac_arr + RELAUX_CACHEBUF_ALLOC;
 581         }
 582 
 583         /* Take an auxiliary descriptor from the cache and add it to rdesc */
 584         rdesc->rel_aux = racp->rac_free++;
 585 
 586         return (TRUE);
 587 }
 588 
 589 /*
 590  * Enter a copy of the given Rel_desc relocation descriptor, and
 591  * any associated auxiliary Rel_aux it may reference, into the
 592  * specified relocation cache.
 593  *
 594  * entry:
 595  *      ofl - Output file descriptor
 596  *      rcp - Relocation descriptor cache to recieve relocation
 597  *      rdesc - Rel_desc image to be inserted
 598  *      flags - Flags to add to rdest->rel_flags in the inserted descriptor
 599  *
 600  * exit:
 601  *      Returns the pointer to the inserted descriptor on success.
 602  *      Returns NULL if an allocation error occurs.
 603  */
 604 Rel_desc *
 605 ld_reloc_enter(Ofl_desc *ofl, Rel_cache *rcp, Rel_desc *rdesc, Word flags)
 606 {
 607         Rel_desc        *arsp;
 608         Rel_aux         *auxp;
 609         Rel_cachebuf    *rcbp;
 610 
 611 
 612         /*
 613          * If no relocation cache structures are available, allocate a new
 614          * one and link it to the buffer list.
 615          */
 616         rcbp = ld_add_rel_cache(ofl, rcp);
 617         if (rcbp == NULL)
 618                 return (NULL);
 619         arsp = rcbp->rc_free;
 620 
 621         /*
 622          * If there is an auxiliary block on the original, allocate
 623          * one for the clone. Save the pointer, because the struct copy
 624          * below will crush it.
 625          */
 626         if (rdesc->rel_aux != NULL) {
 627                 if (!ld_add_rel_aux(ofl, arsp))
 628                         return (NULL);
 629                 auxp = arsp->rel_aux;
 630         }
 631 
 632         /* Copy contents of the original into the clone */
 633         *arsp = *rdesc;
 634 
 635         /*
 636          * If there is an auxiliary block, restore the clone's pointer to
 637          * it, and copy the auxiliary contents.
 638          */
 639         if (rdesc->rel_aux != NULL) {
 640                 arsp->rel_aux = auxp;
 641                 *auxp = *rdesc->rel_aux;
 642         }
 643         arsp->rel_flags |= flags;
 644 
 645         rcbp->rc_free++;
 646         rcp->rc_cnt++;
 647 
 648         return (arsp);
 649 }
 650 
 651 /*
 652  * Initialize a relocation descriptor auxiliary block to default
 653  * values.
 654  *
 655  * entry:
 656  *      rdesc - Relocation descriptor, with a non-NULL rel_aux field
 657  *              pointing at the auxiliary block to be initialized.
 658  *
 659  * exit:
 660  *      Each field in rdesc->rel_aux has been set to its default value
 661  */
 662 static void
 663 ld_init_rel_aux(Rel_desc *rdesc)
 664 {
 665         Rel_aux *rap = rdesc->rel_aux;
 666 
 667         /*
 668          * The default output section is the one the input section
 669          * is assigned to, assuming that there is an input section.
 670          * Failing that, NULL is the only possibility, and we expect
 671          * that the caller will assign an explicit value.
 672          */
 673         rap->ra_osdesc = (rdesc->rel_isdesc == NULL) ? NULL :
 674             rdesc->rel_isdesc->is_osdesc;
 675 
 676         /* The ra_usym defaults to the value in rel_sym */
 677         rap->ra_usym = rdesc->rel_sym;
 678 
 679         /* Remaining fields are zeroed */
 680         rap->ra_move = NULL;
 681         rap->ra_typedata = 0;
 682 }
 683 
 684 /*
 685  * The ld_reloc_set_aux_XXX() functions are used to set the value of an
 686  * auxiliary relocation item on a relocation descriptor that exists in
 687  * the active or output relocation cache. These descriptors are created
 688  * via a call to ld_reloc_enter().
 689  *
 690  * These functions preserve the illusion that every relocation descriptor
 691  * has a non-NULL auxiliary block into which values can be set, while
 692  * only creating an auxiliary block if one is actually necessary, preventing
 693  * the large memory allocations that would otherwise occur. They operate
 694  * as follows:
 695  *
 696  * -    If an auxiliary block already exists, set the desired value and
 697  *      and return TRUE.
 698  *
 699  * -    If no auxiliary block exists, but the desired value is the default
 700  *      value for the specified item, then no auxiliary block is needed,
 701  *      and TRUE is returned.
 702  *
 703  * -    If no auxiliary block exists, and the desired value is not the
 704  *      default for the specified item, allocate an auxiliary block for
 705  *      the descriptor, initialize its contents to default values for all
 706  *      items, set the specified value, and return TRUE.
 707  *
 708  * -    If an auxiliary block needs to be added, but the allocation fails,
 709  *      an error is issued, and FALSE is returned.
 710  *
 711  * Note that we only provide an ld_reloc_set_aux_XXX() function for those
 712  * auxiliary items that libld actually modifies in Rel_desc descriptors
 713  * in the active or output caches. If another one is needed, add it here.
 714  *
 715  * The PROCESS_NULL_REL_AUX macro is used to provide a single implementation
 716  * for the logic that determines if an auxiliary block is needed or not,
 717  * and handles the details of allocating and initializing it. It accepts
 718  * one argument, _isdefault_predicate, which should be a call to the
 719  * RELAUX_ISDEFAULT_xxx() macro appropriate for the auxiliary item
 720  */
 721 
 722 #define PROCESS_NULL_REL_AUX(_isdefault_predicate) \
 723         if (rdesc->rel_aux == NULL) { \
 724                 /* If requested value is the default, no need for aux block */ \
 725                 if (_isdefault_predicate) \
 726                         return (TRUE); \
 727                 /* Allocate and attach an auxiliary block */ \
 728                 if (!ld_add_rel_aux(ofl, rdesc)) \
 729                         return (FALSE); \
 730                 /* Initialize the auxiliary block with default values */ \
 731                 ld_init_rel_aux(rdesc); \
 732         }
 733 
 734 Boolean
 735 ld_reloc_set_aux_osdesc(Ofl_desc *ofl, Rel_desc *rdesc, Os_desc *osp)
 736 {
 737         PROCESS_NULL_REL_AUX(RELAUX_ISDEFAULT_OSDESC(rdesc, osp))
 738         rdesc->rel_aux->ra_osdesc = osp;
 739         return (TRUE);
 740 }
 741 
 742 Boolean
 743 ld_reloc_set_aux_usym(Ofl_desc *ofl, Rel_desc *rdesc, Sym_desc *sdp)
 744 {
 745         PROCESS_NULL_REL_AUX(RELAUX_ISDEFAULT_USYM(rdesc, sdp))
 746         rdesc->rel_aux->ra_usym = sdp;
 747         return (TRUE);
 748 }
 749 
 750 #undef PROCESS_NULL_REL_AUX
 751 
 752 /*
 753  * Return a descriptive name for the symbol associated with the
 754  * given relocation descriptor. This will be the actual symbol
 755  * name if one exists, or a suitable alternative otherwise.
 756  *
 757  * entry:
 758  *      rsp - Relocation descriptor
 759  */
 760 const char *
 761 ld_reloc_sym_name(Rel_desc *rsp)
 762 {
 763         Sym_desc        *sdp = rsp->rel_sym;
 764 
 765         if (sdp != NULL) {
 766                 /* If the symbol has a valid name use it */
 767                 if (sdp->sd_name && *sdp->sd_name)
 768                         return (demangle(sdp->sd_name));
 769 
 770                 /*
 771                  * If the symbol is STT_SECTION, and the corresponding
 772                  * section symbol has the specially prepared string intended
 773                  * for this use, use that string. The string is of the form
 774                  *      secname (section)
 775                  */
 776                 if ((ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION) &&
 777                     (sdp->sd_isc != NULL) && (sdp->sd_isc->is_sym_name != NULL))
 778                         return (demangle(sdp->sd_isc->is_sym_name));
 779         } else {
 780                 /*
 781                  * Use an empty name for a register relocation with
 782                  * no symbol.
 783                  */
 784                 if (IS_REGISTER(rsp->rel_rtype))
 785                         return (MSG_ORIG(MSG_STR_EMPTY));
 786         }
 787 
 788         /* If all else fails, report it as <unknown> */
 789         return (MSG_INTL(MSG_STR_UNKNOWN));
 790 }
 791 
 792 /*
 793  * Add an active relocation record.
 794  */
 795 uintptr_t
 796 ld_add_actrel(Word flags, Rel_desc *rsp, Ofl_desc *ofl)
 797 {
 798         Rel_desc        *arsp;
 799 
 800         if ((arsp = ld_reloc_enter(ofl, &ofl->ofl_actrels, rsp, flags)) == NULL)
 801                 return (S_ERROR);
 802 
 803         /*
 804          * Any GOT relocation reference requires the creation of a .got table.
 805          * Most references to a .got require a .got entry,  which is accounted
 806          * for with the ofl_gotcnt counter.  However, some references are
 807          * relative to the .got table, but require no .got entry.  This test
 808          * insures a .got is created regardless of the type of reference.
 809          */
 810         if (IS_GOT_REQUIRED(arsp->rel_rtype))
 811                 ofl->ofl_flags |= FLG_OF_BLDGOT;
 812 
 813         /*
 814          * If this is a displacement relocation generate a warning.
 815          */
 816         if (arsp->rel_flags & FLG_REL_DISP) {
 817                 ofl->ofl_dtflags_1 |= DF_1_DISPRELDNE;
 818 
 819                 if (ofl->ofl_flags & FLG_OF_VERBOSE)
 820                         ld_disp_errmsg(MSG_INTL(MSG_REL_DISPREL3), arsp, ofl);
 821         }
 822 
 823         DBG_CALL(Dbg_reloc_ars_entry(ofl->ofl_lml, ELF_DBG_LD,
 824             arsp->rel_isdesc->is_shdr->sh_type, ld_targ.t_m.m_mach, arsp));
 825         return (1);
 826 }
 827 
 828 /*
 829  * In the platform specific machrel.XXX.c files, we sometimes write
 830  * a value directly into the got/plt. These function can be used when
 831  * the running linker has the opposite byte order of the object being
 832  * produced.
 833  */
 834 Word
 835 ld_bswap_Word(Word v)
 836 {
 837         return (BSWAP_WORD(v));
 838 }
 839 
 840 
 841 Xword
 842 ld_bswap_Xword(Xword v)
 843 {
 844         return (BSWAP_XWORD(v));
 845 }
 846 
 847 
 848 uintptr_t
 849 ld_reloc_GOT_relative(Boolean local, Rel_desc *rsp, Ofl_desc *ofl)
 850 {
 851         Sym_desc        *sdp = rsp->rel_sym;
 852         ofl_flag_t      flags = ofl->ofl_flags;
 853         Gotndx          *gnp;
 854 
 855         /*
 856          * If this is the first time we've seen this symbol in a GOT
 857          * relocation we need to assign it a GOT token.  Once we've got
 858          * all of the GOT's assigned we can assign the actual indexes.
 859          */
 860         if ((gnp = (*ld_targ.t_mr.mr_find_got_ndx)(sdp->sd_GOTndxs,
 861             GOT_REF_GENERIC, ofl, rsp)) == 0) {
 862                 Word    rtype = rsp->rel_rtype;
 863 
 864                 if ((*ld_targ.t_mr.mr_assign_got_ndx)(&(sdp->sd_GOTndxs), NULL,
 865                     GOT_REF_GENERIC, ofl, rsp, sdp) == S_ERROR)
 866                         return (S_ERROR);
 867 
 868                 /*
 869                  * Initialize the GOT table entry.
 870                  *
 871                  * For global symbols, we clear the GOT table entry and create
 872                  * a GLOB_DAT relocation against the symbol.
 873                  *
 874                  * For local symbols, we enter the symbol value into a GOT
 875                  * table entry and create a relative relocation if all of
 876                  * the following hold:
 877                  *
 878                  * -    Output is a shared object
 879                  * -    Symbol is not ABS
 880                  * -    Relocation is not against one of the special sections
 881                  *      (COMMON, ...)
 882                  * -    This is not one of the generated symbols we have
 883                  *      to update after the output object has been fully
 884                  *      laid out (_START_, _END_, ...)
 885                  *
 886                  * Local symbols that don't meet the above requirements
 887                  * are processed as is.
 888                  */
 889                 if (local == TRUE) {
 890                         if ((flags & FLG_OF_SHAROBJ) &&
 891                             (((sdp->sd_flags & FLG_SY_SPECSEC) == 0) ||
 892                             ((sdp->sd_sym->st_shndx != SHN_ABS)) ||
 893                             (sdp->sd_aux && sdp->sd_aux->sa_symspec))) {
 894                                 if (ld_add_actrel((FLG_REL_GOT | FLG_REL_GOTCL),
 895                                     rsp, ofl) == S_ERROR)
 896                                         return (S_ERROR);
 897 
 898                                 rsp->rel_rtype = ld_targ.t_m.m_r_relative;
 899 
 900                                 if ((*ld_targ.t_mr.mr_add_outrel)
 901                                     ((FLG_REL_GOT | FLG_REL_ADVAL),
 902                                     rsp, ofl) == S_ERROR)
 903                                         return (S_ERROR);
 904 
 905                                 rsp->rel_rtype = rtype;
 906                         } else {
 907                                 if (ld_add_actrel(FLG_REL_GOT, rsp,
 908                                     ofl) == S_ERROR)
 909                                         return (S_ERROR);
 910                         }
 911                 } else {
 912                         rsp->rel_rtype = ld_targ.t_m.m_r_glob_dat;
 913                         if ((*ld_targ.t_mr.mr_add_outrel)(FLG_REL_GOT,
 914                             rsp, ofl) == S_ERROR)
 915                                 return (S_ERROR);
 916                         rsp->rel_rtype = rtype;
 917                 }
 918         } else {
 919                 if ((*ld_targ.t_mr.mr_assign_got_ndx)(&(sdp->sd_GOTndxs), gnp,
 920                     GOT_REF_GENERIC, ofl, rsp, sdp) == S_ERROR)
 921                         return (S_ERROR);
 922         }
 923 
 924         /*
 925          * Perform relocation to GOT table entry.
 926          */
 927         return (ld_add_actrel(NULL, rsp, ofl));
 928 }
 929 
 930 /*
 931  * Perform relocations for PLT's
 932  */
 933 uintptr_t
 934 ld_reloc_plt(Rel_desc *rsp, Ofl_desc *ofl)
 935 {
 936         Sym_desc        *sdp = rsp->rel_sym;
 937 
 938         switch (ld_targ.t_m.m_mach) {
 939         case EM_AMD64:
 940                 /*
 941                  * AMD64 TLS code sequences do not use a unique TLS
 942                  * relocation to reference the __tls_get_addr() function call.
 943                  */
 944                 if ((ofl->ofl_flags & FLG_OF_EXEC) &&
 945                     (strcmp(sdp->sd_name, MSG_ORIG(MSG_SYM_TLSGETADDR_U)) ==
 946                     0))
 947                         return (ld_add_actrel(FLG_REL_TLSFIX, rsp, ofl));
 948                 break;
 949 
 950         case EM_386:
 951                 /*
 952                  * GNUC IA32 TLS code sequences do not use a unique TLS
 953                  * relocation to reference the ___tls_get_addr() function call.
 954                  */
 955                 if ((ofl->ofl_flags & FLG_OF_EXEC) &&
 956                     (strcmp(sdp->sd_name, MSG_ORIG(MSG_SYM_TLSGETADDR_UU)) ==
 957                     0))
 958                         return (ld_add_actrel(FLG_REL_TLSFIX, rsp, ofl));
 959                 break;
 960         }
 961 
 962         /*
 963          * if (not PLT yet assigned)
 964          * then
 965          *      assign PLT index to symbol
 966          *      build output JMP_SLOT relocation
 967          * fi
 968          */
 969         if (sdp->sd_aux->sa_PLTndx == 0) {
 970                 Word    ortype = rsp->rel_rtype;
 971 
 972                 (*ld_targ.t_mr.mr_assign_plt_ndx)(sdp, ofl);
 973 
 974                 /*
 975                  * If this symbol is binding to a lazy loadable, or deferred
 976                  * dependency, then identify the symbol.
 977                  */
 978                 if (sdp->sd_file) {
 979                         if (sdp->sd_file->ifl_flags & FLG_IF_LAZYLD)
 980                                 sdp->sd_flags |= FLG_SY_LAZYLD;
 981                         if (sdp->sd_file->ifl_flags & FLG_IF_DEFERRED)
 982                                 sdp->sd_flags |= FLG_SY_DEFERRED;
 983                 }
 984 
 985                 rsp->rel_rtype = ld_targ.t_m.m_r_jmp_slot;
 986                 if ((*ld_targ.t_mr.mr_add_outrel)(FLG_REL_PLT, rsp, ofl) ==
 987                     S_ERROR)
 988                         return (S_ERROR);
 989                 rsp->rel_rtype = ortype;
 990         }
 991 
 992         /*
 993          * Perform relocation to PLT table entry.
 994          */
 995         if ((ofl->ofl_flags & FLG_OF_SHAROBJ) &&
 996             IS_ADD_RELATIVE(rsp->rel_rtype)) {
 997                 Word    ortype  = rsp->rel_rtype;
 998 
 999                 rsp->rel_rtype = ld_targ.t_m.m_r_relative;
1000                 if ((*ld_targ.t_mr.mr_add_outrel)(FLG_REL_ADVAL, rsp, ofl) ==
1001                     S_ERROR)
1002                         return (S_ERROR);
1003                 rsp->rel_rtype = ortype;
1004                 return (1);
1005         } else
1006                 return (ld_add_actrel(NULL, rsp, ofl));
1007 }
1008 
1009 /*
1010  * Round up to the next power of 2.  Used to ensure section alignments that can
1011  * be used for copy relocation symbol alignments are sane values.
1012  */
1013 static Word
1014 nlpo2(Word val)
1015 {
1016         val--;
1017         val |= (val >> 1);
1018         val |= (val >> 2);
1019         val |= (val >> 4);
1020         val |= (val >> 8);
1021         val |= (val >> 16);
1022         return (++val);
1023 }
1024 
1025 /*
1026  * process GLOBAL undefined and ref_dyn_need symbols.
1027  */
1028 static uintptr_t
1029 reloc_exec(Rel_desc *rsp, Ofl_desc *ofl)
1030 {
1031         Sym_desc        *_sdp, *sdp = rsp->rel_sym;
1032         Sym_aux         *sap = sdp->sd_aux;
1033         Sym             *sym = sdp->sd_sym;
1034         Addr            stval;
1035 
1036         /*
1037          * Reference is to a function so simply create a plt entry for it.
1038          */
1039         if (ELF_ST_TYPE(sym->st_info) == STT_FUNC)
1040                 return (ld_reloc_plt(rsp, ofl));
1041 
1042         /*
1043          * Catch absolutes - these may cause a text relocation.
1044          */
1045         if ((sdp->sd_flags & FLG_SY_SPECSEC) && (sym->st_shndx == SHN_ABS)) {
1046                 if ((ofl->ofl_flags1 & FLG_OF1_ABSEXEC) == 0)
1047                         return ((*ld_targ.t_mr.mr_add_outrel)(NULL, rsp, ofl));
1048 
1049                 /*
1050                  * If -zabsexec is set then promote the ABSOLUTE symbol to
1051                  * current the current object and perform the relocation now.
1052                  */
1053                 sdp->sd_ref = REF_REL_NEED;
1054                 return (ld_add_actrel(NULL, rsp, ofl));
1055         }
1056 
1057         /*
1058          * If the relocation is against a writable section simply compute the
1059          * necessary output relocation.  As an optimization, if the symbol has
1060          * already been transformed into a copy relocation then we can perform
1061          * the relocation directly (copy relocations should only be generated
1062          * for references from the text segment and these relocations are
1063          * normally carried out before we get to the data segment relocations).
1064          */
1065         if ((ELF_ST_TYPE(sym->st_info) == STT_OBJECT) &&
1066             (RELAUX_GET_OSDESC(rsp)->os_shdr->sh_flags & SHF_WRITE)) {
1067                 if (sdp->sd_flags & FLG_SY_MVTOCOMM)
1068                         return (ld_add_actrel(NULL, rsp, ofl));
1069                 else
1070                         return ((*ld_targ.t_mr.mr_add_outrel)(NULL, rsp, ofl));
1071         }
1072 
1073         /*
1074          * If the reference isn't to an object (normally because a .type
1075          * directive wasn't defined in some assembler source), then apply
1076          * a generic relocation (this has a tendency to result in text
1077          * relocations).
1078          */
1079         if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) {
1080                 Conv_inv_buf_t inv_buf;
1081 
1082                 ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_REL_UNEXPSYM),
1083                     conv_sym_info_type(sdp->sd_file->ifl_ehdr->e_machine,
1084                     ELF_ST_TYPE(sym->st_info), 0, &inv_buf),
1085                     rsp->rel_isdesc->is_file->ifl_name,
1086                     ld_reloc_sym_name(rsp), sdp->sd_file->ifl_name);
1087                 return ((*ld_targ.t_mr.mr_add_outrel)(NULL, rsp, ofl));
1088         }
1089 
1090         /*
1091          * Prepare for generating a copy relocation.
1092          *
1093          * If this symbol is one of an alias pair, we need to ensure both
1094          * symbols become part of the output (the strong symbol will be used to
1095          * maintain the symbols state).  And, if we did raise the precedence of
1096          * a symbol we need to check and see if this is a weak symbol.  If it is
1097          * we want to use it's strong counter part.
1098          *
1099          * The results of this logic should be:
1100          *      ra_usym: assigned to strong
1101          *      rel_sym: assigned to symbol to perform
1102          *              copy_reloc against (weak or strong).
1103          */
1104         if (sap->sa_linkndx) {
1105                 _sdp = sdp->sd_file->ifl_oldndx[sap->sa_linkndx];
1106 
1107                 if (_sdp->sd_ref < sdp->sd_ref) {
1108                         _sdp->sd_ref = sdp->sd_ref;
1109                         _sdp->sd_flags |= FLG_SY_REFRSD;
1110 
1111                         /*
1112                          * As we're going to replicate a symbol from a shared
1113                          * object, retain its correct binding status.
1114                          */
1115                         if (ELF_ST_BIND(_sdp->sd_sym->st_info) == STB_GLOBAL)
1116                                 _sdp->sd_flags |= FLG_SY_GLOBREF;
1117 
1118                 } else if (_sdp->sd_ref > sdp->sd_ref) {
1119                         sdp->sd_ref = _sdp->sd_ref;
1120                         sdp->sd_flags |= FLG_SY_REFRSD;
1121 
1122                         /*
1123                          * As we're going to replicate a symbol from a shared
1124                          * object, retain its correct binding status.
1125                          */
1126                         if (ELF_ST_BIND(sym->st_info) == STB_GLOBAL)
1127                                 sdp->sd_flags |= FLG_SY_GLOBREF;
1128                 }
1129 
1130                 /*
1131                  * If this is a weak symbol then we want to move the strong
1132                  * symbol into local .bss.  If there is a copy_reloc to be
1133                  * performed, that should still occur against the WEAK symbol.
1134                  */
1135                 if (((ELF_ST_BIND(sdp->sd_sym->st_info) == STB_WEAK) ||
1136                     (sdp->sd_flags & FLG_SY_WEAKDEF)) &&
1137                     !ld_reloc_set_aux_usym(ofl, rsp, _sdp))
1138                         return (S_ERROR);
1139         } else
1140                 _sdp = 0;
1141 
1142         /*
1143          * If the reference is to an object then allocate space for the object
1144          * within the executables .bss.  Relocations will now be performed from
1145          * this new location.  If the original shared objects data is
1146          * initialized, then generate a copy relocation that will copy the data
1147          * to the executables .bss at runtime.
1148          */
1149         if (!(RELAUX_GET_USYM(rsp)->sd_flags & FLG_SY_MVTOCOMM)) {
1150                 Word            rtype = rsp->rel_rtype, w2align;
1151                 Copy_rel        cr;
1152 
1153                 /*
1154                  * Diagnose the original copy reference, as this symbol
1155                  * information will be overridden with the new destination.
1156                  */
1157                 DBG_CALL(Dbg_syms_copy_reloc(ofl, sdp, 0));
1158 
1159                 /*
1160                  * Indicate that the symbol(s) against which we're relocating
1161                  * have been moved to the executables common.  Also, insure that
1162                  * the symbol(s) remain marked as global, as the shared object
1163                  * from which they are copied must be able to relocate to the
1164                  * new common location within the executable.
1165                  *
1166                  * Note that even though a new symbol has been generated in the
1167                  * output files' .bss, the symbol must remain REF_DYN_NEED and
1168                  * not be promoted to REF_REL_NEED.  sym_validate() still needs
1169                  * to carry out a number of checks against the symbols binding
1170                  * that are triggered by the REF_DYN_NEED state.
1171                  */
1172                 sdp->sd_flags |=
1173                     (FLG_SY_MVTOCOMM | FLG_SY_DEFAULT | FLG_SY_EXPDEF);
1174                 sdp->sd_flags &= ~MSK_SY_LOCAL;
1175                 sdp->sd_sym->st_other &= ~MSK_SYM_VISIBILITY;
1176                 if (_sdp) {
1177                         _sdp->sd_flags |= (FLG_SY_MVTOCOMM |
1178                             FLG_SY_DEFAULT | FLG_SY_EXPDEF);
1179                         _sdp->sd_flags &= ~MSK_SY_LOCAL;
1180                         _sdp->sd_sym->st_other &= ~MSK_SYM_VISIBILITY;
1181 
1182                         /*
1183                          * Make sure the symbol has a reference in case of any
1184                          * error diagnostics against it (perhaps this belongs
1185                          * to a version that isn't allowable for this build).
1186                          * The resulting diagnostic (see sym_undef_entry())
1187                          * might seem a little bogus, as the symbol hasn't
1188                          * really been referenced by this file, but has been
1189                          * promoted as a consequence of its alias reference.
1190                          */
1191                         if (!(_sdp->sd_aux->sa_rfile))
1192                                 _sdp->sd_aux->sa_rfile = sdp->sd_aux->sa_rfile;
1193                 }
1194 
1195                 /*
1196                  * Assign the symbol to the bss.
1197                  */
1198                 _sdp = RELAUX_GET_USYM(rsp);
1199                 stval = _sdp->sd_sym->st_value;
1200                 if (ld_sym_copy(_sdp) == S_ERROR)
1201                         return (S_ERROR);
1202                 _sdp->sd_shndx = _sdp->sd_sym->st_shndx = SHN_COMMON;
1203                 _sdp->sd_flags |= FLG_SY_SPECSEC;
1204 
1205                 /*
1206                  * Ensure the symbol has sufficient alignment.  The symbol
1207                  * definition has no alignment information that can be used,
1208                  * hence we use a heuristic.  Historically, twice the native
1209                  * word alignment was sufficient for any data type, however,
1210                  * the developer may have requested larger alignments (pragma
1211                  * align).  The most conservative approach is to use a power
1212                  * of two alignment, determined from the alignment of the
1213                  * section containing the symbol definition.  Note that this
1214                  * can result in some bloat to the .bss as the not every item
1215                  * of copied data might need the section alignment.
1216                  *
1217                  * COMMON symbols carry their alignment requirements in the
1218                  * symbols st_value field.  This alignment is applied to the
1219                  * symbol when it is eventually transformed into .bss.
1220                  */
1221                 w2align = ld_targ.t_m.m_word_align * 2;
1222                 if (_sdp->sd_sym->st_size < w2align)
1223                         _sdp->sd_sym->st_value = ld_targ.t_m.m_word_align;
1224                 else {
1225                         Shdr    *shdr;
1226                         Word    isalign;
1227 
1228                         if (_sdp->sd_isc &&
1229                             ((shdr = _sdp->sd_isc->is_shdr) != NULL) &&
1230                             ((isalign = shdr->sh_addralign) != 0))
1231                                 _sdp->sd_sym->st_value = nlpo2(isalign);
1232                         else
1233                                 _sdp->sd_sym->st_value = w2align;
1234                 }
1235 
1236                 /*
1237                  * Whether or not the symbol references initialized data we
1238                  * generate a copy relocation - this differs from the past
1239                  * where we would not create the COPY_RELOC if we were binding
1240                  * against .bss.  This is done for *two* reasons.
1241                  *
1242                  *  -   If the symbol in the shared object changes to a
1243                  *      initialized data - we need the COPY to pick it up.
1244                  *  -   Without the COPY RELOC we can't tell that the symbol
1245                  *      from the COPY'd object has been moved and all bindings
1246                  *      to it should bind here.
1247                  *
1248                  * Keep this symbol in the copy relocation list to check the
1249                  * validity later.
1250                  */
1251                 cr.c_sdp = _sdp;
1252                 cr.c_val = stval;
1253                 if (alist_append(&ofl->ofl_copyrels, &cr, sizeof (Copy_rel),
1254                     AL_CNT_OFL_COPYRELS) == NULL)
1255                         return (S_ERROR);
1256 
1257                 rsp->rel_rtype = ld_targ.t_m.m_r_copy;
1258                 if ((*ld_targ.t_mr.mr_add_outrel)(FLG_REL_BSS, rsp, ofl) ==
1259                     S_ERROR)
1260                         return (S_ERROR);
1261                 rsp->rel_rtype = rtype;
1262 
1263                 /*
1264                  * If this symbol is a protected symbol, warn the user.  A
1265                  * potential issue exists as the copy relocated symbol within
1266                  * the executable can be visible to others, whereas the shared
1267                  * object that defined the original copy data symbol is pre-
1268                  * bound to reference it's own definition.  Any modification
1269                  * of the symbols data could lead to inconsistencies for the
1270                  * various users.
1271                  */
1272                 if (_sdp->sd_flags & FLG_SY_PROT) {
1273                         Conv_inv_buf_t inv_buf;
1274 
1275                         ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_REL_COPY),
1276                             conv_reloc_type(_sdp->sd_file->ifl_ehdr->e_machine,
1277                             ld_targ.t_m.m_r_copy, 0, &inv_buf),
1278                             _sdp->sd_file->ifl_name, _sdp->sd_name);
1279                 }
1280                 DBG_CALL(Dbg_syms_copy_reloc(ofl, _sdp,
1281                     _sdp->sd_sym->st_value));
1282         }
1283         return (ld_add_actrel(NULL, rsp, ofl));
1284 }
1285 
1286 /*
1287  * All relocations should have been handled by the other routines.  This
1288  * routine is here as a catch all, if we do enter it we've goofed - but
1289  * we'll try and do the best we can.
1290  */
1291 static uintptr_t
1292 reloc_generic(Rel_desc *rsp, Ofl_desc *ofl)
1293 {
1294         Ifl_desc        *ifl = rsp->rel_isdesc->is_file;
1295         Conv_inv_buf_t  inv_buf;
1296 
1297         ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_REL_UNEXPREL),
1298             conv_reloc_type(ifl->ifl_ehdr->e_machine, rsp->rel_rtype,
1299             0, &inv_buf), ifl->ifl_name, ld_reloc_sym_name(rsp));
1300 
1301         /*
1302          * If building a shared object then put the relocation off
1303          * until runtime.
1304          */
1305         if (ofl->ofl_flags & FLG_OF_SHAROBJ)
1306                 return ((*ld_targ.t_mr.mr_add_outrel)(NULL, rsp, ofl));
1307 
1308         /*
1309          * Otherwise process relocation now.
1310          */
1311         return (ld_add_actrel(NULL, rsp, ofl));
1312 }
1313 
1314 /*
1315  * Process relocations when building a relocatable object.  Typically, there
1316  * aren't many relocations that can be caught at this point, most are simply
1317  * passed through to the output relocatable object.
1318  */
1319 static uintptr_t
1320 reloc_relobj(Boolean local, Rel_desc *rsp, Ofl_desc *ofl)
1321 {
1322         Word            rtype = rsp->rel_rtype;
1323         Sym_desc        *sdp = rsp->rel_sym;
1324         Is_desc         *isp = rsp->rel_isdesc;
1325         Word            oflags = NULL;
1326 
1327         /*
1328          * Determine if we can do any relocations at this point.  We can if:
1329          *
1330          *      this is local_symbol and a non-GOT relocation, and
1331          *      the relocation is pc-relative, and
1332          *      the relocation is against a symbol in same section
1333          */
1334         if (local && !IS_GOT_RELATIVE(rtype) &&
1335             !IS_GOT_BASED(rtype) && !IS_GOT_PC(rtype) &&
1336             IS_PC_RELATIVE(rtype) &&
1337             ((sdp->sd_isc) && (sdp->sd_isc->is_osdesc == isp->is_osdesc)))
1338                 return (ld_add_actrel(NULL, rsp, ofl));
1339 
1340         /*
1341          * If -zredlocsym is in effect, translate all local symbol relocations
1342          * to be against section symbols, since section symbols are the only
1343          * local symbols which will be added to the .symtab.
1344          */
1345         if (local && (((ofl->ofl_flags & FLG_OF_REDLSYM) &&
1346             (ELF_ST_BIND(sdp->sd_sym->st_info) == STB_LOCAL)) ||
1347             ((sdp->sd_flags & FLG_SY_ELIM) &&
1348             (ofl->ofl_flags & FLG_OF_PROCRED)))) {
1349                 /*
1350                  * But if this is PIC code, don't allow it for now.
1351                  */
1352                 if (IS_GOT_RELATIVE(rsp->rel_rtype)) {
1353                         Ifl_desc        *ifl = rsp->rel_isdesc->is_file;
1354                         Conv_inv_buf_t inv_buf;
1355 
1356                         ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_PICREDLOC),
1357                             ld_reloc_sym_name(rsp), ifl->ifl_name,
1358                             conv_reloc_type(ifl->ifl_ehdr->e_machine,
1359                             rsp->rel_rtype, 0, &inv_buf));
1360                         return (S_ERROR);
1361                 }
1362 
1363                 /*
1364                  * Indicate that this relocation should be processed the same
1365                  * as a section symbol.  For RELA, indicate that the addend
1366                  * also needs to be applied to this relocation.
1367                  */
1368                 if ((rsp->rel_flags & FLG_REL_RELA) == FLG_REL_RELA)
1369                         oflags = FLG_REL_SCNNDX | FLG_REL_ADVAL;
1370                 else
1371                         oflags = FLG_REL_SCNNDX;
1372         }
1373 
1374         if ((rsp->rel_flags & FLG_REL_RELA) == 0) {
1375                 /*
1376                  * Intel (Rel) relocations do not contain an addend.  Any
1377                  * addend is contained within the file at the location
1378                  * identified by the relocation offset.  Therefore, if we're
1379                  * processing a section symbol, or a -zredlocsym relocation
1380                  * (that basically transforms a local symbol reference into
1381                  * a section reference), perform an active relocation to
1382                  * propagate any addend.
1383                  */
1384                 if ((ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION) ||
1385                     (oflags == FLG_REL_SCNNDX))
1386                         if (ld_add_actrel(NULL, rsp, ofl) == S_ERROR)
1387                                 return (S_ERROR);
1388         }
1389         return ((*ld_targ.t_mr.mr_add_outrel)(oflags, rsp, ofl));
1390 }
1391 
1392 /*
1393  * Perform any generic TLS validations before passing control to machine
1394  * specific routines.  At this point we know we are dealing with an executable
1395  * or shared object - relocatable objects have already been processed.
1396  */
1397 static uintptr_t
1398 reloc_TLS(Boolean local, Rel_desc *rsp, Ofl_desc *ofl)
1399 {
1400         Word            rtype = rsp->rel_rtype;
1401         ofl_flag_t      flags = ofl->ofl_flags;
1402         Ifl_desc        *ifl = rsp->rel_isdesc->is_file;
1403         Half            mach = ifl->ifl_ehdr->e_machine;
1404         Sym_desc        *sdp = rsp->rel_sym;
1405         unsigned char   type;
1406         Conv_inv_buf_t  inv_buf1, inv_buf2;
1407 
1408         /*
1409          * All TLS relocations are illegal in a static executable.
1410          */
1411         if (OFL_IS_STATIC_EXEC(ofl)) {
1412                 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_TLSSTAT),
1413                     conv_reloc_type(mach, rtype, 0, &inv_buf1), ifl->ifl_name,
1414                     ld_reloc_sym_name(rsp));
1415                 return (S_ERROR);
1416         }
1417 
1418         /*
1419          * Any TLS relocation must be against a STT_TLS symbol, all others
1420          * are illegal.
1421          */
1422         if ((type = ELF_ST_TYPE(sdp->sd_sym->st_info)) != STT_TLS) {
1423                 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_TLSBADSYM),
1424                     conv_reloc_type(mach, rtype, 0, &inv_buf1), ifl->ifl_name,
1425                     ld_reloc_sym_name(rsp),
1426                     conv_sym_info_type(mach, type, 0, &inv_buf2));
1427                 return (S_ERROR);
1428         }
1429 
1430         /*
1431          * A dynamic executable can not use the LD or LE reference models to
1432          * reference an external symbol.  A shared object can not use the LD
1433          * reference model to reference an external symbol.
1434          */
1435         if (!local && (IS_TLS_LD(rtype) ||
1436             ((flags & FLG_OF_EXEC) && IS_TLS_LE(rtype)))) {
1437                 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_TLSBND),
1438                     conv_reloc_type(mach, rtype, 0, &inv_buf1), ifl->ifl_name,
1439                     ld_reloc_sym_name(rsp), sdp->sd_file->ifl_name);
1440                 return (S_ERROR);
1441         }
1442 
1443         /*
1444          * The TLS LE model is only allowed for dynamic executables.  The TLS IE
1445          * model is allowed for shared objects, but this model has restrictions.
1446          * This model can only be used freely in dependencies that are loaded
1447          * immediately as part of process initialization.  However, during the
1448          * initial runtime handshake with libc that establishes the thread
1449          * pointer, a small backup TLS reservation is created.  This area can
1450          * be used by objects that are loaded after threads are initialized.
1451          * However, this area is limited in size and may have already been
1452          * used.  This area is intended for specialized applications, and does
1453          * not provide the degree of flexibility dynamic TLS can offer.  Under
1454          * -z verbose indicate this restriction to the user.
1455          */
1456         if ((flags & FLG_OF_EXEC) == 0) {
1457                 if (IS_TLS_LE(rtype)) {
1458                         ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_TLSLE),
1459                             conv_reloc_type(mach, rtype, 0, &inv_buf1),
1460                             ifl->ifl_name, ld_reloc_sym_name(rsp));
1461                         return (S_ERROR);
1462 
1463                 } else if ((IS_TLS_IE(rtype)) &&
1464                     (flags & FLG_OF_VERBOSE)) {
1465                         ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_REL_TLSIE),
1466                             conv_reloc_type(mach, rtype, 0, &inv_buf1),
1467                             ifl->ifl_name, ld_reloc_sym_name(rsp));
1468                 }
1469         }
1470 
1471         return ((*ld_targ.t_mr.mr_reloc_TLS)(local, rsp, ofl));
1472 }
1473 
1474 uintptr_t
1475 ld_process_sym_reloc(Ofl_desc *ofl, Rel_desc *reld, Rel *reloc, Is_desc *isp,
1476     const char *isname, Word isscnndx)
1477 {
1478         Word            rtype = reld->rel_rtype;
1479         ofl_flag_t      flags = ofl->ofl_flags;
1480         Sym_desc        *sdp = reld->rel_sym;
1481         Sym_aux         *sap;
1482         Boolean         local;
1483         Conv_inv_buf_t  inv_buf;
1484 
1485         DBG_CALL(Dbg_reloc_in(ofl->ofl_lml, ELF_DBG_LD, ld_targ.t_m.m_mach,
1486             ld_targ.t_m.m_rel_sht_type, (void *)reloc, isname, isscnndx,
1487             ld_reloc_sym_name(reld)));
1488 
1489         /*
1490          * Indicate this symbol is being used for relocation and therefore must
1491          * have its output address updated accordingly (refer to update_osym()).
1492          */
1493         sdp->sd_flags |= FLG_SY_UPREQD;
1494 
1495         /*
1496          * Indicate the section this symbol is defined in has been referenced,
1497          * therefor it *is not* a candidate for elimination.
1498          */
1499         if (sdp->sd_isc) {
1500                 sdp->sd_isc->is_flags |= FLG_IS_SECTREF;
1501                 sdp->sd_isc->is_file->ifl_flags |= FLG_IF_FILEREF;
1502         }
1503 
1504         if (!ld_reloc_set_aux_usym(ofl, reld, sdp))
1505                 return (S_ERROR);
1506 
1507         /*
1508          * Determine if this symbol is actually an alias to another symbol.  If
1509          * so, and the alias is not REF_DYN_SEEN, set ra_usym to point to the
1510          * weak symbols strong counter-part.  The one exception is if the
1511          * FLG_SY_MVTOCOMM flag is set on the weak symbol.  If this is the case,
1512          * the strong is only here because of its promotion, and the weak symbol
1513          * should still be used for the relocation reference (see reloc_exec()).
1514          */
1515         sap = sdp->sd_aux;
1516         if (sap && sap->sa_linkndx &&
1517             ((ELF_ST_BIND(sdp->sd_sym->st_info) == STB_WEAK) ||
1518             (sdp->sd_flags & FLG_SY_WEAKDEF)) &&
1519             (!(sdp->sd_flags & FLG_SY_MVTOCOMM))) {
1520                 Sym_desc        *_sdp;
1521 
1522                 _sdp = sdp->sd_file->ifl_oldndx[sap->sa_linkndx];
1523                 if ((_sdp->sd_ref != REF_DYN_SEEN) &&
1524                     !ld_reloc_set_aux_usym(ofl, reld, _sdp))
1525                         return (S_ERROR);
1526         }
1527 
1528         /*
1529          * Determine whether this symbol should be bound locally or not.
1530          * Symbols are bound locally if one of the following is true:
1531          *
1532          *  -   the symbol is of type STB_LOCAL.
1533          *
1534          *  -   the output image is not a relocatable object and the relocation
1535          *      is relative to the .got.
1536          *
1537          *  -   the section being relocated is of type SHT_SUNW_dof.  These
1538          *      sections must be bound to the functions in the containing
1539          *      object and can not be interposed upon.
1540          *
1541          *  -   the symbol has been reduced (scoped to a local or symbolic) and
1542          *      reductions are being processed.
1543          *
1544          *  -   the -Bsymbolic flag is in use when building a shared object,
1545          *      and the symbol hasn't explicitly been defined as nodirect.
1546          *
1547          *  -   an executable (fixed address) is being created, and the symbol
1548          *      is defined in the executable.
1549          *
1550          *  -   the relocation is against a segment which will not be loaded
1551          *      into memory.  In this case, the relocation must be resolved
1552          *      now, as ld.so.1 can not process relocations against unmapped
1553          *      segments.
1554          */
1555         local = FALSE;
1556         if (ELF_ST_BIND(sdp->sd_sym->st_info) == STB_LOCAL) {
1557                 local = TRUE;
1558         } else if (!(reld->rel_flags & FLG_REL_LOAD)) {
1559                 local = TRUE;
1560         } else if (sdp->sd_sym->st_shndx != SHN_UNDEF) {
1561                 if (reld->rel_isdesc &&
1562                     reld->rel_isdesc->is_shdr->sh_type == SHT_SUNW_dof) {
1563                         local = TRUE;
1564                 } else if (!(flags & FLG_OF_RELOBJ) &&
1565                     (IS_LOCALBND(rtype) || IS_SEG_RELATIVE(rtype))) {
1566                         local = TRUE;
1567                 } else if ((sdp->sd_ref == REF_REL_NEED) &&
1568                     ((sdp->sd_flags & FLG_SY_CAP) == 0)) {
1569                         /*
1570                          * Global symbols may have been individually reduced in
1571                          * scope.  If the whole object is to be self contained,
1572                          * such as when generating an executable or a symbolic
1573                          * shared object, make sure all relocation symbol
1574                          * references (sections too) are treated locally.  Note,
1575                          * explicit no-direct symbols should not be bound to
1576                          * locally.
1577                          */
1578                         if ((sdp->sd_flags &
1579                             (FLG_SY_HIDDEN | FLG_SY_PROTECT)))
1580                                 local = TRUE;
1581                         else if ((flags & FLG_OF_EXEC) ||
1582                             ((flags & FLG_OF_SYMBOLIC) &&
1583                             ((sdp->sd_flags & FLG_SY_NDIR) == 0))) {
1584                                 local = TRUE;
1585                         }
1586                 }
1587         }
1588 
1589         /*
1590          * If this is a PC_RELATIVE relocation, the relocation could be
1591          * compromised if the relocated address is later used as a copy
1592          * relocated symbol (PSARC 1999/636, bugid 4187211).  Scan the input
1593          * files symbol table to cross reference this relocation offset.
1594          */
1595         if ((ofl->ofl_flags & FLG_OF_SHAROBJ) &&
1596             IS_PC_RELATIVE(rtype) &&
1597             (IS_GOT_PC(rtype) == 0) &&
1598             (IS_PLT(rtype) == 0)) {
1599                 if (disp_inspect(ofl, reld, local) == S_ERROR)
1600                         return (S_ERROR);
1601         }
1602 
1603         /*
1604          * GOT based relocations must bind to the object being built - since
1605          * they are relevant to the current GOT.  If not building a relocatable
1606          * object - give a appropriate error message.
1607          */
1608         if (!local && !(flags & FLG_OF_RELOBJ) &&
1609             IS_GOT_BASED(rtype)) {
1610                 Ifl_desc        *ifl = reld->rel_isdesc->is_file;
1611 
1612                 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_BADGOTBASED),
1613                     conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype,
1614                     0, &inv_buf), ifl->ifl_name, demangle(sdp->sd_name));
1615                 return (S_ERROR);
1616         }
1617 
1618         /*
1619          * TLS symbols can only have TLS relocations.
1620          */
1621         if ((ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_TLS) &&
1622             (IS_TLS_INS(rtype) == 0)) {
1623                 /*
1624                  * The above test is relaxed if the target section is
1625                  * non-allocable.
1626                  */
1627                 if (RELAUX_GET_OSDESC(reld)->os_shdr->sh_flags & SHF_ALLOC) {
1628                         Ifl_desc        *ifl = reld->rel_isdesc->is_file;
1629 
1630                         ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_BADTLS),
1631                             conv_reloc_type(ifl->ifl_ehdr->e_machine,
1632                             rtype, 0, &inv_buf), ifl->ifl_name,
1633                             demangle(sdp->sd_name));
1634                         return (S_ERROR);
1635                 }
1636         }
1637 
1638         /*
1639          * Select the relocation to perform.
1640          */
1641         if (IS_REGISTER(rtype)) {
1642                 if (ld_targ.t_mr.mr_reloc_register == NULL) {
1643                         ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_NOREG));
1644                         return (S_ERROR);
1645                 }
1646                 return ((*ld_targ.t_mr.mr_reloc_register)(reld, isp, ofl));
1647         }
1648 
1649         if (flags & FLG_OF_RELOBJ)
1650                 return (reloc_relobj(local, reld, ofl));
1651 
1652         if (IS_TLS_INS(rtype))
1653                 return (reloc_TLS(local, reld, ofl));
1654 
1655         if (IS_GOT_OPINS(rtype)) {
1656                 if (ld_targ.t_mr.mr_reloc_GOTOP == NULL) {
1657                         assert(0);
1658                         return (S_ERROR);
1659                 }
1660                 return ((*ld_targ.t_mr.mr_reloc_GOTOP)(local, reld, ofl));
1661         }
1662 
1663         if (IS_GOT_RELATIVE(rtype))
1664                 return (ld_reloc_GOT_relative(local, reld, ofl));
1665 
1666         if (local)
1667                 return ((*ld_targ.t_mr.mr_reloc_local)(reld, ofl));
1668 
1669         if ((IS_PLT(rtype) || ((sdp->sd_flags & FLG_SY_CAP) &&
1670             (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_FUNC))) &&
1671             ((flags & FLG_OF_BFLAG) == 0))
1672                 return (ld_reloc_plt(reld, ofl));
1673 
1674         if ((sdp->sd_ref == REF_REL_NEED) ||
1675             (flags & FLG_OF_BFLAG) || (flags & FLG_OF_SHAROBJ) ||
1676             (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_NOTYPE))
1677                 return ((*ld_targ.t_mr.mr_add_outrel)(NULL, reld, ofl));
1678 
1679         if (sdp->sd_ref == REF_DYN_NEED)
1680                 return (reloc_exec(reld, ofl));
1681 
1682         /*
1683          * IS_NOT_REL(rtype)
1684          */
1685         return (reloc_generic(reld, ofl));
1686 }
1687 
1688 /*
1689  * Given a relocation that references a local symbol from a discarded COMDAT
1690  * section, replace the symbol with the corresponding symbol from the section
1691  * that was kept.
1692  *
1693  * entry:
1694  *      reld - Relocation
1695  *      sdp - Symbol to be replaced. Must be a local symbol (STB_LOCAL).
1696  *      reject - Address of variable to receive rejection code
1697  *              if no replacement symbol is found.
1698  *
1699  * exit:
1700  *      Returns address of replacement symbol descriptor if one was
1701  *      found, and NULL otherwise. The result is also cached in
1702  *      ofl->ofl_sr_cache as an optimization to speed following calls
1703  *      for the same value of sdp.
1704  *
1705  *      On success (non-NULL result), *reject is set to RLXREL_REJ_NONE.
1706  *      On failure (NULL result), *reject is filled in with a code
1707  *      describing the underlying reason.
1708  *
1709  * note:
1710  *      The word "COMDAT" is used to refer to actual COMDAT sections, COMDAT
1711  *      groups tied together with an SHF_GROUP section, and .gnu.linkonce
1712  *      sections which provide a simplified COMDAT requirement.  COMDAT
1713  *      sections are identified with the FLG_IS_COMDAT section flag.
1714  *
1715  *      In principle, this sort of sloppy relocation remapping is
1716  *      a questionable practice. All self-referential sections should
1717  *      be in a common SHF_GROUP so that they are all kept or removed
1718  *      together. The problem is that there is no way to ensure that the
1719  *      two sections are similar enough that the replacement section will
1720  *      really supply the correct information. However, we see a couple of
1721  *      situations where it is useful to do this: (1) Older Sun C compilers
1722  *      generated DWARF sections that would refer to one of the COMDAT
1723  *      sections, and (2) gcc, when its GNU linkonce COMDAT feature is enabled.
1724  *      It turns out that the GNU ld does these sloppy remappings.
1725  *
1726  *      The GNU ld takes an approach that hard wires special section
1727  *      names and treats them specially. We avoid that practice and
1728  *      try to get the necessary work done relying only on the ELF
1729  *      attributes of the sections and symbols involved. This means
1730  *      that our heuristic is somewhat different than theirs, but the
1731  *      end result is close enough to solve the same problem.
1732  *
1733  *      gcc is in the process of converting to SHF_GROUP. This will
1734  *      eventually phase out the need for sloppy relocations, and
1735  *      then this logic won't be needed. In the meantime, relaxed relocation
1736  *      processing allows us to interoperate.
1737  */
1738 static Sym_desc *
1739 sloppy_comdat_reloc(Ofl_desc *ofl, Rel_desc *reld, Sym_desc *sdp,
1740     Rlxrel_rej *reject)
1741 {
1742         Is_desc         *rep_isp;
1743         Sym             *sym, *rep_sym;
1744         Is_desc         *isp;
1745         Ifl_desc        *ifl;
1746         Conv_inv_buf_t  inv_buf;
1747         Word            scnndx, symscnt;
1748         Sym_desc        **oldndx, *rep_sdp;
1749         const char      *is_name;
1750 
1751 
1752         /*
1753          * Sloppy relocations are never applied to .eh_frame or
1754          * .gcc_except_table sections. The entries in these sections
1755          * for discarded sections are better left uninitialized.
1756          *
1757          * We match these sections by name, because on most platforms they
1758          * are SHT_PROGBITS, and cannot be identified otherwise. On amd64
1759          * architectures, .eh_frame is SHT_AMD64_UNWIND, but that is ambiguous
1760          * (.eh_frame_hdr is also SHT_AMD64_UNWIND), so we still match it by
1761          * name.
1762          */
1763         is_name = reld->rel_isdesc->is_name;
1764         if (((is_name[1] == 'e') &&
1765             (strcmp(is_name, MSG_ORIG(MSG_SCN_EHFRAME)) == 0)) ||
1766             ((is_name[1] == 'g') &&
1767             (strcmp(is_name, MSG_ORIG(MSG_SCN_GCC_X_TBL)) == 0))) {
1768                 *reject = RLXREL_REJ_TARGET;
1769                 return (NULL);
1770         }
1771 
1772         /*
1773          * If we looked up the same symbol on the previous call, we can
1774          * return the cached value.
1775          */
1776         if (sdp == ofl->ofl_sr_cache.sr_osdp) {
1777                 *reject = ofl->ofl_sr_cache.sr_rej;
1778                 return (ofl->ofl_sr_cache.sr_rsdp);
1779         }
1780 
1781         ofl->ofl_sr_cache.sr_osdp = sdp;
1782         sym = sdp->sd_sym;
1783         isp = sdp->sd_isc;
1784         ifl = sdp->sd_file;
1785 
1786         /*
1787          * When a COMDAT section is discarded in favor of another COMDAT
1788          * section, the replacement is recorded in its section descriptor
1789          * (is_comdatkeep). We must validate the replacement before using
1790          * it. The replacement section must:
1791          *      - Not have been discarded
1792          *      - Have the same size (*)
1793          *      - Have the same section type
1794          *      - Have the same SHF_GROUP flag setting (either on or off)
1795          *      - Must be a COMDAT section of one form or the other.
1796          *
1797          * (*) One might imagine that the replacement section could be
1798          * larger than the original, rather than the exact size. However,
1799          * we have verified that this is the same policy used by the GNU
1800          * ld. If the sections are not the same size, the chance of them
1801          * being interchangeable drops significantly.
1802          */
1803         if (((rep_isp = isp->is_comdatkeep) == NULL) ||
1804             ((rep_isp->is_flags & FLG_IS_DISCARD) != 0) ||
1805             ((rep_isp->is_flags & FLG_IS_COMDAT) == 0) ||
1806             (isp->is_indata->d_size != rep_isp->is_indata->d_size) ||
1807             (isp->is_shdr->sh_type != rep_isp->is_shdr->sh_type) ||
1808             ((isp->is_shdr->sh_flags & SHF_GROUP) !=
1809             (rep_isp->is_shdr->sh_flags & SHF_GROUP))) {
1810                 *reject = ofl->ofl_sr_cache.sr_rej = RLXREL_REJ_SECTION;
1811                 return (ofl->ofl_sr_cache.sr_rsdp = NULL);
1812         }
1813 
1814         /*
1815          * We found the kept COMDAT section. Now, look at all of the
1816          * symbols from the input file that contains it to find the
1817          * symbol that corresponds to the one we started with:
1818          *      - Hasn't been discarded
1819          *      - Has section index of kept section
1820          *      - If one symbol has a name, the other must have
1821          *              the same name. The st_name field of a symbol
1822          *              is 0 if there is no name, and is a string
1823          *              table offset otherwise. The string table
1824          *              offsets may well not agree --- it is the
1825          *              actual string that matters.
1826          *      - Type and binding attributes match (st_info)
1827          *      - Values match (st_value)
1828          *      - Sizes match (st_size)
1829          *      - Visibility matches (st_other)
1830          */
1831         scnndx = rep_isp->is_scnndx;
1832         oldndx = rep_isp->is_file->ifl_oldndx;
1833         symscnt = rep_isp->is_file->ifl_symscnt;
1834         while (symscnt--) {
1835                 rep_sdp = *oldndx++;
1836                 if ((rep_sdp == NULL) || (rep_sdp->sd_flags & FLG_SY_ISDISC) ||
1837                     ((rep_sym = rep_sdp->sd_sym)->st_shndx != scnndx) ||
1838                     ((sym->st_name == 0) != (rep_sym->st_name == 0)) ||
1839                     ((sym->st_name != 0) &&
1840                     (strcmp(sdp->sd_name, rep_sdp->sd_name) != 0)) ||
1841                     (sym->st_info != rep_sym->st_info) ||
1842                     (sym->st_value != rep_sym->st_value) ||
1843                     (sym->st_size != rep_sym->st_size) ||
1844                     (sym->st_other != rep_sym->st_other))
1845                         continue;
1846 
1847 
1848                 if (ofl->ofl_flags & FLG_OF_VERBOSE) {
1849                         if (sym->st_name != 0) {
1850                                 ld_eprintf(ofl, ERR_WARNING,
1851                                     MSG_INTL(MSG_REL_SLOPCDATNAM),
1852                                     conv_reloc_type(ifl->ifl_ehdr->e_machine,
1853                                     reld->rel_rtype, 0, &inv_buf),
1854                                     ifl->ifl_name,
1855                                     EC_WORD(reld->rel_isdesc->is_scnndx),
1856                                     reld->rel_isdesc->is_name,
1857                                     rep_sdp->sd_name,
1858                                     EC_WORD(isp->is_scnndx), isp->is_name,
1859                                     rep_sdp->sd_file->ifl_name);
1860                         } else {
1861                                 ld_eprintf(ofl, ERR_WARNING,
1862                                     MSG_INTL(MSG_REL_SLOPCDATNONAM),
1863                                     conv_reloc_type(ifl->ifl_ehdr->e_machine,
1864                                     reld->rel_rtype, 0, &inv_buf),
1865                                     ifl->ifl_name,
1866                                     EC_WORD(reld->rel_isdesc->is_scnndx),
1867                                     reld->rel_isdesc->is_name,
1868                                     EC_WORD(isp->is_scnndx), isp->is_name,
1869                                     rep_sdp->sd_file->ifl_name);
1870                         }
1871                 }
1872                 DBG_CALL(Dbg_reloc_sloppycomdat(ofl->ofl_lml, rep_sdp));
1873                 *reject = ofl->ofl_sr_cache.sr_rej = RLXREL_REJ_NONE;
1874                 return (ofl->ofl_sr_cache.sr_rsdp = rep_sdp);
1875         }
1876 
1877         /* If didn't return above, we didn't find it */
1878         *reject = ofl->ofl_sr_cache.sr_rej = RLXREL_REJ_SYMBOL;
1879         return (ofl->ofl_sr_cache.sr_rsdp = NULL);
1880 }
1881 
1882 /*
1883  * Generate relocation descriptor and dispatch
1884  */
1885 static uintptr_t
1886 process_reld(Ofl_desc *ofl, Is_desc *isp, Rel_desc *reld, Word rsndx,
1887     Rel *reloc)
1888 {
1889         Ifl_desc        *ifl = isp->is_file;
1890         Word            rtype = reld->rel_rtype;
1891         Sym_desc        *sdp;
1892         Conv_inv_buf_t  inv_buf;
1893 
1894         /*
1895          * Make sure the relocation is in the valid range.
1896          */
1897         if (rtype >= ld_targ.t_m.m_r_num) {
1898                 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_INVALRELT),
1899                     ifl->ifl_name, EC_WORD(isp->is_scnndx), isp->is_name,
1900                     rtype);
1901                 return (S_ERROR);
1902         }
1903 
1904         ofl->ofl_entrelscnt++;
1905 
1906         /*
1907          * Special case: a register symbol associated with symbol index 0 is
1908          * initialized (i.e., relocated) to a constant from the r_addend field
1909          * rather than from a symbol value.
1910          */
1911         if (IS_REGISTER(rtype) && (rsndx == 0)) {
1912                 reld->rel_sym = NULL;
1913                 DBG_CALL(Dbg_reloc_in(ofl->ofl_lml, ELF_DBG_LD,
1914                     ld_targ.t_m.m_mach, isp->is_shdr->sh_type,
1915                     (void *)reloc, isp->is_name, isp->is_scnndx,
1916                     ld_reloc_sym_name(reld)));
1917                 if (ld_targ.t_mr.mr_reloc_register == NULL) {
1918                         ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_NOREG));
1919                         return (S_ERROR);
1920                 }
1921                 return ((*ld_targ.t_mr.mr_reloc_register)(reld, isp, ofl));
1922         }
1923 
1924         /*
1925          * If this is a STT_SECTION symbol, make sure the associated
1926          * section has a descriptive non-NULL is_sym_name field that can
1927          * be accessed by ld_reloc_sym_name() to satisfy debugging output
1928          * and errors.
1929          *
1930          * In principle, we could add this string to every input section
1931          * as it is created, but we defer it until we see a relocation
1932          * symbol that might need it. Not every section will have such
1933          * a relocation, so we create fewer of them this way.
1934          */
1935         sdp = reld->rel_sym = ifl->ifl_oldndx[rsndx];
1936         if ((sdp != NULL) &&
1937             (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION) &&
1938             (sdp->sd_isc != NULL) && (sdp->sd_isc->is_name != NULL) &&
1939             (sdp->sd_isc->is_sym_name == NULL) &&
1940             (ld_stt_section_sym_name(sdp->sd_isc) == NULL))
1941                 return (S_ERROR);
1942 
1943         /*
1944          * If for some reason we have a null relocation record issue a
1945          * warning and continue (the compiler folks can get into this
1946          * state some time).  Normal users should never see this error.
1947          */
1948         if (rtype == ld_targ.t_m.m_r_none) {
1949                 DBG_CALL(Dbg_reloc_in(ofl->ofl_lml, ELF_DBG_LD,
1950                     ld_targ.t_m.m_mach, ld_targ.t_m.m_rel_sht_type,
1951                     (void *)reloc, isp->is_name, isp->is_scnndx,
1952                     ld_reloc_sym_name(reld)));
1953                 ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_REL_NULL),
1954                     ifl->ifl_name, EC_WORD(isp->is_scnndx), isp->is_name);
1955                 return (1);
1956         }
1957 
1958         if (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) &&
1959             IS_NOTSUP(rtype)) {
1960                 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_NOTSUP),
1961                     conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype,
1962                     0, &inv_buf), ifl->ifl_name, EC_WORD(isp->is_scnndx),
1963                     isp->is_name);
1964                 return (S_ERROR);
1965         }
1966 
1967         /*
1968          * If we are here, we know that the relocation requires reference
1969          * symbol. If no symbol is assigned, this is a fatal error.
1970          */
1971         if (sdp == NULL) {
1972                 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_NOSYMBOL),
1973                     conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype,
1974                     0, &inv_buf), ifl->ifl_name, EC_WORD(isp->is_scnndx),
1975                     isp->is_name, EC_XWORD(reloc->r_offset));
1976                 return (S_ERROR);
1977         }
1978 
1979         if (sdp->sd_flags & FLG_SY_IGNORE)
1980                 return (1);
1981 
1982         /*
1983          * If this symbol is part of a DISCARDED section attempt to find another
1984          * definition.
1985          */
1986         if (sdp->sd_flags & FLG_SY_ISDISC) {
1987                 Sym_desc        *nsdp = NULL;
1988                 Rlxrel_rej      reject;
1989 
1990                 if (ELF_ST_BIND(sdp->sd_sym->st_info) == STB_LOCAL) {
1991                         /*
1992                          * If "-z relaxreloc", and the input section is COMDAT
1993                          * that has been assigned to an output section, then
1994                          * determine if this is a reference to a discarded
1995                          * COMDAT section that can be replaced with a COMDAT
1996                          * that has been kept.
1997                          */
1998                         if ((ofl->ofl_flags1 & FLG_OF1_RLXREL) &&
1999                             sdp->sd_isc->is_osdesc &&
2000                             (sdp->sd_isc->is_flags & FLG_IS_COMDAT) &&
2001                             ((nsdp = sloppy_comdat_reloc(ofl, reld,
2002                             sdp, &reject)) == NULL)) {
2003                                 Shdr    *is_shdr = reld->rel_isdesc->is_shdr;
2004 
2005                                 /*
2006                                  * A matching symbol was not found. We will
2007                                  * ignore this relocation.  Determine whether
2008                                  * or not to issue a warning.
2009                                  * Warnings are always issued under -z verbose,
2010                                  * but otherwise, we will follow the lead of
2011                                  * the GNU ld and suppress them for certain
2012                                  * cases:
2013                                  *
2014                                  *  -   It is a non-allocable debug section.
2015                                  *      The GNU ld tests for these by name,
2016                                  *      but we are willing to extend it to
2017                                  *      any non-allocable/read-only section.
2018                                  *  -   The target section is excluded from
2019                                  *      sloppy relocations by policy.
2020                                  */
2021                                 if (((ofl->ofl_flags & FLG_OF_VERBOSE) != 0) ||
2022                                     ((is_shdr->sh_flags & SHF_ALLOC) &&
2023                                     (is_shdr->sh_flags & SHF_WRITE) &&
2024                                     (reject != RLXREL_REJ_TARGET)))
2025                                         ld_eprintf(ofl, ERR_WARNING,
2026                                             MSG_INTL(MSG_REL_SLOPCDATNOSYM),
2027                                             conv_reloc_type(
2028                                             ifl->ifl_ehdr->e_machine,
2029                                             reld->rel_rtype, 0, &inv_buf),
2030                                             ifl->ifl_name,
2031                                             EC_WORD(isp->is_scnndx),
2032                                             isp->is_name,
2033                                             ld_reloc_sym_name(reld),
2034                                             EC_WORD(sdp->sd_isc->is_scnndx),
2035                                             sdp->sd_isc->is_name);
2036                                 return (1);
2037                         }
2038                 } else if ((sdp != NULL) && sdp->sd_name && *sdp->sd_name)
2039                         nsdp = ld_sym_find(sdp->sd_name, SYM_NOHASH, NULL, ofl);
2040 
2041                 if (nsdp == NULL) {
2042                         ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_SYMDISC),
2043                             conv_reloc_type(ifl->ifl_ehdr->e_machine,
2044                             reld->rel_rtype, 0, &inv_buf), ifl->ifl_name,
2045                             EC_WORD(isp->is_scnndx), isp->is_name,
2046                             ld_reloc_sym_name(reld),
2047                             EC_WORD(sdp->sd_isc->is_scnndx),
2048                             sdp->sd_isc->is_name);
2049                         return (S_ERROR);
2050                 }
2051                 ifl->ifl_oldndx[rsndx] = sdp = nsdp;
2052                 if ((ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION) &&
2053                     (sdp->sd_isc != NULL) && (sdp->sd_isc->is_name != NULL) &&
2054                     (sdp->sd_isc->is_sym_name == NULL) &&
2055                     (ld_stt_section_sym_name(sdp->sd_isc) == NULL))
2056                         return (S_ERROR);
2057         }
2058 
2059         /*
2060          * If this is a global symbol, determine whether its visibility needs
2061          * adjusting.
2062          */
2063         if (sdp->sd_aux && ((sdp->sd_flags & FLG_SY_VISIBLE) == 0))
2064                 ld_sym_adjust_vis(sdp, ofl);
2065 
2066         /*
2067          * Ignore any relocation against a section that will not be in the
2068          * output file (has been stripped).
2069          */
2070         if ((sdp->sd_isc == 0) &&
2071             (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION))
2072                 return (1);
2073 
2074         /*
2075          * If the input section exists, but the section has not been associated
2076          * to an output section, then this is a little suspicious.
2077          */
2078         if (sdp->sd_isc && (sdp->sd_isc->is_osdesc == 0) &&
2079             (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION)) {
2080                 ld_eprintf(ofl, ERR_WARNING, MSG_INTL(MSG_RELINVSEC),
2081                     conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype,
2082                     0, &inv_buf), ifl->ifl_name, EC_WORD(isp->is_scnndx),
2083                     isp->is_name, EC_WORD(sdp->sd_isc->is_scnndx),
2084                     sdp->sd_isc->is_name);
2085                 return (1);
2086         }
2087 
2088         /*
2089          * If the symbol for this relocation is invalid (which should have
2090          * generated a message during symbol processing), or the relocation
2091          * record's symbol reference is in any other way invalid, then it's
2092          * about time we gave up.
2093          */
2094         if ((sdp->sd_flags & FLG_SY_INVALID) || (rsndx == 0) ||
2095             (rsndx >= ifl->ifl_symscnt)) {
2096                 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_UNKNWSYM),
2097                     conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype,
2098                     0, &inv_buf), ifl->ifl_name, EC_WORD(isp->is_scnndx),
2099                     isp->is_name, ld_reloc_sym_name(reld),
2100                     EC_XWORD(reloc->r_offset), EC_WORD(rsndx));
2101                 return (S_ERROR);
2102         }
2103 
2104         /*
2105          * Size relocations against section symbols are presently unsupported.
2106          * There is a question as to whether the input section size, or output
2107          * section size would be used.  Until an explicit requirement is
2108          * established for either case, we'll punt.
2109          */
2110         if (IS_SIZE(rtype) &&
2111             (ELF_ST_TYPE(sdp->sd_sym->st_info) == STT_SECTION)) {
2112                 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_UNSUPSIZE),
2113                     conv_reloc_type(ifl->ifl_ehdr->e_machine, rtype,
2114                     0, &inv_buf), ifl->ifl_name, EC_WORD(isp->is_scnndx),
2115                     isp->is_name);
2116                 return (S_ERROR);
2117         }
2118 
2119         reld->rel_sym = sdp;
2120         if (reld->rel_aux)
2121                 reld->rel_aux->ra_usym = sdp;
2122         return (ld_process_sym_reloc(ofl, reld, reloc, isp, isp->is_name,
2123             isp->is_scnndx));
2124 }
2125 
2126 static uintptr_t
2127 reloc_section(Ofl_desc *ofl, Is_desc *isect, Is_desc *rsect, Os_desc *osect)
2128 {
2129         Rel             *rend;          /* end of relocation section data */
2130         Rel             *reloc;         /* current relocation entry */
2131         Xword           rsize;          /* size of relocation section data */
2132         Xword           entsize;        /* size of relocation entry */
2133         Rel_desc        reld;           /* relocation descriptor */
2134         Rel_aux rel_aux;
2135         Shdr *          shdr;
2136         Word            flags = 0;
2137         uintptr_t       ret = 1;
2138 
2139         shdr = rsect->is_shdr;
2140         rsize = shdr->sh_size;
2141         reloc = (Rel *)rsect->is_indata->d_buf;
2142 
2143         /*
2144          * Decide entry size.
2145          */
2146         if (((entsize = shdr->sh_entsize) == 0) || (entsize > rsize)) {
2147                 if (shdr->sh_type == SHT_RELA)
2148                         entsize = sizeof (Rela);
2149                 else
2150                         entsize = sizeof (Rel);
2151         }
2152 
2153         /*
2154          * Build up the basic information in for the Rel_desc structure.
2155          */
2156         reld.rel_isdesc = isect;
2157         reld.rel_aux = &rel_aux;
2158         ld_init_rel_aux(&reld);
2159         rel_aux.ra_osdesc = osect;
2160 
2161         if ((ofl->ofl_flags & FLG_OF_RELOBJ) ||
2162             (osect && (osect->os_sgdesc->sg_phdr.p_type == PT_LOAD)))
2163                 flags |= FLG_REL_LOAD;
2164 
2165         if (shdr->sh_info == 0)
2166                 flags |= FLG_REL_NOINFO;
2167 
2168         DBG_CALL(Dbg_reloc_proc(ofl->ofl_lml, osect, isect, rsect));
2169 
2170         for (rend = (Rel *)((uintptr_t)reloc + (uintptr_t)rsize);
2171             reloc < rend;
2172             reloc = (Rel *)((uintptr_t)reloc + (uintptr_t)entsize)) {
2173                 Word    rsndx;
2174 
2175                 /*
2176                  * Initialize the relocation record information and process
2177                  * the individual relocation.  Reinitialize the flags to
2178                  * insure we don't carry any state over from the previous
2179                  * relocation records processing.
2180                  */
2181                 reld.rel_flags = flags;
2182                 rsndx = (*ld_targ.t_mr.mr_init_rel)(&reld,
2183                     &rel_aux.ra_typedata, (void *)reloc);
2184 
2185                 /*
2186                  * Determine whether or not to pass an auxiliary block
2187                  * in with this Rel_desc. It is not needed if both the
2188                  * osdesc and typedata fields have default values.
2189                  */
2190                 reld.rel_aux =
2191                     (RELAUX_ISDEFAULT_OSDESC(&reld, rel_aux.ra_osdesc) &&
2192                     RELAUX_ISDEFAULT_TYPEDATA(&reld, rel_aux.ra_typedata)) ?
2193                     NULL : &rel_aux;
2194 
2195                 if (process_reld(ofl, rsect, &reld, rsndx, reloc) == S_ERROR)
2196                         ret = S_ERROR;
2197         }
2198         return (ret);
2199 }
2200 
2201 static uintptr_t
2202 reloc_segments(int wr_flag, Ofl_desc *ofl)
2203 {
2204         Aliste          idx1;
2205         Sg_desc         *sgp;
2206         Is_desc         *isp;
2207 
2208         for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp)) {
2209                 Os_desc *osp;
2210                 Aliste  idx2;
2211 
2212                 if ((sgp->sg_phdr.p_flags & PF_W) != wr_flag)
2213                         continue;
2214 
2215                 for (APLIST_TRAVERSE(sgp->sg_osdescs, idx2, osp)) {
2216                         Is_desc *risp;
2217                         Aliste  idx3;
2218 
2219                         osp->os_szoutrels = 0;
2220                         for (APLIST_TRAVERSE(osp->os_relisdescs, idx3, risp)) {
2221                                 Word    indx;
2222 
2223                                 /*
2224                                  * Determine the input section that this
2225                                  * relocation information refers to.
2226                                  */
2227                                 indx = risp->is_shdr->sh_info;
2228                                 isp = risp->is_file->ifl_isdesc[indx];
2229 
2230                                 /*
2231                                  * Do not process relocations against sections
2232                                  * which are being discarded (COMDAT)
2233                                  */
2234                                 if (isp->is_flags & FLG_IS_DISCARD)
2235                                         continue;
2236 
2237                                 if (reloc_section(ofl, isp, risp, osp) ==
2238                                     S_ERROR)
2239                                         return (S_ERROR);
2240                         }
2241 
2242                         /*
2243                          * Check for relocations against non-writable
2244                          * allocatable sections.
2245                          */
2246                         if (osp->os_szoutrels &&
2247                             (sgp->sg_phdr.p_type == PT_LOAD) &&
2248                             ((sgp->sg_phdr.p_flags & PF_W) == 0)) {
2249                                 ofl->ofl_flags |= FLG_OF_TEXTREL;
2250                                 ofl->ofl_dtflags |= DF_TEXTREL;
2251                         }
2252                 }
2253         }
2254 
2255         return (1);
2256 }
2257 
2258 /*
2259  * Move Section related function
2260  * Get move entry
2261  */
2262 static Move *
2263 get_move_entry(Is_desc *rsect, Xword roffset)
2264 {
2265         Ifl_desc        *ifile = rsect->is_file;
2266         Shdr            *rshdr = rsect->is_shdr;
2267         Is_desc         *misp;
2268         Shdr            *mshdr;
2269         Xword           midx;
2270         Move            *mvp;
2271 
2272         /*
2273          * Set info for the target move section
2274          */
2275         misp = ifile->ifl_isdesc[rshdr->sh_info];
2276         mshdr = misp->is_shdr;
2277 
2278         if (mshdr->sh_entsize == 0)
2279                 return (NULL);
2280 
2281         /*
2282          * If this is an invalid entry, return NULL.
2283          */
2284         midx = roffset / mshdr->sh_entsize;
2285         if ((midx * mshdr->sh_entsize) >= mshdr->sh_size)
2286                 return (NULL);
2287 
2288         mvp = (Move *)misp->is_indata->d_buf;
2289         mvp += midx;
2290         return (mvp);
2291 }
2292 
2293 /*
2294  * Relocation against Move Table.
2295  */
2296 static uintptr_t
2297 process_movereloc(Ofl_desc *ofl, Is_desc *rsect)
2298 {
2299         Ifl_desc        *file = rsect->is_file;
2300         Rel             *rend, *reloc;
2301         Xword           rsize, entsize;
2302         Rel_desc        reld;
2303         Rel_aux rel_aux;
2304 
2305         rsize = rsect->is_shdr->sh_size;
2306         reloc = (Rel *)rsect->is_indata->d_buf;
2307 
2308         /*
2309          * Decide entry size.
2310          */
2311         entsize = rsect->is_shdr->sh_entsize;
2312         if ((entsize == 0) ||
2313             (entsize > rsect->is_shdr->sh_size)) {
2314                 if (rsect->is_shdr->sh_type == SHT_RELA)
2315                         entsize = sizeof (Rela);
2316                 else
2317                         entsize = sizeof (Rel);
2318         }
2319 
2320         /*
2321          * The requirement for move data ensures that we have to supply a
2322          * Rel_aux auxiliary block.
2323          */
2324         reld.rel_aux = &rel_aux;
2325         ld_init_rel_aux(&reld);
2326 
2327         /*
2328          * Go through the relocation entries.
2329          */
2330         for (rend = (Rel *)((uintptr_t)reloc + (uintptr_t)rsize);
2331             reloc < rend;
2332             reloc = (Rel *)((uintptr_t)reloc + (uintptr_t)entsize)) {
2333                 Sym_desc        *psdp;
2334                 Move            *mvp;
2335                 Word            rsndx;
2336 
2337                 /*
2338                  * Initialize the relocation record information.
2339                  */
2340                 reld.rel_flags = FLG_REL_LOAD;
2341                 rsndx = (*ld_targ.t_mr.mr_init_rel)(&reld,
2342                     &rel_aux.ra_typedata, (void *)reloc);
2343 
2344                 if (((mvp = get_move_entry(rsect, reloc->r_offset)) == NULL) ||
2345                     ((rel_aux.ra_move =
2346                     libld_malloc(sizeof (Mv_reloc))) == NULL))
2347                         return (S_ERROR);
2348 
2349                 psdp = file->ifl_oldndx[ELF_M_SYM(mvp->m_info)];
2350                 rel_aux.ra_move->mr_move = mvp;
2351                 rel_aux.ra_move->mr_sym = psdp;
2352 
2353                 if (psdp->sd_flags & FLG_SY_PAREXPN) {
2354                         int     _num, num = mvp->m_repeat;
2355 
2356                         rel_aux.ra_osdesc = ofl->ofl_isparexpn->is_osdesc;
2357                         reld.rel_isdesc = ofl->ofl_isparexpn;
2358                         reld.rel_roffset = mvp->m_poffset;
2359 
2360                         for (_num = 0; _num < num; _num++) {
2361                                 reld.rel_roffset +=
2362                                     /* LINTED */
2363                                     (_num * ELF_M_SIZE(mvp->m_info));
2364 
2365                                 /*
2366                                  * Generate Reld
2367                                  */
2368                                 if (process_reld(ofl,
2369                                     rsect, &reld, rsndx, reloc) == S_ERROR)
2370                                         return (S_ERROR);
2371                         }
2372                 } else {
2373                         /*
2374                          * Generate Reld
2375                          */
2376                         reld.rel_flags |= FLG_REL_MOVETAB;
2377                         rel_aux.ra_osdesc = ofl->ofl_osmove;
2378                         reld.rel_isdesc = ld_os_first_isdesc(ofl->ofl_osmove);
2379 
2380                         if (process_reld(ofl,
2381                             rsect, &reld, rsndx, reloc) == S_ERROR)
2382                                 return (S_ERROR);
2383                 }
2384         }
2385         return (1);
2386 }
2387 
2388 /*
2389  * This function is similar to reloc_init().
2390  *
2391  * This function is called when the SHT_SUNW_move table is expanded and there
2392  * are relocations against the SHT_SUNW_move section.
2393  */
2394 static uintptr_t
2395 reloc_movesections(Ofl_desc *ofl)
2396 {
2397         Aliste          idx;
2398         Is_desc         *risp;
2399         uintptr_t       ret = 1;
2400 
2401         /*
2402          * Generate/Expand relocation entries
2403          */
2404         for (APLIST_TRAVERSE(ofl->ofl_ismoverel, idx, risp)) {
2405                 if (process_movereloc(ofl, risp) == S_ERROR)
2406                         ret = S_ERROR;
2407         }
2408 
2409         return (ret);
2410 }
2411 
2412 /*
2413  * Count the number of output relocation entries, global offset table entries,
2414  * and procedure linkage table entries.  This function searches the segment and
2415  * outsect lists and passes each input reloc section to process_reloc().
2416  * It allocates space for any output relocations needed.  And builds up
2417  * the relocation structures for later processing.
2418  */
2419 uintptr_t
2420 ld_reloc_init(Ofl_desc *ofl)
2421 {
2422         Aliste          idx;
2423         Is_desc         *isp;
2424         Sym_desc        *sdp;
2425 
2426         DBG_CALL(Dbg_basic_collect(ofl->ofl_lml));
2427 
2428         /*
2429          * At this point we have finished processing all input symbols.  Make
2430          * sure we add any absolute (internal) symbols before continuing with
2431          * any relocation processing.
2432          */
2433         if (ld_sym_spec(ofl) == S_ERROR)
2434                 return (S_ERROR);
2435 
2436         ofl->ofl_gotcnt = ld_targ.t_m.m_got_xnumber;
2437 
2438         /*
2439          * Process all of the relocations against NON-writable segments
2440          * followed by relocations against the writable segments.
2441          *
2442          * This separation is so that when the writable segments are processed
2443          * we know whether or not a COPYRELOC will be produced for any symbols.
2444          * If relocations aren't processed in this order, a COPYRELOC and a
2445          * regular relocation can be produced against the same symbol.  The
2446          * regular relocation would be redundant.
2447          */
2448         if (reloc_segments(0, ofl) == S_ERROR)
2449                 return (S_ERROR);
2450 
2451         if (reloc_segments(PF_W, ofl) == S_ERROR)
2452                 return (S_ERROR);
2453 
2454         /*
2455          * Process any extra relocations.  These are relocation sections that
2456          * have a NULL sh_info.
2457          */
2458         for (APLIST_TRAVERSE(ofl->ofl_extrarels, idx, isp)) {
2459                 if (reloc_section(ofl, NULL, isp, NULL) == S_ERROR)
2460                         return (S_ERROR);
2461         }
2462 
2463         /*
2464          * If there were relocation against move table,
2465          * process the relocation sections.
2466          */
2467         if (reloc_movesections(ofl) == S_ERROR)
2468                 return (S_ERROR);
2469 
2470         /*
2471          * Now all the relocations are pre-processed,
2472          * check the validity of copy relocations.
2473          */
2474         if (ofl->ofl_copyrels) {
2475                 Copy_rel        *crp;
2476 
2477                 for (ALIST_TRAVERSE(ofl->ofl_copyrels, idx, crp)) {
2478                         /*
2479                          * If there were no displacement relocation
2480                          * in this file, don't worry about it.
2481                          */
2482                         if (crp->c_sdp->sd_file->ifl_flags &
2483                             (FLG_IF_DISPPEND | FLG_IF_DISPDONE))
2484                                 is_disp_copied(ofl, crp);
2485                 }
2486         }
2487 
2488         /*
2489          * GOT sections are created for dynamic executables and shared objects
2490          * if the FLG_OF_BLDGOT is set, or explicit reference has been made to
2491          * a GOT symbol.
2492          */
2493         if (((ofl->ofl_flags & FLG_OF_RELOBJ) == 0) &&
2494             ((ofl->ofl_flags & FLG_OF_BLDGOT) ||
2495             ((((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_GOFTBL),
2496             SYM_NOHASH, NULL, ofl)) != NULL) ||
2497             ((sdp = ld_sym_find(MSG_ORIG(MSG_SYM_GOFTBL_U),
2498             SYM_NOHASH, NULL, ofl)) != NULL)) &&
2499             (sdp->sd_ref != REF_DYN_SEEN)))) {
2500                 if (ld_make_got(ofl) == S_ERROR)
2501                         return (S_ERROR);
2502 
2503                 /* Allocate the GOT if required by target */
2504                 if ((ld_targ.t_mr.mr_allocate_got != NULL) &&
2505                     ((*ld_targ.t_mr.mr_allocate_got)(ofl) == S_ERROR))
2506                         return (S_ERROR);
2507         }
2508 
2509         return (1);
2510 }
2511 
2512 /*
2513  * Simple comparison routine to be used by qsort() for
2514  * the sorting of the output relocation list.
2515  *
2516  * The reloc_compare() routine results in a relocation
2517  * table which is located on:
2518  *
2519  *      file referenced (NEEDED NDX)
2520  *      referenced symbol
2521  *      relocation offset
2522  *
2523  * This provides the most efficient traversal of the relocation
2524  * table at run-time.
2525  */
2526 static int
2527 reloc_compare(Reloc_list *i, Reloc_list *j)
2528 {
2529 
2530         /*
2531          * first - sort on neededndx
2532          */
2533         if (i->rl_key1 > j->rl_key1)
2534                 return (1);
2535         if (i->rl_key1 < j->rl_key1)
2536                 return (-1);
2537 
2538         /*
2539          * Then sort on symbol
2540          */
2541         if ((uintptr_t)i->rl_key2 > (uintptr_t)j->rl_key2)
2542                 return (1);
2543         if ((uintptr_t)i->rl_key2 < (uintptr_t)j->rl_key2)
2544                 return (-1);
2545 
2546         /*
2547          * i->key2 == j->key2
2548          *
2549          * At this point we fall back to key2 (offsets) to
2550          * sort the output relocations.  Ideally this will
2551          * make for the most efficient processing of these
2552          * relocations at run-time.
2553          */
2554         if (i->rl_key3 > j->rl_key3)
2555                 return (1);
2556         if (i->rl_key3 < j->rl_key3)
2557                 return (-1);
2558         return (0);
2559 }
2560 
2561 static uintptr_t
2562 do_sorted_outrelocs(Ofl_desc *ofl)
2563 {
2564         Rel_desc        *orsp;
2565         Rel_cachebuf    *rcbp;
2566         Aliste          idx;
2567         Reloc_list      *sorted_list;
2568         Word            index = 0;
2569         int             debug = 0;
2570         uintptr_t       error = 1;
2571         Boolean         remain_seen = FALSE;
2572 
2573         if ((sorted_list = libld_malloc((size_t)(sizeof (Reloc_list) *
2574             ofl->ofl_reloccnt))) == NULL)
2575                 return (S_ERROR);
2576 
2577         /*
2578          * All but the PLT output relocations are sorted in the output file
2579          * based upon their sym_desc.  By doing this multiple relocations
2580          * against the same symbol are grouped together, thus when the object
2581          * is later relocated by ld.so.1 it will take advantage of the symbol
2582          * cache that ld.so.1 has.  This can significantly reduce the runtime
2583          * relocation cost of a dynamic object.
2584          *
2585          * PLT relocations are not sorted because the order of the PLT
2586          * relocations is used by ld.so.1 to determine what symbol a PLT
2587          * relocation is against.
2588          */
2589         REL_CACHE_TRAVERSE(&ofl->ofl_outrels, idx, rcbp, orsp) {
2590                 if (debug == 0) {
2591                         DBG_CALL(Dbg_reloc_dooutrel(ofl->ofl_lml,
2592                             ld_targ.t_m.m_rel_sht_type));
2593                         debug = 1;
2594                 }
2595 
2596                 /*
2597                  * If it's a PLT relocation we output it now in the
2598                  * order that it was originally processed.
2599                  */
2600                 if (orsp->rel_flags & FLG_REL_PLT) {
2601                         if ((*ld_targ.t_mr.mr_perform_outreloc)
2602                             (orsp, ofl, &remain_seen) == S_ERROR)
2603                                 error = S_ERROR;
2604                         continue;
2605                 }
2606 
2607                 if ((orsp->rel_rtype == ld_targ.t_m.m_r_relative) ||
2608                     (orsp->rel_rtype == ld_targ.t_m.m_r_register)) {
2609                         sorted_list[index].rl_key1 = 0;
2610                         sorted_list[index].rl_key2 =
2611                             /* LINTED */
2612                             (Sym_desc *)(uintptr_t)orsp->rel_rtype;
2613                 } else {
2614                         sorted_list[index].rl_key1 =
2615                             orsp->rel_sym->sd_file->ifl_neededndx;
2616                         sorted_list[index].rl_key2 = orsp->rel_sym;
2617                 }
2618 
2619                 if (orsp->rel_flags & FLG_REL_GOT) {
2620                         sorted_list[index].rl_key3 =
2621                             (*ld_targ.t_mr.mr_calc_got_offset)(orsp, ofl);
2622                 } else {
2623                         if (orsp->rel_rtype == ld_targ.t_m.m_r_register) {
2624                                         sorted_list[index].rl_key3 = 0;
2625                         } else {
2626                                 sorted_list[index].rl_key3 = orsp->rel_roffset +
2627                                     (Xword)_elf_getxoff(orsp->
2628                                     rel_isdesc->is_indata) +
2629                                     orsp->rel_isdesc->is_osdesc->
2630                                     os_shdr->sh_addr;
2631                         }
2632                 }
2633 
2634                 sorted_list[index++].rl_rsp = orsp;
2635         }
2636 
2637         qsort(sorted_list, (size_t)ofl->ofl_reloccnt, sizeof (Reloc_list),
2638             (int (*)(const void *, const void *))reloc_compare);
2639 
2640         /*
2641          * All output relocations have now been sorted, go through
2642          * and process each relocation.
2643          */
2644         for (index = 0; index < ofl->ofl_reloccnt; index++) {
2645                 if ((*ld_targ.t_mr.mr_perform_outreloc)
2646                     (sorted_list[index].rl_rsp, ofl, &remain_seen) == S_ERROR)
2647                         error = S_ERROR;
2648         }
2649 
2650         /* Guidance: Use -z text when building shared objects */
2651         if (remain_seen && OFL_GUIDANCE(ofl, FLG_OFG_NO_TEXT))
2652                 ld_eprintf(ofl, ERR_GUIDANCE, MSG_INTL(MSG_GUIDE_TEXT));
2653 
2654         return (error);
2655 }
2656 
2657 /*
2658  * Process relocations.  Finds every input relocation section for each output
2659  * section and invokes reloc_section() to relocate that section.
2660  */
2661 uintptr_t
2662 ld_reloc_process(Ofl_desc *ofl)
2663 {
2664         Sg_desc         *sgp;
2665         Os_desc         *osp;
2666         Word            ndx = 0;
2667         ofl_flag_t      flags = ofl->ofl_flags;
2668         Shdr            *shdr;
2669 
2670         DBG_CALL(Dbg_basic_relocate(ofl->ofl_lml));
2671 
2672         /*
2673          * Determine the index of the symbol table that will be referenced by
2674          * the relocation entries.
2675          */
2676         if (OFL_ALLOW_DYNSYM(ofl))
2677                 /* LINTED */
2678                 ndx = (Word)elf_ndxscn(ofl->ofl_osdynsym->os_scn);
2679         else if (!(flags & FLG_OF_STRIP) || (flags & FLG_OF_RELOBJ))
2680                 /* LINTED */
2681                 ndx = (Word)elf_ndxscn(ofl->ofl_ossymtab->os_scn);
2682 
2683         /*
2684          * Re-initialize counters. These are used to provide relocation
2685          * offsets within the output buffers.
2686          */
2687         ofl->ofl_relocpltsz = 0;
2688         ofl->ofl_relocgotsz = 0;
2689         ofl->ofl_relocbsssz = 0;
2690 
2691         /*
2692          * Now that the output file is created and symbol update has occurred,
2693          * process the relocations collected in process_reloc().
2694          */
2695         if (do_sorted_outrelocs(ofl) == S_ERROR)
2696                 return (S_ERROR);
2697 
2698         if ((*ld_targ.t_mr.mr_do_activerelocs)(ofl) == S_ERROR)
2699                 return (S_ERROR);
2700 
2701         if ((flags & FLG_OF_COMREL) == 0) {
2702                 Aliste  idx1;
2703 
2704                 /*
2705                  * Process the relocation sections.  For each relocation
2706                  * section generated for the output image update its shdr
2707                  * information to reflect the symbol table it needs (sh_link)
2708                  * and the section to which the relocation must be applied
2709                  * (sh_info).
2710                  */
2711                 for (APLIST_TRAVERSE(ofl->ofl_segs, idx1, sgp)) {
2712                         Os_desc *osp;
2713                         Aliste  idx2;
2714 
2715                         for (APLIST_TRAVERSE(sgp->sg_osdescs, idx2, osp)) {
2716                                 if (osp->os_relosdesc == 0)
2717                                         continue;
2718 
2719                                 shdr = osp->os_relosdesc->os_shdr;
2720                                 shdr->sh_link = ndx;
2721                                 /* LINTED */
2722                                 shdr->sh_info = (Word)elf_ndxscn(osp->os_scn);
2723                         }
2724                 }
2725 
2726                 /*
2727                  * Since the .rel[a] section is not tied to any specific
2728                  * section, we'd not have found it above.
2729                  */
2730                 if ((osp = ofl->ofl_osrel) != NULL) {
2731                         shdr = osp->os_shdr;
2732                         shdr->sh_link = ndx;
2733                         shdr->sh_info = 0;
2734                 }
2735         } else {
2736                 /*
2737                  * We only have two relocation sections here, (PLT's,
2738                  * coalesced) so just hit them directly instead of stepping
2739                  * over the output sections.
2740                  */
2741                 if ((osp = ofl->ofl_osrelhead) != NULL) {
2742                         shdr = osp->os_shdr;
2743                         shdr->sh_link = ndx;
2744                         shdr->sh_info = 0;
2745                 }
2746                 if (((osp = ofl->ofl_osplt) != NULL) && osp->os_relosdesc) {
2747                         shdr = osp->os_relosdesc->os_shdr;
2748                         shdr->sh_link = ndx;
2749                         /* LINTED */
2750                         shdr->sh_info = (Word)elf_ndxscn(osp->os_scn);
2751                 }
2752         }
2753 
2754         /*
2755          * If the -z text option was given, and we have output relocations
2756          * against a non-writable, allocatable section, issue a diagnostic and
2757          * return (the actual entries that caused this error would have been
2758          * output during the relocating section phase).
2759          */
2760         if ((flags & (FLG_OF_PURETXT | FLG_OF_TEXTREL)) ==
2761             (FLG_OF_PURETXT | FLG_OF_TEXTREL)) {
2762                 ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_REMAIN_3));
2763                 return (S_ERROR);
2764         }
2765 
2766         /*
2767          * Finally, initialize the first got entry with the address of the
2768          * .dynamic section (_DYNAMIC).
2769          */
2770         if (flags & FLG_OF_DYNAMIC) {
2771                 if ((*ld_targ.t_mr.mr_fillin_gotplt)(ofl) == S_ERROR)
2772                         return (S_ERROR);
2773         }
2774 
2775         /*
2776          * Now that any GOT information has been written, display the debugging
2777          * information if required.
2778          */
2779         if ((osp = ofl->ofl_osgot) != NULL)
2780                 DBG_CALL(Dbg_got_display(ofl, osp->os_shdr->sh_addr, 1,
2781                     ld_targ.t_m.m_got_xnumber, ld_targ.t_m.m_got_entsize));
2782 
2783         return (1);
2784 }
2785 
2786 /*
2787  * If the -z text option was given, and we have output relocations against a
2788  * non-writable, allocatable section, issue a diagnostic. Print offending
2789  * symbols in tabular form similar to the way undefined symbols are presented.
2790  * Called from reloc_count().  The actual fatal error condition is triggered on
2791  * in reloc_process() above.
2792  *
2793  * Note.  For historic reasons -ztext is not a default option (however all OS
2794  * shared object builds use this option).  It can be argued that this option
2795  * should also be default when generating an a.out (see 1163979).  However, if
2796  * an a.out contains text relocations it is either because the user is creating
2797  * something pretty weird (they've used the -b or -znodefs options), or because
2798  * the library against which they're building wasn't constructed correctly (ie.
2799  * a function has a NOTYPE type, in which case the a.out won't generate an
2800  * associated plt).  In the latter case the builder of the a.out can't do
2801  * anything to fix the error - thus we've chosen not to give the user an error,
2802  * or warning, for this case.
2803  */
2804 void
2805 ld_reloc_remain_entry(Rel_desc *orsp, Os_desc *osp, Ofl_desc *ofl,
2806     Boolean *remain_seen)
2807 {
2808 
2809         /*
2810          * -ztextoff
2811          */
2812         if (ofl->ofl_flags1 & FLG_OF1_TEXTOFF)
2813                 return;
2814 
2815         /*
2816          * Only give relocation errors against loadable read-only segments.
2817          */
2818         if ((orsp->rel_rtype == ld_targ.t_m.m_r_register) || (!osp) ||
2819             (osp->os_sgdesc->sg_phdr.p_type != PT_LOAD) ||
2820             (osp->os_sgdesc->sg_phdr.p_flags & PF_W))
2821                 return;
2822 
2823         /*
2824          * If we are in -ztextwarn mode, it's a silent error if a relocation is
2825          * due to a 'WEAK REFERENCE'.  This is because if the symbol is not
2826          * provided at run-time we will not perform a text-relocation.
2827          */
2828         if (((ofl->ofl_flags & FLG_OF_PURETXT) == 0) &&
2829             (ELF_ST_BIND(orsp->rel_sym->sd_sym->st_info) == STB_WEAK) &&
2830             (orsp->rel_sym->sd_sym->st_shndx == SHN_UNDEF))
2831                 return;
2832 
2833         if (*remain_seen == FALSE) {
2834                 /*
2835                  * If building with '-ztext' then emit a fatal error.  If
2836                  * building a executable then only emit a 'warning'.
2837                  */
2838                 const char *str1 = (ofl->ofl_flags & FLG_OF_PURETXT) ?
2839                     MSG_INTL(MSG_REL_RMN_ITM_11) : MSG_INTL(MSG_REL_RMN_ITM_13);
2840 
2841                 ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_REL_REMAIN_FMT_1), str1,
2842                     MSG_INTL(MSG_REL_RMN_ITM_31), MSG_INTL(MSG_REL_RMN_ITM_12),
2843                     MSG_INTL(MSG_REL_RMN_ITM_2), MSG_INTL(MSG_REL_RMN_ITM_32));
2844 
2845                 *remain_seen = TRUE;
2846         }
2847 
2848         ld_eprintf(ofl, ERR_NONE, MSG_INTL(MSG_REL_REMAIN_2),
2849             ld_reloc_sym_name(orsp), EC_OFF(orsp->rel_roffset),
2850             orsp->rel_isdesc->is_file->ifl_name);
2851 }
2852 
2853 /*
2854  * Generic encapsulation for generating a TLS got index.
2855  */
2856 uintptr_t
2857 ld_assign_got_TLS(Boolean local, Rel_desc *rsp, Ofl_desc *ofl, Sym_desc *sdp,
2858     Gotndx *gnp, Gotref gref, Word rflag, Word ortype, Word rtype1, Word rtype2)
2859 {
2860         Word    rflags;
2861 
2862         if ((*ld_targ.t_mr.mr_assign_got_ndx)(&(sdp->sd_GOTndxs), gnp,
2863             gref, ofl, rsp, sdp) == S_ERROR)
2864                 return (S_ERROR);
2865 
2866         rflags = FLG_REL_GOT | rflag;
2867         if (local)
2868                 rflags |= FLG_REL_SCNNDX;
2869         rsp->rel_rtype = rtype1;
2870 
2871         if ((*ld_targ.t_mr.mr_add_outrel)(rflags, rsp, ofl) == S_ERROR)
2872                 return (S_ERROR);
2873 
2874         if (local && (gref == GOT_REF_TLSIE)) {
2875                 /*
2876                  * If this is a local LE TLS symbol, then the symbol won't be
2877                  * available at runtime.  The value of the local symbol will
2878                  * be placed in the associated got entry, and the got
2879                  * relocation is reassigned to a section symbol.
2880                  */
2881                 if (ld_add_actrel(rflags, rsp, ofl) == S_ERROR)
2882                         return (S_ERROR);
2883         }
2884 
2885         if (rtype2) {
2886                 rflags = FLG_REL_GOT | rflag;
2887                 rsp->rel_rtype = rtype2;
2888 
2889                 if (local) {
2890                         if (ld_add_actrel(rflags, rsp, ofl) == S_ERROR)
2891                                 return (S_ERROR);
2892                 } else {
2893                         if ((*ld_targ.t_mr.mr_add_outrel)(rflags, rsp, ofl) ==
2894                             S_ERROR)
2895                                 return (S_ERROR);
2896                 }
2897         }
2898 
2899         rsp->rel_rtype = ortype;
2900 
2901         return (1);
2902 }
2903 
2904 /*
2905  * Move Section related function
2906  */
2907 static void
2908 newroffset_for_move(Sym_desc *sdp, Move *mvp, Xword offset1, Xword *offset2)
2909 {
2910         Mv_desc         *mdp;
2911         Aliste          idx;
2912 
2913         /*
2914          * Search for matching move entry.
2915          */
2916         for (ALIST_TRAVERSE(sdp->sd_move, idx, mdp)) {
2917                 if (mdp->md_move == mvp) {
2918                         /*
2919                          * Update r_offset
2920                          */
2921                         *offset2 = (Xword)((mdp->md_oidx - 1) * sizeof (Move) +
2922                             offset1 % sizeof (Move));
2923                         return;
2924                 }
2925         }
2926 }
2927 
2928 void
2929 ld_adj_movereloc(Ofl_desc *ofl, Rel_desc *arsp)
2930 {
2931         Move            *move = arsp->rel_aux->ra_move->mr_move;
2932         Sym_desc        *psdp = arsp->rel_aux->ra_move->mr_sym;
2933         Xword           newoffset;
2934 
2935         if (arsp->rel_flags & FLG_REL_MOVETAB) {
2936                 /*
2937                  * We are relocating the move table itself.
2938                  */
2939                 newroffset_for_move(psdp, move, arsp->rel_roffset,
2940                     &newoffset);
2941                 DBG_CALL(Dbg_move_adjmovereloc(ofl->ofl_lml, arsp->rel_roffset,
2942                     newoffset, psdp->sd_name));
2943                 arsp->rel_roffset = newoffset;
2944         } else {
2945                 /*
2946                  * We are expanding the partial symbol.  So we are generating
2947                  * the relocation entry relocating the expanded partial symbol.
2948                  */
2949                 arsp->rel_roffset += psdp->sd_sym->st_value -
2950                     ofl->ofl_isparexpn->is_osdesc->os_shdr->sh_addr;
2951                 DBG_CALL(Dbg_move_adjexpandreloc(ofl->ofl_lml,
2952                     arsp->rel_roffset, psdp->sd_name));
2953         }
2954 }
2955 
2956 /*
2957  * Partially Initialized Symbol Handling routines
2958  * For RELA architecture, the second argument is reld->rel_raddend.  For REL
2959  * architecure, the second argument is the value stored at the relocation
2960  * target address.
2961  */
2962 Sym_desc *
2963 ld_am_I_partial(Rel_desc *reld, Xword val)
2964 {
2965         Ifl_desc        *ifile = reld->rel_sym->sd_isc->is_file;
2966         int             nlocs = ifile->ifl_locscnt, i;
2967 
2968         for (i = 1; i < nlocs; i++) {
2969                 Sym             *osym;
2970                 Sym_desc        *symd = ifile->ifl_oldndx[i];
2971 
2972                 if ((osym = symd->sd_osym) == 0)
2973                         continue;
2974                 if ((symd->sd_flags & FLG_SY_PAREXPN) == 0)
2975                         continue;
2976                 if ((osym->st_value <= val) &&
2977                     (osym->st_value + osym->st_size > val))
2978                         return (symd);
2979         }
2980         return (NULL);
2981 }
2982 
2983 /*
2984  * Return True (1) if the code processing the given relocation
2985  * needs to perform byte swapping when accessing the section data.
2986  */
2987 int
2988 ld_swap_reloc_data(Ofl_desc *ofl, Rel_desc *rsp)
2989 {
2990         /*
2991          * In a cross-link situation where the linker host and target
2992          * have opposite byte orders, it can be necessary to swap bytes
2993          * when doing relocation processing. This is indicated by the
2994          * presence of the FLG_OF1_ENCDIFF flag bit. However, swapping
2995          * is only needed for the section types that libelf doesn't
2996          * automatically xlate.
2997          */
2998         if ((ofl->ofl_flags1 & FLG_OF1_ENCDIFF) != 0) {
2999                 switch (RELAUX_GET_OSDESC(rsp)->os_shdr->sh_type) {
3000                 case SHT_PROGBITS:
3001                         return (1);
3002 
3003                 case SHT_SPARC_GOTDATA:
3004                         if (ld_targ.t_m.m_mach ==
3005                             LD_TARG_BYCLASS(EM_SPARC, EM_SPARCV9))
3006                                 return (1);
3007                         break;
3008 
3009                 case SHT_AMD64_UNWIND:
3010                         if (ld_targ.t_m.m_mach == EM_AMD64)
3011                                 return (1);
3012                         break;
3013                 }
3014         }
3015 
3016         /*
3017          * If FLG_OF1_ENCDIFF isn't set, or the section isn't
3018          * progbits (or similar), then no swapping is needed.
3019          */
3020         return (0);
3021 }
3022 
3023 
3024 
3025 /*
3026  * Obtain the current value at the given relocation target.
3027  *
3028  * entry:
3029  *      ofl - Output file descriptor
3030  *      rsp - Relocation record
3031  *      data - Pointer to relocation target
3032  *      value - Address of variable to recieve value
3033  *
3034  * exit:
3035  *      The value of the data at the relocation target has
3036  *      been stored in value.
3037  */
3038 int
3039 ld_reloc_targval_get(Ofl_desc *ofl, Rel_desc *rsp, uchar_t *data, Xword *value)
3040 {
3041         const Rel_entry *rep;
3042 
3043         rep = &ld_targ.t_mr.mr_reloc_table[rsp->rel_rtype];
3044 
3045         switch (rep->re_fsize) {
3046         case 1:
3047                 /* LINTED */
3048                 *value = (Xword) *((uchar_t *)data);
3049                 break;
3050         case 2:
3051                 {
3052                         Half    v;
3053                         uchar_t *v_bytes = (uchar_t *)&v;
3054 
3055                         if (OFL_SWAP_RELOC_DATA(ofl, rsp)) {
3056                                 UL_ASSIGN_BSWAP_HALF(v_bytes, data);
3057                         } else {
3058                                 UL_ASSIGN_HALF(v_bytes, data);
3059                         }
3060                         *value = (Xword) v;
3061                 }
3062                 break;
3063         case 4:
3064                 {
3065                         Word    v;
3066                         uchar_t *v_bytes = (uchar_t *)&v;
3067 
3068                         if (OFL_SWAP_RELOC_DATA(ofl, rsp)) {
3069                                 UL_ASSIGN_BSWAP_WORD(v_bytes, data);
3070                         } else {
3071                                 UL_ASSIGN_WORD(v_bytes, data);
3072                         }
3073                         *value = (Xword) v;
3074                 }
3075                 break;
3076         default:
3077                 {
3078                         Conv_inv_buf_t inv_buf;
3079                         ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_UNSUPSZ),
3080                             conv_reloc_type(ld_targ.t_m.m_mach, rsp->rel_rtype,
3081                             0, &inv_buf), rsp->rel_isdesc->is_file->ifl_name,
3082                             ld_reloc_sym_name(rsp), (int)rep->re_fsize);
3083                 }
3084                 return (0);
3085         }
3086         return (1);
3087 }
3088 
3089 
3090 /*
3091  * Set the value at the given relocation target.
3092  *
3093  * entry:
3094  *      ofl - Output file descriptor
3095  *      rsp - Relocation record
3096  *      data - Pointer to relocation target
3097  *      value - Address of variable to recieve value
3098  *
3099  * exit:
3100  *      The value of the data at the relocation target has
3101  *      been stored in value.
3102  */
3103 int
3104 ld_reloc_targval_set(Ofl_desc *ofl, Rel_desc *rsp, uchar_t *data, Xword value)
3105 {
3106         const Rel_entry *rep;
3107 
3108         rep = &ld_targ.t_mr.mr_reloc_table[rsp->rel_rtype];
3109 
3110         switch (rep->re_fsize) {
3111         case 1:
3112                 /* LINTED */
3113                 *((uchar_t *)data) = (uchar_t)value;
3114                 break;
3115         case 2:
3116                 {
3117                         Half    v = (Half)value;
3118                         uchar_t *v_bytes = (uchar_t *)&v;
3119 
3120                         if (OFL_SWAP_RELOC_DATA(ofl, rsp)) {
3121                                 UL_ASSIGN_BSWAP_HALF(data, v_bytes);
3122                         } else {
3123                                 UL_ASSIGN_HALF(data, v_bytes);
3124                         }
3125                 }
3126                 break;
3127         case 4:
3128                 {
3129                         Word    v = (Word)value;
3130                         uchar_t *v_bytes = (uchar_t *)&v;
3131 
3132                         if (OFL_SWAP_RELOC_DATA(ofl, rsp)) {
3133                                 UL_ASSIGN_BSWAP_WORD(data, v_bytes);
3134                         } else {
3135                                 UL_ASSIGN_WORD(data, v_bytes);
3136                         }
3137                 }
3138                 break;
3139         default:
3140                 {
3141                         Conv_inv_buf_t inv_buf;
3142                         ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_UNSUPSZ),
3143                             conv_reloc_type(ld_targ.t_m.m_mach, rsp->rel_rtype,
3144                             0, &inv_buf), rsp->rel_isdesc->is_file->ifl_name,
3145                             ld_reloc_sym_name(rsp), (int)rep->re_fsize);
3146                 }
3147                 return (0);
3148         }
3149         return (1);
3150 }
3151 
3152 
3153 /*
3154  * Because of the combinations of 32-bit lib providing 64-bit support, and
3155  * visa-versa, the use of krtld's dorelocs can result in differing message
3156  * requirements that make msg.c/msg.h creation and chkmsg "interesting".
3157  * Thus the actual message files contain a couple of entries to satisfy
3158  * each architectures build.  Here we add dummy calls to quieten chkmsg.
3159  *
3160  * chkmsg: MSG_INTL(MSG_REL_NOFIT)
3161  * chkmsg: MSG_INTL(MSG_REL_NONALIGN)
3162  */