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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 #include        <string.h>
  27 #include        <stdio.h>
  28 #include        <sys/types.h>
  29 #include        <sgs.h>
  30 #include        <debug.h>
  31 #include        <_libld.h>
  32 #include        <dwarf.h>
  33 #include        <stdlib.h>
  34 
  35 /*
  36  * A EH_FRAME_HDR consists of the following:
  37  *
  38  *      Encoding        Field
  39  *      --------------------------------
  40  *      unsigned byte   version
  41  *      unsigned byte   eh_frame_ptr_enc
  42  *      unsigned byte   fde_count_enc
  43  *      unsigned byte   table_enc
  44  *      encoded         eh_frame_ptr
  45  *      encoded         fde_count
  46  *      [ binary search table ]
  47  *
  48  * The binary search table entries each consists of:
  49  *
  50  *      encoded         initial_func_loc
  51  *      encoded         FDE_address
  52  *
  53  * The entries in the binary search table are sorted
  54  * in a increasing order by the initial location.
  55  *
  56  *
  57  * version
  58  *
  59  *   Version of the .eh_frame_hdr format. This value shall be 1.
  60  *
  61  * eh_frame_ptr_enc
  62  *
  63  *    The encoding format of the eh_frame_ptr field.  For shared
  64  *    libraries the encoding must be
  65  *    DW_EH_PE_sdata4|DW_EH_PE_pcrel or
  66  *    DW_EH_PE_sdata4|DW_EH_PE_datarel.
  67  *
  68  *
  69  * fde_count_enc
  70  *
  71  *    The encoding format of the fde_count field. A value of
  72  *    DW_EH_PE_omit indicates the binary search table is not
  73  *    present.
  74  *
  75  * table_enc
  76  *
  77  *    The encoding format of the entries in the binary search
  78  *    table. A value of DW_EH_PE_omit indicates the binary search
  79  *    table is not present. For shared libraries the encoding
  80  *    must be DW_EH_PE_sdata4|DW_EH_PE_pcrel or
  81  *    DW_EH_PE_sdata4|DW_EH_PE_datarel.
  82  *
  83  *
  84  * eh_frame_ptr
  85  *
  86  *    The encoded value of the pointer to the start of the
  87  *    .eh_frame section.
  88  *
  89  * fde_count
  90  *
  91  *    The encoded value of the count of entries in the binary
  92  *    search table.
  93  *
  94  * binary search table
  95  *
  96  *    A binary search table containing fde_count entries. Each
  97  *    entry of the table consist of two encoded values, the
  98  *    initial location of the function to which an FDE applies,
  99  *    and the address of the FDE. The entries are sorted in an
 100  *    increasing order by the initial location value.
 101  *
 102  */
 103 
 104 
 105 /*
 106  * EH_FRAME sections
 107  * =================
 108  *
 109  * The call frame information needed for unwinding the stack is output in
 110  * an ELF section(s) of type SHT_AMD64_UNWIND (amd64) or SHT_PROGBITS (other).
 111  * In the simplest case there will be one such section per object file and it
 112  * will be named ".eh_frame".  An .eh_frame section consists of one or more
 113  * subsections. Each subsection contains a CIE (Common Information Entry)
 114  * followed by varying number of FDEs (Frame Descriptor Entry). A FDE
 115  * corresponds to an explicit or compiler generated function in a
 116  * compilation unit, all FDEs can access the CIE that begins their
 117  * subsection for data.
 118  *
 119  * If an object file contains C++ template instantiations, there shall be
 120  * a separate CIE immediately preceding each FDE corresponding to an
 121  * instantiation.
 122  *
 123  * Using the preferred encoding specified below, the .eh_frame section can
 124  * be entirely resolved at link time and thus can become part of the
 125  * text segment.
 126  *
 127  * .eh_frame Section Layout
 128  * ------------------------
 129  *
 130  * EH_PE encoding below refers to the pointer encoding as specified in the
 131  * enhanced LSB Chapter 7 for Eh_Frame_Hdr.
 132  *
 133  * Common Information Entry (CIE)
 134  * ------------------------------
 135  * CIE has the following format:
 136  *
 137  *                           Length
 138  *                              in
 139  *     Field                   Byte      Description
 140  *     -----                  ------     -----------
 141  *  1. Length                   4        Length of CIE (not including
 142  *                                       this 4-byte field).
 143  *
 144  *  2. CIE id                   4        Value Zero (0) for .eh_frame
 145  *                                       (used to distinguish CIEs and
 146  *                                       FDEs when scanning the section)
 147  *
 148  *  3. Version                  1        Value One (1)
 149  *
 150  *  4. CIE Augmentation       string     Null-terminated string with legal
 151  *                                       values being "" or 'z' optionally
 152  *                                       followed by single occurrences of
 153  *                                       'P', 'L', or 'R' in any order.
 154  *     String                            The presence of character(s) in the
 155  *                                       string dictates the content of
 156  *                                       field 8, the Augmentation Section.
 157  *                                       Each character has one or two
 158  *                                       associated operands in the AS.
 159  *                                       Operand order depends on
 160  *                                       position in the string ('z' must
 161  *                                       be first).
 162  *
 163  *  5. Code Align Factor      uleb128    To be multiplied with the
 164  *                                       "Advance Location" instructions in
 165  *                                       the Call Frame Instructions
 166  *
 167  *  6. Data Align Factor      sleb128    To be multiplied with all offset
 168  *                                       in the Call Frame Instructions
 169  *
 170  *  7. Ret Address Reg          1        A "virtual" register representation
 171  *                                       of the return address. In Dwarf V2,
 172  *                                       this is a byte, otherwise it is
 173  *                                       uleb128. It is a byte in gcc 3.3.x
 174  *
 175  *  8. Optional CIE           varying    Present if Augmentation String in
 176  *     Augmentation Section              field 4 is not 0.
 177  *
 178  *     z:
 179  *      size               uleb128       Length of the remainder of the
 180  *                                       Augmentation Section
 181  *
 182  *     P:
 183  *      personality_enc    1             Encoding specifier - preferred
 184  *                                       value is a pc-relative, signed
 185  *                                       4-byte
 186  *
 187  *
 188  *        personality routine (encoded)  Encoded pointer to personality
 189  *                                       routine (actually to the PLT
 190  *                                       entry for the personality
 191  *                                       routine)
 192  *     R:
 193  *      code_enc           1          Non-default encoding for the
 194  *                                    code-pointers (FDE members
 195  *                                    "initial_location" and "address_range"
 196  *                                    and the operand for DW_CFA_set_loc)
 197  *                                    - preferred value is pc-relative,
 198  *                                    signed 4-byte.
 199  *     L:
 200  *      lsda_enc           1          FDE augmentation bodies may contain
 201  *                                    LSDA pointers. If so they are
 202  *                                    encoded as specified here -
 203  *                                    preferred value is pc-relative,
 204  *                                    signed 4-byte possibly indirect
 205  *                                    thru a GOT entry.
 206  *
 207  *
 208  *  9. Optional Call Frame varying
 209  *     Instructions
 210  *
 211  * The size of the optional call frame instruction area must be computed
 212  * based on the overall size and the offset reached while scanning the
 213  * preceding fields of the CIE.
 214  *
 215  *
 216  * Frame Descriptor Entry (FDE)
 217  * ----------------------------
 218  * FDE has the following format:
 219  *
 220  *                            Length
 221  *                              in
 222  *     Field                   Byte      Description
 223  *     -----                  ------     -----------
 224  *  1. Length                   4        Length of remainder of this FDE
 225  *
 226  *  2. CIE Pointer              4        Distance from this field to the
 227  *                                       nearest preceding CIE
 228  *                                       (uthe value is subtracted from the
 229  *                                       current address). This value
 230  *                                       can never be zero and thus can
 231  *                                       be used to distinguish CIE's and
 232  *                                       FDE's when scanning the
 233  *                                       .eh_frame section
 234  *
 235  *  3. Initial Location       varying    Reference to the function code
 236  *                                       corresponding to this FDE.
 237  *                                       If 'R' is missing from the CIE
 238  *                                       Augmentation String, the field is an
 239  *                                       8-byte absolute pointer. Otherwise,
 240  *                                       the corresponding EH_PE encoding in the
 241  *                                       CIE Augmentation Section is used to
 242  *                                       interpret the reference.
 243  *
 244  *  4. Address Range          varying    Size of the function code corresponding
 245  *                                       to this FDE.
 246  *                                       If 'R' is missing from the CIE
 247  *                                       Augmentation String, the field is an
 248  *                                       8-byte unsigned number. Otherwise,
 249  *                                       the size is determined by the
 250  *                                       corresponding EH_PE encoding in the
 251  *                                       CIE Augmentation Section (the
 252  *                                       value is always absolute).
 253  *
 254  *  5. Optional FDE           varying    present if CIE augmentation
 255  *     Augmentation Section              string is non-empty.
 256  *
 257  *
 258  *     'z':
 259  *      length             uleb128       length of the remainder of the
 260  *                                       FDE augmentation section
 261  *
 262  *
 263  *     'L' (and length > 0):
 264  *         LSDA               varying    LSDA pointer, encoded in the
 265  *                                       format specified by the
 266  *                                       corresponding operand in the CIE's
 267  *                                       augmentation body.
 268  *
 269  *  6. Optional Call          varying
 270  *     Frame Instructions
 271  *
 272  * The size of the optional call frame instruction area must be computed
 273  * based on the overall size and the offset reached while scanning the
 274  * preceding fields of the FDE.
 275  *
 276  * The overall size of a .eh_frame section is given in the ELF section
 277  * header.  The only way to determine the number of entries is to scan
 278  * the section till the end and count.
 279  *
 280  */
 281 
 282 
 283 
 284 
 285 static uint_t
 286 extract_uint(const uchar_t *data, uint64_t *ndx, int do_swap)
 287 {
 288         uint_t  r;
 289         uchar_t *p = (uchar_t *)&r;
 290 
 291         data += *ndx;
 292         if (do_swap)
 293                 UL_ASSIGN_BSWAP_WORD(p, data);
 294         else
 295                 UL_ASSIGN_WORD(p, data);
 296 
 297         (*ndx) += 4;
 298         return (r);
 299 }
 300 
 301 /*
 302  * Create an unwind header (.eh_frame_hdr) output section.
 303  * The section is created and space reserved, but the data
 304  * is not copied into place. That is done by a later call
 305  * to ld_unwind_populate(), after active relocations have been
 306  * processed.
 307  *
 308  * When GNU linkonce processing is in effect, we can end up in a situation
 309  * where the FDEs related to discarded sections remain in the eh_frame
 310  * section. Ideally, we would remove these dead entries from eh_frame.
 311  * However, that optimization has not yet been implemented. In the current
 312  * implementation, the number of dead FDEs cannot be determined until
 313  * active relocations are processed, and that processing follows the
 314  * call to this function. This means that we are unable to detect dead FDEs
 315  * here, and the section created by this routine is sized for maximum case
 316  * where all FDEs are valid.
 317  */
 318 uintptr_t
 319 ld_unwind_make_hdr(Ofl_desc *ofl)
 320 {
 321         int             bswap = (ofl->ofl_flags1 & FLG_OF1_ENCDIFF) != 0;
 322         Shdr            *shdr;
 323         Elf_Data        *elfdata;
 324         Is_desc         *isp;
 325         size_t          size;
 326         Xword           fde_cnt;
 327         Aliste          idx1;
 328         Os_desc         *osp;
 329 
 330         /*
 331          * we only build a unwind header if we have
 332          * some unwind information in the file.
 333          */
 334         if (ofl->ofl_unwind == NULL)
 335                 return (1);
 336 
 337         /*
 338          * Allocate and initialize the Elf_Data structure.
 339          */
 340         if ((elfdata = libld_calloc(sizeof (Elf_Data), 1)) == NULL)
 341                 return (S_ERROR);
 342         elfdata->d_type = ELF_T_BYTE;
 343         elfdata->d_align = ld_targ.t_m.m_word_align;
 344         elfdata->d_version = ofl->ofl_dehdr->e_version;
 345 
 346         /*
 347          * Allocate and initialize the Shdr structure.
 348          */
 349         if ((shdr = libld_calloc(sizeof (Shdr), 1)) == NULL)
 350                 return (S_ERROR);
 351         shdr->sh_type = ld_targ.t_m.m_sht_unwind;
 352         shdr->sh_flags = SHF_ALLOC;
 353         shdr->sh_addralign = ld_targ.t_m.m_word_align;
 354         shdr->sh_entsize = 0;
 355 
 356         /*
 357          * Allocate and initialize the Is_desc structure.
 358          */
 359         if ((isp = libld_calloc(1, sizeof (Is_desc))) == NULL)
 360                 return (S_ERROR);
 361         isp->is_name = MSG_ORIG(MSG_SCN_UNWINDHDR);
 362         isp->is_shdr = shdr;
 363         isp->is_indata = elfdata;
 364 
 365         if ((ofl->ofl_unwindhdr = ld_place_section(ofl, isp, NULL,
 366             ld_targ.t_id.id_unwindhdr, NULL)) == (Os_desc *)S_ERROR)
 367                 return (S_ERROR);
 368 
 369         /*
 370          * Scan through all of the input Frame information, counting each FDE
 371          * that requires an index.  Each fde_entry gets a corresponding entry
 372          * in the binary search table.
 373          */
 374         fde_cnt = 0;
 375         for (APLIST_TRAVERSE(ofl->ofl_unwind, idx1, osp)) {
 376                 Aliste  idx2;
 377                 int     os_isdescs_idx;
 378 
 379                 OS_ISDESCS_TRAVERSE(os_isdescs_idx, osp, idx2, isp) {
 380                         uchar_t         *data;
 381                         uint64_t        off = 0;
 382 
 383                         data = isp->is_indata->d_buf;
 384                         size = isp->is_indata->d_size;
 385 
 386                         while (off < size) {
 387                                 uint_t          length, id;
 388                                 uint64_t        ndx = 0;
 389 
 390                                 /*
 391                                  * Extract length in lsb format.  A zero length
 392                                  * indicates that this CIE is a terminator and
 393                                  * that processing for unwind information is
 394                                  * complete.
 395                                  */
 396                                 length = extract_uint(data + off, &ndx, bswap);
 397                                 if (length == 0)
 398                                         break;
 399 
 400                                 /*
 401                                  * Extract CIE id in lsb format.
 402                                  */
 403                                 id = extract_uint(data + off, &ndx, bswap);
 404 
 405                                 /*
 406                                  * A CIE record has a id of '0', otherwise
 407                                  * this is a FDE entry and the 'id' is the
 408                                  * CIE pointer.
 409                                  */
 410                                 if (id == 0) {
 411                                         uint_t  cieversion;
 412                                         /*
 413                                          * The only CIE version supported
 414                                          * is '1' - quick sanity check
 415                                          * here.
 416                                          */
 417                                         cieversion = data[off + ndx];
 418                                         ndx += 1;
 419                                         /* BEGIN CSTYLED */
 420                                         if (cieversion != 1) {
 421                                             ld_eprintf(ofl, ERR_FATAL,
 422                                                 MSG_INTL(MSG_UNW_BADCIEVERS),
 423                                                 isp->is_file->ifl_name,
 424                                                 isp->is_name, off);
 425                                             return (S_ERROR);
 426                                         }
 427                                         /* END CSTYLED */
 428                                 } else {
 429                                         fde_cnt++;
 430                                 }
 431                                 off += length + 4;
 432                         }
 433                 }
 434         }
 435 
 436         /*
 437          * section size:
 438          *      byte        version             +1
 439          *      byte        eh_frame_ptr_enc    +1
 440          *      byte        fde_count_enc       +1
 441          *      byte        table_enc           +1
 442          *      4 bytes     eh_frame_ptr        +4
 443          *      4 bytes     fde_count           +4
 444          *      [4 bytes] [4bytes] * fde_count  ...
 445          */
 446         size = 12 + (8 * fde_cnt);
 447 
 448         if ((elfdata->d_buf = libld_calloc(size, 1)) == NULL)
 449                 return (S_ERROR);
 450         elfdata->d_size = size;
 451         shdr->sh_size = (Xword)size;
 452 
 453         return (1);
 454 }
 455 
 456 /*
 457  * the comparator function needs to calculate
 458  * the actual 'initloc' of a bintab entry - to
 459  * do this we initialize the following global to point
 460  * to it.
 461  */
 462 static Addr framehdr_addr;
 463 
 464 static int
 465 bintabcompare(const void *p1, const void *p2)
 466 {
 467         uint_t      *bintab1, *bintab2;
 468         uint_t      ent1, ent2;
 469 
 470         bintab1 = (uint_t *)p1;
 471         bintab2 = (uint_t *)p2;
 472 
 473         assert(bintab1 != 0);
 474         assert(bintab2 != 0);
 475 
 476         ent1 = *bintab1 + framehdr_addr;
 477         ent2 = *bintab2 + framehdr_addr;
 478 
 479         if (ent1 > ent2)
 480                 return (1);
 481         if (ent1 < ent2)
 482                 return (-1);
 483         return (0);
 484 }
 485 
 486 uintptr_t
 487 ld_unwind_populate_hdr(Ofl_desc *ofl)
 488 {
 489         uchar_t         *hdrdata;
 490         uint_t          *binarytable;
 491         uint_t          hdroff;
 492         Aliste          idx;
 493         Addr            hdraddr;
 494         Os_desc         *hdrosp;
 495         Os_desc         *osp;
 496         Os_desc         *first_unwind;
 497         uint_t          fde_count;
 498         uint_t          *uint_ptr;
 499         int             bswap = (ofl->ofl_flags1 & FLG_OF1_ENCDIFF) != 0;
 500 
 501         /*
 502          * Are we building the unwind hdr?
 503          */
 504         if ((hdrosp = ofl->ofl_unwindhdr) == 0)
 505                 return (1);
 506 
 507         hdrdata = hdrosp->os_outdata->d_buf;
 508         hdraddr = hdrosp->os_shdr->sh_addr;
 509         hdroff = 0;
 510 
 511         /*
 512          * version == 1
 513          */
 514         hdrdata[hdroff++] = 1;
 515         /*
 516          * The encodings are:
 517          *
 518          *  eh_frameptr_enc     sdata4 | pcrel
 519          *  fde_count_enc       udata4
 520          *  table_enc           sdata4 | datarel
 521          */
 522         hdrdata[hdroff++] = DW_EH_PE_sdata4 | DW_EH_PE_pcrel;
 523         hdrdata[hdroff++] = DW_EH_PE_udata4;
 524         hdrdata[hdroff++] = DW_EH_PE_sdata4 | DW_EH_PE_datarel;
 525 
 526         /*
 527          *      Header Offsets
 528          *      -----------------------------------
 529          *      byte        version             +1
 530          *      byte        eh_frame_ptr_enc    +1
 531          *      byte        fde_count_enc       +1
 532          *      byte        table_enc           +1
 533          *      4 bytes     eh_frame_ptr        +4
 534          *      4 bytes     fde_count           +4
 535          */
 536         /* LINTED */
 537         binarytable =  (uint_t *)(hdrdata + 12);
 538         first_unwind = 0;
 539         fde_count = 0;
 540 
 541         for (APLIST_TRAVERSE(ofl->ofl_unwind, idx, osp)) {
 542                 uchar_t         *data;
 543                 size_t          size;
 544                 uint64_t        off = 0;
 545                 uint_t          cieRflag = 0, ciePflag = 0;
 546                 Shdr            *shdr;
 547 
 548                 /*
 549                  * remember first UNWIND section to
 550                  * point to in the frame_ptr entry.
 551                  */
 552                 if (first_unwind == 0)
 553                         first_unwind = osp;
 554 
 555                 data = osp->os_outdata->d_buf;
 556                 shdr = osp->os_shdr;
 557                 size = shdr->sh_size;
 558 
 559                 while (off < size) {
 560                         uint_t      length, id;
 561                         uint64_t    ndx = 0;
 562 
 563                         /*
 564                          * Extract length in lsb format.  A zero length
 565                          * indicates that this CIE is a terminator and that
 566                          * processing of unwind information is complete.
 567                          */
 568                         length = extract_uint(data + off, &ndx, bswap);
 569                         if (length == 0)
 570                                 goto done;
 571 
 572                         /*
 573                          * Extract CIE id in lsb format.
 574                          */
 575                         id = extract_uint(data + off, &ndx, bswap);
 576 
 577                         /*
 578                          * A CIE record has a id of '0'; otherwise
 579                          * this is a FDE entry and the 'id' is the
 580                          * CIE pointer.
 581                          */
 582                         if (id == 0) {
 583                                 char    *cieaugstr;
 584                                 uint_t  cieaugndx;
 585 
 586                                 ciePflag = 0;
 587                                 cieRflag = 0;
 588                                 /*
 589                                  * We need to drill through the CIE
 590                                  * to find the Rflag.  It's the Rflag
 591                                  * which describes how the FDE code-pointers
 592                                  * are encoded.
 593                                  */
 594 
 595                                 /*
 596                                  * burn through version
 597                                  */
 598                                 ndx++;
 599 
 600                                 /*
 601                                  * augstr
 602                                  */
 603                                 cieaugstr = (char *)(&data[off + ndx]);
 604                                 ndx += strlen(cieaugstr) + 1;
 605 
 606                                 /*
 607                                  * calign & dalign
 608                                  */
 609                                 (void) uleb_extract(&data[off], &ndx);
 610                                 (void) sleb_extract(&data[off], &ndx);
 611 
 612                                 /*
 613                                  * retreg
 614                                  */
 615                                 ndx++;
 616 
 617                                 /*
 618                                  * we walk through the augmentation
 619                                  * section now looking for the Rflag
 620                                  */
 621                                 for (cieaugndx = 0; cieaugstr[cieaugndx];
 622                                     cieaugndx++) {
 623                                         /* BEGIN CSTYLED */
 624                                         switch (cieaugstr[cieaugndx]) {
 625                                         case 'z':
 626                                             /* size */
 627                                             (void) uleb_extract(&data[off],
 628                                                 &ndx);
 629                                             break;
 630                                         case 'P':
 631                                             /* personality */
 632                                             ciePflag = data[off + ndx];
 633                                             ndx++;
 634                                                 /*
 635                                                  * Just need to extract the
 636                                                  * value to move on to the next
 637                                                  * field.
 638                                                  */
 639                                             (void) dwarf_ehe_extract(
 640                                                 &data[off + ndx],
 641                                                 &ndx, ciePflag,
 642                                                 ofl->ofl_dehdr->e_ident, B_FALSE,
 643                                                 shdr->sh_addr, off + ndx, 0);
 644                                             break;
 645                                         case 'R':
 646                                             /* code encoding */
 647                                             cieRflag = data[off + ndx];
 648                                             ndx++;
 649                                             break;
 650                                         case 'L':
 651                                             /* lsda encoding */
 652                                             ndx++;
 653                                             break;
 654                                         }
 655                                         /* END CSTYLED */
 656                                 }
 657                         } else {
 658                                 uint_t      bintabndx;
 659                                 uint64_t    initloc;
 660                                 uint64_t    fdeaddr;
 661                                 uint64_t    gotaddr = 0;
 662 
 663                                 if (ofl->ofl_osgot != NULL)
 664                                         gotaddr =
 665                                             ofl->ofl_osgot->os_shdr->sh_addr;
 666 
 667                                 initloc = dwarf_ehe_extract(&data[off],
 668                                     &ndx, cieRflag, ofl->ofl_dehdr->e_ident,
 669                                     B_FALSE,
 670                                     shdr->sh_addr, off + ndx,
 671                                     gotaddr);
 672 
 673                                 /*
 674                                  * Ignore FDEs with initloc set to 0.
 675                                  * initloc will not be 0 unless this FDE was
 676                                  * abandoned due to GNU linkonce processing.
 677                                  * The 0 value occurs because we don't resolve
 678                                  * sloppy relocations for unwind header target
 679                                  * sections.
 680                                  */
 681                                 if (initloc != 0) {
 682                                         bintabndx = fde_count * 2;
 683                                         fde_count++;
 684 
 685                                         /*
 686                                          * FDEaddr is adjusted
 687                                          * to account for the length & id which
 688                                          * have already been consumed.
 689                                          */
 690                                         fdeaddr = shdr->sh_addr + off;
 691 
 692                                         binarytable[bintabndx] =
 693                                             (uint_t)(initloc - hdraddr);
 694                                         binarytable[bintabndx + 1] =
 695                                             (uint_t)(fdeaddr - hdraddr);
 696                                 }
 697                         }
 698 
 699                         /*
 700                          * the length does not include the length
 701                          * itself - so account for that too.
 702                          */
 703                         off += length + 4;
 704                 }
 705         }
 706 
 707 done:
 708         /*
 709          * Do a quicksort on the binary table. If this is a cross
 710          * link from a system with the opposite byte order, xlate
 711          * the resulting values into LSB order.
 712          */
 713         framehdr_addr = hdraddr;
 714         qsort((void *)binarytable, (size_t)fde_count,
 715             (size_t)(sizeof (uint_t) * 2), bintabcompare);
 716         if (bswap) {
 717                 uint_t  *btable = binarytable;
 718                 uint_t  cnt;
 719 
 720                 for (cnt = fde_count * 2; cnt-- > 0; btable++)
 721                         *btable = ld_bswap_Word(*btable);
 722         }
 723 
 724         /*
 725          * Fill in:
 726          *      first_frame_ptr
 727          *      fde_count
 728          */
 729         hdroff = 4;
 730         /* LINTED */
 731         uint_ptr = (uint_t *)(&hdrdata[hdroff]);
 732         *uint_ptr = first_unwind->os_shdr->sh_addr -
 733             (hdrosp->os_shdr->sh_addr + hdroff);
 734         if (bswap)
 735                 *uint_ptr = ld_bswap_Word(*uint_ptr);
 736 
 737         hdroff += 4;
 738         /* LINTED */
 739         uint_ptr = (uint_t *)&hdrdata[hdroff];
 740         *uint_ptr = fde_count;
 741         if (bswap)
 742                 *uint_ptr = ld_bswap_Word(*uint_ptr);
 743 
 744         /*
 745          * If relaxed relocations are active, then there is a chance
 746          * that we didn't use all the space reserved for this section.
 747          * For details, see the note at head of ld_unwind_make_hdr() above.
 748          *
 749          * Find the PT_SUNW_UNWIND program header, and change the size values
 750          * to the size of the subset of the section that was actually used.
 751          */
 752         if (ofl->ofl_flags1 & FLG_OF1_RLXREL) {
 753                 Word    phnum = ofl->ofl_nehdr->e_phnum;
 754                 Phdr    *phdr = ofl->ofl_phdr;
 755 
 756                 for (; phnum-- > 0; phdr++) {
 757                         if (phdr->p_type == PT_SUNW_UNWIND) {
 758                                 phdr->p_memsz = 12 + (8 * fde_count);
 759                                 phdr->p_filesz = phdr->p_memsz;
 760                                 break;
 761                         }
 762                 }
 763         }
 764 
 765         return (1);
 766 }
 767 
 768 /*
 769  * Append an .eh_frame section to our output list if not already present.
 770  *
 771  * Usually, there is a single .eh_frame output section. However, there can
 772  * be more if there are incompatible section flags on incoming sections.
 773  * If this does happen, the frame_ptr field of the eh_frame_hdr section
 774  * will point at the base of the first output section, and the other
 775  * sections will not be accessible via frame_ptr. However, the .eh_frame_hdr
 776  * will be able to access all the data in the different .eh_frame sections,
 777  * because the entries in sorted table are all encoded as DW_EH_PE_datarel.
 778  */
 779 uintptr_t
 780 ld_unwind_register(Os_desc *osp, Ofl_desc * ofl)
 781 {
 782         Aliste  idx;
 783         Os_desc *_osp;
 784         /*
 785          * Check to see if this output section is already
 786          * on the list.
 787          */
 788         for (APLIST_TRAVERSE(ofl->ofl_unwind, idx, _osp))
 789                 if (osp == _osp)
 790                         return (1);
 791 
 792         /*
 793          * Append output section to unwind list
 794          */
 795         if (aplist_append(&ofl->ofl_unwind, osp, AL_CNT_OFL_UNWIND) == NULL)
 796                 return (S_ERROR);
 797 
 798         return (1);
 799 }