Back to index

cell-binutils  2.17cvs20070401
elf-eh-frame.c
Go to the documentation of this file.
00001 /* .eh_frame section optimization.
00002    Copyright 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
00003    Written by Jakub Jelinek <jakub@redhat.com>.
00004 
00005    This file is part of BFD, the Binary File Descriptor library.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program; if not, write to the Free Software
00019    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
00020 
00021 #include "bfd.h"
00022 #include "sysdep.h"
00023 #include "libbfd.h"
00024 #include "elf-bfd.h"
00025 #include "elf/dwarf2.h"
00026 
00027 #define EH_FRAME_HDR_SIZE 8
00028 
00029 struct cie
00030 {
00031   unsigned int length;
00032   unsigned int hash;
00033   unsigned char version;
00034   char augmentation[20];
00035   bfd_vma code_align;
00036   bfd_signed_vma data_align;
00037   bfd_vma ra_column;
00038   bfd_vma augmentation_size;
00039   struct elf_link_hash_entry *personality;
00040   asection *output_sec;
00041   struct eh_cie_fde *cie_inf;
00042   unsigned char per_encoding;
00043   unsigned char lsda_encoding;
00044   unsigned char fde_encoding;
00045   unsigned char initial_insn_length;
00046   unsigned char make_relative;
00047   unsigned char make_lsda_relative;
00048   unsigned char initial_instructions[50];
00049 };
00050 
00051 
00052 
00053 /* If *ITER hasn't reached END yet, read the next byte into *RESULT and
00054    move onto the next byte.  Return true on success.  */
00055 
00056 static inline bfd_boolean
00057 read_byte (bfd_byte **iter, bfd_byte *end, unsigned char *result)
00058 {
00059   if (*iter >= end)
00060     return FALSE;
00061   *result = *((*iter)++);
00062   return TRUE;
00063 }
00064 
00065 /* Move *ITER over LENGTH bytes, or up to END, whichever is closer.
00066    Return true it was possible to move LENGTH bytes.  */
00067 
00068 static inline bfd_boolean
00069 skip_bytes (bfd_byte **iter, bfd_byte *end, bfd_size_type length)
00070 {
00071   if ((bfd_size_type) (end - *iter) < length)
00072     {
00073       *iter = end;
00074       return FALSE;
00075     }
00076   *iter += length;
00077   return TRUE;
00078 }
00079 
00080 /* Move *ITER over an leb128, stopping at END.  Return true if the end
00081    of the leb128 was found.  */
00082 
00083 static bfd_boolean
00084 skip_leb128 (bfd_byte **iter, bfd_byte *end)
00085 {
00086   unsigned char byte;
00087   do
00088     if (!read_byte (iter, end, &byte))
00089       return FALSE;
00090   while (byte & 0x80);
00091   return TRUE;
00092 }
00093 
00094 /* Like skip_leb128, but treat the leb128 as an unsigned value and
00095    store it in *VALUE.  */
00096 
00097 static bfd_boolean
00098 read_uleb128 (bfd_byte **iter, bfd_byte *end, bfd_vma *value)
00099 {
00100   bfd_byte *start, *p;
00101 
00102   start = *iter;
00103   if (!skip_leb128 (iter, end))
00104     return FALSE;
00105 
00106   p = *iter;
00107   *value = *--p;
00108   while (p > start)
00109     *value = (*value << 7) | (*--p & 0x7f);
00110 
00111   return TRUE;
00112 }
00113 
00114 /* Like read_uleb128, but for signed values.  */
00115 
00116 static bfd_boolean
00117 read_sleb128 (bfd_byte **iter, bfd_byte *end, bfd_signed_vma *value)
00118 {
00119   bfd_byte *start, *p;
00120 
00121   start = *iter;
00122   if (!skip_leb128 (iter, end))
00123     return FALSE;
00124 
00125   p = *iter;
00126   *value = ((*--p & 0x7f) ^ 0x40) - 0x40;
00127   while (p > start)
00128     *value = (*value << 7) | (*--p & 0x7f);
00129 
00130   return TRUE;
00131 }
00132 
00133 /* Return 0 if either encoding is variable width, or not yet known to bfd.  */
00134 
00135 static
00136 int get_DW_EH_PE_width (int encoding, int ptr_size)
00137 {
00138   /* DW_EH_PE_ values of 0x60 and 0x70 weren't defined at the time .eh_frame
00139      was added to bfd.  */
00140   if ((encoding & 0x60) == 0x60)
00141     return 0;
00142 
00143   switch (encoding & 7)
00144     {
00145     case DW_EH_PE_udata2: return 2;
00146     case DW_EH_PE_udata4: return 4;
00147     case DW_EH_PE_udata8: return 8;
00148     case DW_EH_PE_absptr: return ptr_size;
00149     default:
00150       break;
00151     }
00152 
00153   return 0;
00154 }
00155 
00156 #define get_DW_EH_PE_signed(encoding) (((encoding) & DW_EH_PE_signed) != 0)
00157 
00158 /* Read a width sized value from memory.  */
00159 
00160 static bfd_vma
00161 read_value (bfd *abfd, bfd_byte *buf, int width, int is_signed)
00162 {
00163   bfd_vma value;
00164 
00165   switch (width)
00166     {
00167     case 2:
00168       if (is_signed)
00169        value = bfd_get_signed_16 (abfd, buf);
00170       else
00171        value = bfd_get_16 (abfd, buf);
00172       break;
00173     case 4:
00174       if (is_signed)
00175        value = bfd_get_signed_32 (abfd, buf);
00176       else
00177        value = bfd_get_32 (abfd, buf);
00178       break;
00179     case 8:
00180       if (is_signed)
00181        value = bfd_get_signed_64 (abfd, buf);
00182       else
00183        value = bfd_get_64 (abfd, buf);
00184       break;
00185     default:
00186       BFD_FAIL ();
00187       return 0;
00188     }
00189 
00190   return value;
00191 }
00192 
00193 /* Store a width sized value to memory.  */
00194 
00195 static void
00196 write_value (bfd *abfd, bfd_byte *buf, bfd_vma value, int width)
00197 {
00198   switch (width)
00199     {
00200     case 2: bfd_put_16 (abfd, value, buf); break;
00201     case 4: bfd_put_32 (abfd, value, buf); break;
00202     case 8: bfd_put_64 (abfd, value, buf); break;
00203     default: BFD_FAIL ();
00204     }
00205 }
00206 
00207 /* Return one if C1 and C2 CIEs can be merged.  */
00208 
00209 static int
00210 cie_eq (const void *e1, const void *e2)
00211 {
00212   const struct cie *c1 = e1;
00213   const struct cie *c2 = e2;
00214 
00215   if (c1->hash == c2->hash
00216       && c1->length == c2->length
00217       && c1->version == c2->version
00218       && strcmp (c1->augmentation, c2->augmentation) == 0
00219       && strcmp (c1->augmentation, "eh") != 0
00220       && c1->code_align == c2->code_align
00221       && c1->data_align == c2->data_align
00222       && c1->ra_column == c2->ra_column
00223       && c1->augmentation_size == c2->augmentation_size
00224       && c1->personality == c2->personality
00225       && c1->output_sec == c2->output_sec
00226       && c1->per_encoding == c2->per_encoding
00227       && c1->lsda_encoding == c2->lsda_encoding
00228       && c1->fde_encoding == c2->fde_encoding
00229       && c1->initial_insn_length == c2->initial_insn_length
00230       && memcmp (c1->initial_instructions,
00231                c2->initial_instructions,
00232                c1->initial_insn_length) == 0)
00233     return 1;
00234 
00235   return 0;
00236 }
00237 
00238 static hashval_t
00239 cie_hash (const void *e)
00240 {
00241   const struct cie *c = e;
00242   return c->hash;
00243 }
00244 
00245 static hashval_t
00246 cie_compute_hash (struct cie *c)
00247 {
00248   hashval_t h = 0;
00249   h = iterative_hash_object (c->length, h);
00250   h = iterative_hash_object (c->version, h);
00251   h = iterative_hash (c->augmentation, strlen (c->augmentation) + 1, h);
00252   h = iterative_hash_object (c->code_align, h);
00253   h = iterative_hash_object (c->data_align, h);
00254   h = iterative_hash_object (c->ra_column, h);
00255   h = iterative_hash_object (c->augmentation_size, h);
00256   h = iterative_hash_object (c->personality, h);
00257   h = iterative_hash_object (c->output_sec, h);
00258   h = iterative_hash_object (c->per_encoding, h);
00259   h = iterative_hash_object (c->lsda_encoding, h);
00260   h = iterative_hash_object (c->fde_encoding, h);
00261   h = iterative_hash_object (c->initial_insn_length, h);
00262   h = iterative_hash (c->initial_instructions, c->initial_insn_length, h);
00263   c->hash = h;
00264   return h;
00265 }
00266 
00267 /* Return the number of extra bytes that we'll be inserting into
00268    ENTRY's augmentation string.  */
00269 
00270 static INLINE unsigned int
00271 extra_augmentation_string_bytes (struct eh_cie_fde *entry)
00272 {
00273   unsigned int size = 0;
00274   if (entry->cie)
00275     {
00276       if (entry->add_augmentation_size)
00277        size++;
00278       if (entry->add_fde_encoding)
00279        size++;
00280     }
00281   return size;
00282 }
00283 
00284 /* Likewise ENTRY's augmentation data.  */
00285 
00286 static INLINE unsigned int
00287 extra_augmentation_data_bytes (struct eh_cie_fde *entry)
00288 {
00289   unsigned int size = 0;
00290   if (entry->cie)
00291     {
00292       if (entry->add_augmentation_size)
00293        size++;
00294       if (entry->add_fde_encoding)
00295        size++;
00296     }
00297   else
00298     {
00299       if (entry->cie_inf->add_augmentation_size)
00300        size++;
00301     }
00302   return size;
00303 }
00304 
00305 /* Return the size that ENTRY will have in the output.  ALIGNMENT is the
00306    required alignment of ENTRY in bytes.  */
00307 
00308 static unsigned int
00309 size_of_output_cie_fde (struct eh_cie_fde *entry, unsigned int alignment)
00310 {
00311   if (entry->removed)
00312     return 0;
00313   if (entry->size == 4)
00314     return 4;
00315   return (entry->size
00316          + extra_augmentation_string_bytes (entry)
00317          + extra_augmentation_data_bytes (entry)
00318          + alignment - 1) & -alignment;
00319 }
00320 
00321 /* Assume that the bytes between *ITER and END are CFA instructions.
00322    Try to move *ITER past the first instruction and return true on
00323    success.  ENCODED_PTR_WIDTH gives the width of pointer entries.  */
00324 
00325 static bfd_boolean
00326 skip_cfa_op (bfd_byte **iter, bfd_byte *end, unsigned int encoded_ptr_width)
00327 {
00328   bfd_byte op;
00329   bfd_vma length;
00330 
00331   if (!read_byte (iter, end, &op))
00332     return FALSE;
00333 
00334   switch (op & 0xc0 ? op & 0xc0 : op)
00335     {
00336     case DW_CFA_nop:
00337     case DW_CFA_advance_loc:
00338     case DW_CFA_restore:
00339     case DW_CFA_remember_state:
00340     case DW_CFA_restore_state:
00341     case DW_CFA_GNU_window_save:
00342       /* No arguments.  */
00343       return TRUE;
00344 
00345     case DW_CFA_offset:
00346     case DW_CFA_restore_extended:
00347     case DW_CFA_undefined:
00348     case DW_CFA_same_value:
00349     case DW_CFA_def_cfa_register:
00350     case DW_CFA_def_cfa_offset:
00351     case DW_CFA_def_cfa_offset_sf:
00352     case DW_CFA_GNU_args_size:
00353       /* One leb128 argument.  */
00354       return skip_leb128 (iter, end);
00355 
00356     case DW_CFA_val_offset:
00357     case DW_CFA_val_offset_sf:
00358     case DW_CFA_offset_extended:
00359     case DW_CFA_register:
00360     case DW_CFA_def_cfa:
00361     case DW_CFA_offset_extended_sf:
00362     case DW_CFA_GNU_negative_offset_extended:
00363     case DW_CFA_def_cfa_sf:
00364       /* Two leb128 arguments.  */
00365       return (skip_leb128 (iter, end)
00366              && skip_leb128 (iter, end));
00367 
00368     case DW_CFA_def_cfa_expression:
00369       /* A variable-length argument.  */
00370       return (read_uleb128 (iter, end, &length)
00371              && skip_bytes (iter, end, length));
00372 
00373     case DW_CFA_expression:
00374     case DW_CFA_val_expression:
00375       /* A leb128 followed by a variable-length argument.  */
00376       return (skip_leb128 (iter, end)
00377              && read_uleb128 (iter, end, &length)
00378              && skip_bytes (iter, end, length));
00379 
00380     case DW_CFA_set_loc:
00381       return skip_bytes (iter, end, encoded_ptr_width);
00382 
00383     case DW_CFA_advance_loc1:
00384       return skip_bytes (iter, end, 1);
00385 
00386     case DW_CFA_advance_loc2:
00387       return skip_bytes (iter, end, 2);
00388 
00389     case DW_CFA_advance_loc4:
00390       return skip_bytes (iter, end, 4);
00391 
00392     case DW_CFA_MIPS_advance_loc8:
00393       return skip_bytes (iter, end, 8);
00394 
00395     default:
00396       return FALSE;
00397     }
00398 }
00399 
00400 /* Try to interpret the bytes between BUF and END as CFA instructions.
00401    If every byte makes sense, return a pointer to the first DW_CFA_nop
00402    padding byte, or END if there is no padding.  Return null otherwise.
00403    ENCODED_PTR_WIDTH is as for skip_cfa_op.  */
00404 
00405 static bfd_byte *
00406 skip_non_nops (bfd_byte *buf, bfd_byte *end, unsigned int encoded_ptr_width,
00407               unsigned int *set_loc_count)
00408 {
00409   bfd_byte *last;
00410 
00411   last = buf;
00412   while (buf < end)
00413     if (*buf == DW_CFA_nop)
00414       buf++;
00415     else
00416       {
00417        if (*buf == DW_CFA_set_loc)
00418          ++*set_loc_count;
00419        if (!skip_cfa_op (&buf, end, encoded_ptr_width))
00420          return 0;
00421        last = buf;
00422       }
00423   return last;
00424 }
00425 
00426 /* This function is called for each input file before the .eh_frame
00427    section is relocated.  It discards duplicate CIEs and FDEs for discarded
00428    functions.  The function returns TRUE iff any entries have been
00429    deleted.  */
00430 
00431 bfd_boolean
00432 _bfd_elf_discard_section_eh_frame
00433    (bfd *abfd, struct bfd_link_info *info, asection *sec,
00434     bfd_boolean (*reloc_symbol_deleted_p) (bfd_vma, void *),
00435     struct elf_reloc_cookie *cookie)
00436 {
00437 #define REQUIRE(COND)                                   \
00438   do                                             \
00439     if (!(COND))                                 \
00440       goto free_no_table;                        \
00441   while (0)
00442 
00443   bfd_byte *ehbuf = NULL, *buf;
00444   bfd_byte *last_fde;
00445   struct eh_cie_fde *ent, *this_inf;
00446   unsigned int hdr_length, hdr_id;
00447   struct extended_cie
00448     {
00449       struct cie cie;
00450       unsigned int offset;
00451       unsigned int usage_count;
00452       unsigned int entry;
00453     } *ecies = NULL, *ecie;
00454   unsigned int ecie_count = 0, ecie_alloced = 0;
00455   struct cie *cie;
00456   struct elf_link_hash_table *htab;
00457   struct eh_frame_hdr_info *hdr_info;
00458   struct eh_frame_sec_info *sec_info = NULL;
00459   unsigned int offset;
00460   unsigned int ptr_size;
00461   unsigned int entry_alloced;
00462 
00463   if (sec->size == 0)
00464     {
00465       /* This file does not contain .eh_frame information.  */
00466       return FALSE;
00467     }
00468 
00469   if (bfd_is_abs_section (sec->output_section))
00470     {
00471       /* At least one of the sections is being discarded from the
00472         link, so we should just ignore them.  */
00473       return FALSE;
00474     }
00475 
00476   htab = elf_hash_table (info);
00477   hdr_info = &htab->eh_info;
00478 
00479   if (hdr_info->cies == NULL && !info->relocatable)
00480     hdr_info->cies = htab_try_create (1, cie_hash, cie_eq, free);
00481 
00482   /* Read the frame unwind information from abfd.  */
00483 
00484   REQUIRE (bfd_malloc_and_get_section (abfd, sec, &ehbuf));
00485 
00486   if (sec->size >= 4
00487       && bfd_get_32 (abfd, ehbuf) == 0
00488       && cookie->rel == cookie->relend)
00489     {
00490       /* Empty .eh_frame section.  */
00491       free (ehbuf);
00492       return FALSE;
00493     }
00494 
00495   /* If .eh_frame section size doesn't fit into int, we cannot handle
00496      it (it would need to use 64-bit .eh_frame format anyway).  */
00497   REQUIRE (sec->size == (unsigned int) sec->size);
00498 
00499   ptr_size = (get_elf_backend_data (abfd)
00500              ->elf_backend_eh_frame_address_size (abfd, sec));
00501   REQUIRE (ptr_size != 0);
00502 
00503   buf = ehbuf;
00504   sec_info = bfd_zmalloc (sizeof (struct eh_frame_sec_info)
00505                        + 99 * sizeof (struct eh_cie_fde));
00506   REQUIRE (sec_info);
00507 
00508   entry_alloced = 100;
00509 
00510 #define ENSURE_NO_RELOCS(buf)                           \
00511   REQUIRE (!(cookie->rel < cookie->relend        \
00512             && (cookie->rel->r_offset                   \
00513                < (bfd_size_type) ((buf) - ehbuf))       \
00514             && cookie->rel->r_info != 0))
00515 
00516 #define SKIP_RELOCS(buf)                         \
00517   while (cookie->rel < cookie->relend                   \
00518         && (cookie->rel->r_offset                \
00519             < (bfd_size_type) ((buf) - ehbuf)))  \
00520     cookie->rel++
00521 
00522 #define GET_RELOC(buf)                                  \
00523   ((cookie->rel < cookie->relend                 \
00524     && (cookie->rel->r_offset                           \
00525        == (bfd_size_type) ((buf) - ehbuf)))             \
00526    ? cookie->rel : NULL)
00527 
00528   for (;;)
00529     {
00530       char *aug;
00531       bfd_byte *start, *end, *insns, *insns_end;
00532       bfd_size_type length;
00533       unsigned int set_loc_count;
00534 
00535       if (sec_info->count == entry_alloced)
00536        {
00537          sec_info = bfd_realloc (sec_info,
00538                               sizeof (struct eh_frame_sec_info)
00539                               + ((entry_alloced + 99)
00540                                  * sizeof (struct eh_cie_fde)));
00541          REQUIRE (sec_info);
00542 
00543          memset (&sec_info->entry[entry_alloced], 0,
00544                 100 * sizeof (struct eh_cie_fde));
00545          entry_alloced += 100;
00546        }
00547 
00548       this_inf = sec_info->entry + sec_info->count;
00549       last_fde = buf;
00550 
00551       if ((bfd_size_type) (buf - ehbuf) == sec->size)
00552        break;
00553 
00554       /* Read the length of the entry.  */
00555       REQUIRE (skip_bytes (&buf, ehbuf + sec->size, 4));
00556       hdr_length = bfd_get_32 (abfd, buf - 4);
00557 
00558       /* 64-bit .eh_frame is not supported.  */
00559       REQUIRE (hdr_length != 0xffffffff);
00560 
00561       /* The CIE/FDE must be fully contained in this input section.  */
00562       REQUIRE ((bfd_size_type) (buf - ehbuf) + hdr_length <= sec->size);
00563       end = buf + hdr_length;
00564 
00565       this_inf->offset = last_fde - ehbuf;
00566       this_inf->size = 4 + hdr_length;
00567 
00568       if (hdr_length == 0)
00569        {
00570          /* A zero-length CIE should only be found at the end of
00571             the section.  */
00572          REQUIRE ((bfd_size_type) (buf - ehbuf) == sec->size);
00573          ENSURE_NO_RELOCS (buf);
00574          sec_info->count++;
00575          break;
00576        }
00577 
00578       REQUIRE (skip_bytes (&buf, end, 4));
00579       hdr_id = bfd_get_32 (abfd, buf - 4);
00580 
00581       if (hdr_id == 0)
00582        {
00583          unsigned int initial_insn_length;
00584 
00585          /* CIE  */
00586          this_inf->cie = 1;
00587 
00588          if (ecie_count == ecie_alloced)
00589            {
00590              ecies = bfd_realloc (ecies,
00591                                (ecie_alloced + 20) * sizeof (*ecies));
00592              REQUIRE (ecies);
00593              memset (&ecies[ecie_alloced], 0, 20 * sizeof (*ecies));
00594              ecie_alloced += 20;
00595            }
00596 
00597          cie = &ecies[ecie_count].cie;
00598          ecies[ecie_count].offset = this_inf->offset;
00599          ecies[ecie_count++].entry = sec_info->count;
00600          cie->length = hdr_length;
00601          start = buf;
00602          REQUIRE (read_byte (&buf, end, &cie->version));
00603 
00604          /* Cannot handle unknown versions.  */
00605          REQUIRE (cie->version == 1 || cie->version == 3);
00606          REQUIRE (strlen ((char *) buf) < sizeof (cie->augmentation));
00607 
00608          strcpy (cie->augmentation, (char *) buf);
00609          buf = (bfd_byte *) strchr ((char *) buf, '\0') + 1;
00610          ENSURE_NO_RELOCS (buf);
00611          if (buf[0] == 'e' && buf[1] == 'h')
00612            {
00613              /* GCC < 3.0 .eh_frame CIE */
00614              /* We cannot merge "eh" CIEs because __EXCEPTION_TABLE__
00615                is private to each CIE, so we don't need it for anything.
00616                Just skip it.  */
00617              REQUIRE (skip_bytes (&buf, end, ptr_size));
00618              SKIP_RELOCS (buf);
00619            }
00620          REQUIRE (read_uleb128 (&buf, end, &cie->code_align));
00621          REQUIRE (read_sleb128 (&buf, end, &cie->data_align));
00622          if (cie->version == 1)
00623            {
00624              REQUIRE (buf < end);
00625              cie->ra_column = *buf++;
00626            }
00627          else
00628            REQUIRE (read_uleb128 (&buf, end, &cie->ra_column));
00629          ENSURE_NO_RELOCS (buf);
00630          cie->lsda_encoding = DW_EH_PE_omit;
00631          cie->fde_encoding = DW_EH_PE_omit;
00632          cie->per_encoding = DW_EH_PE_omit;
00633          aug = cie->augmentation;
00634          if (aug[0] != 'e' || aug[1] != 'h')
00635            {
00636              if (*aug == 'z')
00637               {
00638                 aug++;
00639                 REQUIRE (read_uleb128 (&buf, end, &cie->augmentation_size));
00640                 ENSURE_NO_RELOCS (buf);
00641               }
00642 
00643              while (*aug != '\0')
00644               switch (*aug++)
00645                 {
00646                 case 'L':
00647                   REQUIRE (read_byte (&buf, end, &cie->lsda_encoding));
00648                   ENSURE_NO_RELOCS (buf);
00649                   REQUIRE (get_DW_EH_PE_width (cie->lsda_encoding, ptr_size));
00650                   break;
00651                 case 'R':
00652                   REQUIRE (read_byte (&buf, end, &cie->fde_encoding));
00653                   ENSURE_NO_RELOCS (buf);
00654                   REQUIRE (get_DW_EH_PE_width (cie->fde_encoding, ptr_size));
00655                   break;
00656                 case 'S':
00657                   break;
00658                 case 'P':
00659                   {
00660                     int per_width;
00661 
00662                     REQUIRE (read_byte (&buf, end, &cie->per_encoding));
00663                     per_width = get_DW_EH_PE_width (cie->per_encoding,
00664                                                 ptr_size);
00665                     REQUIRE (per_width);
00666                     if ((cie->per_encoding & 0xf0) == DW_EH_PE_aligned)
00667                      {
00668                        length = -(buf - ehbuf) & (per_width - 1);
00669                        REQUIRE (skip_bytes (&buf, end, length));
00670                      }
00671                     ENSURE_NO_RELOCS (buf);
00672                     /* Ensure we have a reloc here, against
00673                       a global symbol.  */
00674                     if (GET_RELOC (buf) != NULL)
00675                      {
00676                        unsigned long r_symndx;
00677 
00678 #ifdef BFD64
00679                        if (ptr_size == 8)
00680                          r_symndx = ELF64_R_SYM (cookie->rel->r_info);
00681                        else
00682 #endif
00683                          r_symndx = ELF32_R_SYM (cookie->rel->r_info);
00684                        if (r_symndx >= cookie->locsymcount)
00685                          {
00686                            struct elf_link_hash_entry *h;
00687 
00688                            r_symndx -= cookie->extsymoff;
00689                            h = cookie->sym_hashes[r_symndx];
00690 
00691                            while (h->root.type == bfd_link_hash_indirect
00692                                  || h->root.type == bfd_link_hash_warning)
00693                             h = (struct elf_link_hash_entry *)
00694                                 h->root.u.i.link;
00695 
00696                            cie->personality = h;
00697                          }
00698                        /* Cope with MIPS-style composite relocations.  */
00699                        do
00700                          cookie->rel++;
00701                        while (GET_RELOC (buf) != NULL);
00702                      }
00703                     REQUIRE (skip_bytes (&buf, end, per_width));
00704                     REQUIRE (cie->personality);
00705                   }
00706                   break;
00707                 default:
00708                   /* Unrecognized augmentation. Better bail out.  */
00709                   goto free_no_table;
00710                 }
00711            }
00712 
00713          /* For shared libraries, try to get rid of as many RELATIVE relocs
00714             as possible.  */
00715          if (info->shared
00716              && (get_elf_backend_data (abfd)
00717                 ->elf_backend_can_make_relative_eh_frame
00718                 (abfd, info, sec)))
00719            {
00720              if ((cie->fde_encoding & 0xf0) == DW_EH_PE_absptr)
00721               cie->make_relative = 1;
00722              /* If the CIE doesn't already have an 'R' entry, it's fairly
00723                easy to add one, provided that there's no aligned data
00724                after the augmentation string.  */
00725              else if (cie->fde_encoding == DW_EH_PE_omit
00726                      && (cie->per_encoding & 0xf0) != DW_EH_PE_aligned)
00727               {
00728                 if (*cie->augmentation == 0)
00729                   this_inf->add_augmentation_size = 1;
00730                 this_inf->add_fde_encoding = 1;
00731                 cie->make_relative = 1;
00732               }
00733            }
00734 
00735          if (info->shared
00736              && (get_elf_backend_data (abfd)
00737                 ->elf_backend_can_make_lsda_relative_eh_frame
00738                 (abfd, info, sec))
00739              && (cie->lsda_encoding & 0xf0) == DW_EH_PE_absptr)
00740            cie->make_lsda_relative = 1;
00741 
00742          /* If FDE encoding was not specified, it defaults to
00743             DW_EH_absptr.  */
00744          if (cie->fde_encoding == DW_EH_PE_omit)
00745            cie->fde_encoding = DW_EH_PE_absptr;
00746 
00747          initial_insn_length = end - buf;
00748          if (initial_insn_length <= sizeof (cie->initial_instructions))
00749            {
00750              cie->initial_insn_length = initial_insn_length;
00751              memcpy (cie->initial_instructions, buf, initial_insn_length);
00752            }
00753          insns = buf;
00754          buf += initial_insn_length;
00755          ENSURE_NO_RELOCS (buf);
00756        }
00757       else
00758        {
00759          /* Find the corresponding CIE.  */
00760          unsigned int cie_offset = this_inf->offset + 4 - hdr_id;
00761          for (ecie = ecies; ecie < ecies + ecie_count; ++ecie)
00762            if (cie_offset == ecie->offset)
00763              break;
00764 
00765          /* Ensure this FDE references one of the CIEs in this input
00766             section.  */
00767          REQUIRE (ecie != ecies + ecie_count);
00768          cie = &ecie->cie;
00769 
00770          ENSURE_NO_RELOCS (buf);
00771          REQUIRE (GET_RELOC (buf));
00772 
00773          if ((*reloc_symbol_deleted_p) (buf - ehbuf, cookie))
00774            /* This is a FDE against a discarded section.  It should
00775               be deleted.  */
00776            this_inf->removed = 1;
00777          else
00778            {
00779              if (info->shared
00780                 && (((cie->fde_encoding & 0xf0) == DW_EH_PE_absptr
00781                      && cie->make_relative == 0)
00782                     || (cie->fde_encoding & 0xf0) == DW_EH_PE_aligned))
00783               {
00784                 /* If a shared library uses absolute pointers
00785                    which we cannot turn into PC relative,
00786                    don't create the binary search table,
00787                    since it is affected by runtime relocations.  */
00788                 hdr_info->table = FALSE;
00789               }
00790              ecie->usage_count++;
00791              hdr_info->fde_count++;
00792              this_inf->cie_inf = (void *) (ecie - ecies);
00793            }
00794 
00795          /* Skip the initial location and address range.  */
00796          start = buf;
00797          length = get_DW_EH_PE_width (cie->fde_encoding, ptr_size);
00798          REQUIRE (skip_bytes (&buf, end, 2 * length));
00799 
00800          /* Skip the augmentation size, if present.  */
00801          if (cie->augmentation[0] == 'z')
00802            REQUIRE (read_uleb128 (&buf, end, &length));
00803          else
00804            length = 0;
00805 
00806          /* Of the supported augmentation characters above, only 'L'
00807             adds augmentation data to the FDE.  This code would need to
00808             be adjusted if any future augmentations do the same thing.  */
00809          if (cie->lsda_encoding != DW_EH_PE_omit)
00810            {
00811              this_inf->lsda_offset = buf - start;
00812              /* If there's no 'z' augmentation, we don't know where the
00813                CFA insns begin.  Assume no padding.  */
00814              if (cie->augmentation[0] != 'z')
00815               length = end - buf;
00816            }
00817 
00818          /* Skip over the augmentation data.  */
00819          REQUIRE (skip_bytes (&buf, end, length));
00820          insns = buf;
00821 
00822          buf = last_fde + 4 + hdr_length;
00823          SKIP_RELOCS (buf);
00824        }
00825 
00826       /* Try to interpret the CFA instructions and find the first
00827         padding nop.  Shrink this_inf's size so that it doesn't
00828         include the padding.  */
00829       length = get_DW_EH_PE_width (cie->fde_encoding, ptr_size);
00830       set_loc_count = 0;
00831       insns_end = skip_non_nops (insns, end, length, &set_loc_count);
00832       /* If we don't understand the CFA instructions, we can't know
00833         what needs to be adjusted there.  */
00834       if (insns_end == NULL
00835          /* For the time being we don't support DW_CFA_set_loc in
00836             CIE instructions.  */
00837          || (set_loc_count && this_inf->cie))
00838        goto free_no_table;
00839       this_inf->size -= end - insns_end;
00840       if (insns_end != end && this_inf->cie)
00841        {
00842          cie->initial_insn_length -= end - insns_end;
00843          cie->length -= end - insns_end;
00844        }
00845       if (set_loc_count
00846          && ((cie->fde_encoding & 0xf0) == DW_EH_PE_pcrel
00847              || cie->make_relative))
00848        {
00849          unsigned int cnt;
00850          bfd_byte *p;
00851 
00852          this_inf->set_loc = bfd_malloc ((set_loc_count + 1)
00853                                      * sizeof (unsigned int));
00854          REQUIRE (this_inf->set_loc);
00855          this_inf->set_loc[0] = set_loc_count;
00856          p = insns;
00857          cnt = 0;
00858          while (p < end)
00859            {
00860              if (*p == DW_CFA_set_loc)
00861               this_inf->set_loc[++cnt] = p + 1 - start;
00862              REQUIRE (skip_cfa_op (&p, end, length));
00863            }
00864        }
00865 
00866       this_inf->fde_encoding = cie->fde_encoding;
00867       this_inf->lsda_encoding = cie->lsda_encoding;
00868       sec_info->count++;
00869     }
00870 
00871   elf_section_data (sec)->sec_info = sec_info;
00872   sec->sec_info_type = ELF_INFO_TYPE_EH_FRAME;
00873 
00874   /* Look at all CIEs in this section and determine which can be
00875      removed as unused, which can be merged with previous duplicate
00876      CIEs and which need to be kept.  */
00877   for (ecie = ecies; ecie < ecies + ecie_count; ++ecie)
00878     {
00879       if (ecie->usage_count == 0)
00880        {
00881          sec_info->entry[ecie->entry].removed = 1;
00882          continue;
00883        }
00884       ecie->cie.output_sec = sec->output_section;
00885       ecie->cie.cie_inf = sec_info->entry + ecie->entry;
00886       cie_compute_hash (&ecie->cie);
00887       if (hdr_info->cies != NULL)
00888        {
00889          void **loc = htab_find_slot_with_hash (hdr_info->cies, &ecie->cie,
00890                                            ecie->cie.hash, INSERT);
00891          if (loc != NULL)
00892            {
00893              if (*loc != HTAB_EMPTY_ENTRY)
00894               {
00895                 sec_info->entry[ecie->entry].removed = 1;
00896                 ecie->cie.cie_inf = ((struct cie *) *loc)->cie_inf;
00897                 continue;
00898               }
00899 
00900              *loc = malloc (sizeof (struct cie));
00901              if (*loc == NULL)
00902               *loc = HTAB_DELETED_ENTRY;
00903              else
00904               memcpy (*loc, &ecie->cie, sizeof (struct cie));
00905            }
00906        }
00907       ecie->cie.cie_inf->make_relative = ecie->cie.make_relative;
00908       ecie->cie.cie_inf->make_lsda_relative = ecie->cie.make_lsda_relative;
00909       ecie->cie.cie_inf->per_encoding_relative
00910        = (ecie->cie.per_encoding & 0x70) == DW_EH_PE_pcrel;
00911     }
00912 
00913   /* Ok, now we can assign new offsets.  */
00914   offset = 0;
00915   for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
00916     if (!ent->removed)
00917       {
00918        if (!ent->cie)
00919          {
00920            ecie = ecies + (unsigned long) ent->cie_inf;
00921            ent->cie_inf = ecie->cie.cie_inf;
00922          }
00923        ent->new_offset = offset;
00924        offset += size_of_output_cie_fde (ent, ptr_size);
00925       }
00926 
00927   /* Resize the sec as needed.  */
00928   sec->rawsize = sec->size;
00929   sec->size = offset;
00930 
00931   free (ehbuf);
00932   if (ecies)
00933     free (ecies);
00934   return offset != sec->rawsize;
00935 
00936 free_no_table:
00937   if (ehbuf)
00938     free (ehbuf);
00939   if (sec_info)
00940     free (sec_info);
00941   if (ecies)
00942     free (ecies);
00943   hdr_info->table = FALSE;
00944   return FALSE;
00945 
00946 #undef REQUIRE
00947 }
00948 
00949 /* This function is called for .eh_frame_hdr section after
00950    _bfd_elf_discard_section_eh_frame has been called on all .eh_frame
00951    input sections.  It finalizes the size of .eh_frame_hdr section.  */
00952 
00953 bfd_boolean
00954 _bfd_elf_discard_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
00955 {
00956   struct elf_link_hash_table *htab;
00957   struct eh_frame_hdr_info *hdr_info;
00958   asection *sec;
00959 
00960   htab = elf_hash_table (info);
00961   hdr_info = &htab->eh_info;
00962 
00963   if (hdr_info->cies != NULL)
00964     {
00965       htab_delete (hdr_info->cies);
00966       hdr_info->cies = NULL;
00967     }
00968 
00969   sec = hdr_info->hdr_sec;
00970   if (sec == NULL)
00971     return FALSE;
00972 
00973   sec->size = EH_FRAME_HDR_SIZE;
00974   if (hdr_info->table)
00975     sec->size += 4 + hdr_info->fde_count * 8;
00976 
00977   elf_tdata (abfd)->eh_frame_hdr = sec;
00978   return TRUE;
00979 }
00980 
00981 /* This function is called from size_dynamic_sections.
00982    It needs to decide whether .eh_frame_hdr should be output or not,
00983    because when the dynamic symbol table has been sized it is too late
00984    to strip sections.  */
00985 
00986 bfd_boolean
00987 _bfd_elf_maybe_strip_eh_frame_hdr (struct bfd_link_info *info)
00988 {
00989   asection *o;
00990   bfd *abfd;
00991   struct elf_link_hash_table *htab;
00992   struct eh_frame_hdr_info *hdr_info;
00993 
00994   htab = elf_hash_table (info);
00995   hdr_info = &htab->eh_info;
00996   if (hdr_info->hdr_sec == NULL)
00997     return TRUE;
00998 
00999   if (bfd_is_abs_section (hdr_info->hdr_sec->output_section))
01000     {
01001       hdr_info->hdr_sec = NULL;
01002       return TRUE;
01003     }
01004 
01005   abfd = NULL;
01006   if (info->eh_frame_hdr)
01007     for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
01008       {
01009        /* Count only sections which have at least a single CIE or FDE.
01010           There cannot be any CIE or FDE <= 8 bytes.  */
01011        o = bfd_get_section_by_name (abfd, ".eh_frame");
01012        if (o && o->size > 8 && !bfd_is_abs_section (o->output_section))
01013          break;
01014       }
01015 
01016   if (abfd == NULL)
01017     {
01018       hdr_info->hdr_sec->flags |= SEC_EXCLUDE;
01019       hdr_info->hdr_sec = NULL;
01020       return TRUE;
01021     }
01022 
01023   hdr_info->table = TRUE;
01024   return TRUE;
01025 }
01026 
01027 /* Adjust an address in the .eh_frame section.  Given OFFSET within
01028    SEC, this returns the new offset in the adjusted .eh_frame section,
01029    or -1 if the address refers to a CIE/FDE which has been removed
01030    or to offset with dynamic relocation which is no longer needed.  */
01031 
01032 bfd_vma
01033 _bfd_elf_eh_frame_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED,
01034                               struct bfd_link_info *info,
01035                               asection *sec,
01036                               bfd_vma offset)
01037 {
01038   struct eh_frame_sec_info *sec_info;
01039   struct elf_link_hash_table *htab;
01040   struct eh_frame_hdr_info *hdr_info;
01041   unsigned int lo, hi, mid;
01042 
01043   if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
01044     return offset;
01045   sec_info = elf_section_data (sec)->sec_info;
01046 
01047   if (offset >= sec->rawsize)
01048     return offset - sec->rawsize + sec->size;
01049 
01050   htab = elf_hash_table (info);
01051   hdr_info = &htab->eh_info;
01052   if (hdr_info->offsets_adjusted)
01053     offset += sec->output_offset;
01054 
01055   lo = 0;
01056   hi = sec_info->count;
01057   mid = 0;
01058   while (lo < hi)
01059     {
01060       mid = (lo + hi) / 2;
01061       if (offset < sec_info->entry[mid].offset)
01062        hi = mid;
01063       else if (offset
01064               >= sec_info->entry[mid].offset + sec_info->entry[mid].size)
01065        lo = mid + 1;
01066       else
01067        break;
01068     }
01069 
01070   BFD_ASSERT (lo < hi);
01071 
01072   /* FDE or CIE was removed.  */
01073   if (sec_info->entry[mid].removed)
01074     return (bfd_vma) -1;
01075 
01076   /* If converting to DW_EH_PE_pcrel, there will be no need for run-time
01077      relocation against FDE's initial_location field.  */
01078   if (!sec_info->entry[mid].cie
01079       && sec_info->entry[mid].cie_inf->make_relative
01080       && offset == sec_info->entry[mid].offset + 8)
01081     return (bfd_vma) -2;
01082 
01083   /* If converting LSDA pointers to DW_EH_PE_pcrel, there will be no need
01084      for run-time relocation against LSDA field.  */
01085   if (!sec_info->entry[mid].cie
01086       && sec_info->entry[mid].cie_inf->make_lsda_relative
01087       && (offset == (sec_info->entry[mid].offset + 8
01088                    + sec_info->entry[mid].lsda_offset))
01089       && (sec_info->entry[mid].cie_inf->need_lsda_relative
01090          || !hdr_info->offsets_adjusted))
01091     {
01092       sec_info->entry[mid].cie_inf->need_lsda_relative = 1;
01093       return (bfd_vma) -2;
01094     }
01095 
01096   /* If converting to DW_EH_PE_pcrel, there will be no need for run-time
01097      relocation against DW_CFA_set_loc's arguments.  */
01098   if (sec_info->entry[mid].set_loc
01099       && (sec_info->entry[mid].cie
01100          ? sec_info->entry[mid].make_relative
01101          : sec_info->entry[mid].cie_inf->make_relative)
01102       && (offset >= sec_info->entry[mid].offset + 8
01103                   + sec_info->entry[mid].set_loc[1]))
01104     {
01105       unsigned int cnt;
01106 
01107       for (cnt = 1; cnt <= sec_info->entry[mid].set_loc[0]; cnt++)
01108        if (offset == sec_info->entry[mid].offset + 8
01109                     + sec_info->entry[mid].set_loc[cnt])
01110          return (bfd_vma) -2;
01111     }
01112 
01113   if (hdr_info->offsets_adjusted)
01114     offset -= sec->output_offset;
01115   /* Any new augmentation bytes go before the first relocation.  */
01116   return (offset + sec_info->entry[mid].new_offset
01117          - sec_info->entry[mid].offset
01118          + extra_augmentation_string_bytes (sec_info->entry + mid)
01119          + extra_augmentation_data_bytes (sec_info->entry + mid));
01120 }
01121 
01122 /* Write out .eh_frame section.  This is called with the relocated
01123    contents.  */
01124 
01125 bfd_boolean
01126 _bfd_elf_write_section_eh_frame (bfd *abfd,
01127                              struct bfd_link_info *info,
01128                              asection *sec,
01129                              bfd_byte *contents)
01130 {
01131   struct eh_frame_sec_info *sec_info;
01132   struct elf_link_hash_table *htab;
01133   struct eh_frame_hdr_info *hdr_info;
01134   unsigned int ptr_size;
01135   struct eh_cie_fde *ent;
01136 
01137   if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
01138     return bfd_set_section_contents (abfd, sec->output_section, contents,
01139                                  sec->output_offset, sec->size);
01140 
01141   ptr_size = (get_elf_backend_data (abfd)
01142              ->elf_backend_eh_frame_address_size (abfd, sec));
01143   BFD_ASSERT (ptr_size != 0);
01144 
01145   sec_info = elf_section_data (sec)->sec_info;
01146   htab = elf_hash_table (info);
01147   hdr_info = &htab->eh_info;
01148 
01149   /* First convert all offsets to output section offsets, so that a
01150      CIE offset is valid if the CIE is used by a FDE from some other
01151      section.  This can happen when duplicate CIEs are deleted in
01152      _bfd_elf_discard_section_eh_frame.  We do all sections here because
01153      this function might not be called on sections in the same order as
01154      _bfd_elf_discard_section_eh_frame.  */
01155   if (!hdr_info->offsets_adjusted)
01156     {
01157       bfd *ibfd;
01158       asection *eh;
01159       struct eh_frame_sec_info *eh_inf;
01160 
01161       for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
01162        {
01163          if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
01164              || (ibfd->flags & DYNAMIC) != 0)
01165            continue;
01166 
01167          eh = bfd_get_section_by_name (ibfd, ".eh_frame");
01168          if (eh == NULL || eh->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
01169            continue;
01170 
01171          eh_inf = elf_section_data (eh)->sec_info;
01172          for (ent = eh_inf->entry; ent < eh_inf->entry + eh_inf->count; ++ent)
01173            {
01174              ent->offset += eh->output_offset;
01175              ent->new_offset += eh->output_offset;
01176            }
01177        }
01178       hdr_info->offsets_adjusted = TRUE;
01179     }
01180 
01181   if (hdr_info->table && hdr_info->array == NULL)
01182     hdr_info->array
01183       = bfd_malloc (hdr_info->fde_count * sizeof(*hdr_info->array));
01184   if (hdr_info->array == NULL)
01185     hdr_info = NULL;
01186 
01187   /* The new offsets can be bigger or smaller than the original offsets.
01188      We therefore need to make two passes over the section: one backward
01189      pass to move entries up and one forward pass to move entries down.
01190      The two passes won't interfere with each other because entries are
01191      not reordered  */
01192   for (ent = sec_info->entry + sec_info->count; ent-- != sec_info->entry;)
01193     if (!ent->removed && ent->new_offset > ent->offset)
01194       memmove (contents + ent->new_offset - sec->output_offset,
01195               contents + ent->offset - sec->output_offset, ent->size);
01196 
01197   for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
01198     if (!ent->removed && ent->new_offset < ent->offset)
01199       memmove (contents + ent->new_offset - sec->output_offset,
01200               contents + ent->offset - sec->output_offset, ent->size);
01201 
01202   for (ent = sec_info->entry; ent < sec_info->entry + sec_info->count; ++ent)
01203     {
01204       unsigned char *buf, *end;
01205       unsigned int new_size;
01206 
01207       if (ent->removed)
01208        continue;
01209 
01210       if (ent->size == 4)
01211        {
01212          /* Any terminating FDE must be at the end of the section.  */
01213          BFD_ASSERT (ent == sec_info->entry + sec_info->count - 1);
01214          continue;
01215        }
01216 
01217       buf = contents + ent->new_offset - sec->output_offset;
01218       end = buf + ent->size;
01219       new_size = size_of_output_cie_fde (ent, ptr_size);
01220 
01221       /* Update the size.  It may be shrinked.  */
01222       bfd_put_32 (abfd, new_size - 4, buf);
01223 
01224       /* Filling the extra bytes with DW_CFA_nops.  */
01225       if (new_size != ent->size)
01226        memset (end, 0, new_size - ent->size);
01227 
01228       if (ent->cie)
01229        {
01230          /* CIE */
01231          if (ent->make_relative
01232              || ent->need_lsda_relative
01233              || ent->per_encoding_relative)
01234            {
01235              char *aug;
01236              unsigned int action, extra_string, extra_data;
01237              unsigned int per_width, per_encoding;
01238 
01239              /* Need to find 'R' or 'L' augmentation's argument and modify
01240                DW_EH_PE_* value.  */
01241              action = ((ent->make_relative ? 1 : 0)
01242                      | (ent->need_lsda_relative ? 2 : 0)
01243                      | (ent->per_encoding_relative ? 4 : 0));
01244              extra_string = extra_augmentation_string_bytes (ent);
01245              extra_data = extra_augmentation_data_bytes (ent);
01246 
01247              /* Skip length, id and version.  */
01248              buf += 9;
01249              aug = (char *) buf;
01250              buf += strlen (aug) + 1;
01251              skip_leb128 (&buf, end);
01252              skip_leb128 (&buf, end);
01253              skip_leb128 (&buf, end);
01254              if (*aug == 'z')
01255               {
01256                 /* The uleb128 will always be a single byte for the kind
01257                    of augmentation strings that we're prepared to handle.  */
01258                 *buf++ += extra_data;
01259                 aug++;
01260               }
01261 
01262              /* Make room for the new augmentation string and data bytes.  */
01263              memmove (buf + extra_string + extra_data, buf, end - buf);
01264              memmove (aug + extra_string, aug, buf - (bfd_byte *) aug);
01265              buf += extra_string;
01266              end += extra_string + extra_data;
01267 
01268              if (ent->add_augmentation_size)
01269               {
01270                 *aug++ = 'z';
01271                 *buf++ = extra_data - 1;
01272               }
01273              if (ent->add_fde_encoding)
01274               {
01275                 BFD_ASSERT (action & 1);
01276                 *aug++ = 'R';
01277                 *buf++ = DW_EH_PE_pcrel;
01278                 action &= ~1;
01279               }
01280 
01281              while (action)
01282               switch (*aug++)
01283                 {
01284                 case 'L':
01285                   if (action & 2)
01286                     {
01287                      BFD_ASSERT (*buf == ent->lsda_encoding);
01288                      *buf |= DW_EH_PE_pcrel;
01289                      action &= ~2;
01290                     }
01291                   buf++;
01292                   break;
01293                 case 'P':
01294                   per_encoding = *buf++;
01295                   per_width = get_DW_EH_PE_width (per_encoding, ptr_size);
01296                   BFD_ASSERT (per_width != 0);
01297                   BFD_ASSERT (((per_encoding & 0x70) == DW_EH_PE_pcrel)
01298                             == ent->per_encoding_relative);
01299                   if ((per_encoding & 0xf0) == DW_EH_PE_aligned)
01300                     buf = (contents
01301                           + ((buf - contents + per_width - 1)
01302                             & ~((bfd_size_type) per_width - 1)));
01303                   if (action & 4)
01304                     {
01305                      bfd_vma val;
01306 
01307                      val = read_value (abfd, buf, per_width,
01308                                      get_DW_EH_PE_signed (per_encoding));
01309                      val += ent->offset - ent->new_offset;
01310                      val -= extra_string + extra_data;
01311                      write_value (abfd, buf, val, per_width);
01312                      action &= ~4;
01313                     }
01314                   buf += per_width;
01315                   break;
01316                 case 'R':
01317                   if (action & 1)
01318                     {
01319                      BFD_ASSERT (*buf == ent->fde_encoding);
01320                      *buf |= DW_EH_PE_pcrel;
01321                      action &= ~1;
01322                     }
01323                   buf++;
01324                   break;
01325                 case 'S':
01326                   break;
01327                 default:
01328                   BFD_FAIL ();
01329                 }
01330            }
01331        }
01332       else
01333        {
01334          /* FDE */
01335          bfd_vma value, address;
01336          unsigned int width;
01337          bfd_byte *start;
01338 
01339          /* Skip length.  */
01340          buf += 4;
01341          value = ent->new_offset + 4 - ent->cie_inf->new_offset;
01342          bfd_put_32 (abfd, value, buf);
01343          buf += 4;
01344          width = get_DW_EH_PE_width (ent->fde_encoding, ptr_size);
01345          value = read_value (abfd, buf, width,
01346                            get_DW_EH_PE_signed (ent->fde_encoding));
01347          address = value;
01348          if (value)
01349            {
01350              switch (ent->fde_encoding & 0xf0)
01351               {
01352               case DW_EH_PE_indirect:
01353               case DW_EH_PE_textrel:
01354                 BFD_ASSERT (hdr_info == NULL);
01355                 break;
01356               case DW_EH_PE_datarel:
01357                 {
01358                   asection *got = bfd_get_section_by_name (abfd, ".got");
01359 
01360                   BFD_ASSERT (got != NULL);
01361                   address += got->vma;
01362                 }
01363                 break;
01364               case DW_EH_PE_pcrel:
01365                 value += ent->offset - ent->new_offset;
01366                 address += sec->output_section->vma + ent->offset + 8;
01367                 break;
01368               }
01369              if (ent->cie_inf->make_relative)
01370               value -= sec->output_section->vma + ent->new_offset + 8;
01371              write_value (abfd, buf, value, width);
01372            }
01373 
01374          start = buf;
01375 
01376          if (hdr_info)
01377            {
01378              hdr_info->array[hdr_info->array_count].initial_loc = address;
01379              hdr_info->array[hdr_info->array_count++].fde
01380               = sec->output_section->vma + ent->new_offset;
01381            }
01382 
01383          if ((ent->lsda_encoding & 0xf0) == DW_EH_PE_pcrel
01384              || ent->cie_inf->need_lsda_relative)
01385            {
01386              buf += ent->lsda_offset;
01387              width = get_DW_EH_PE_width (ent->lsda_encoding, ptr_size);
01388              value = read_value (abfd, buf, width,
01389                               get_DW_EH_PE_signed (ent->lsda_encoding));
01390              if (value)
01391               {
01392                 if ((ent->lsda_encoding & 0xf0) == DW_EH_PE_pcrel)
01393                   value += ent->offset - ent->new_offset;
01394                 else if (ent->cie_inf->need_lsda_relative)
01395                   value -= (sec->output_section->vma + ent->new_offset + 8
01396                            + ent->lsda_offset);
01397                 write_value (abfd, buf, value, width);
01398               }
01399            }
01400          else if (ent->cie_inf->add_augmentation_size)
01401            {
01402              /* Skip the PC and length and insert a zero byte for the
01403                augmentation size.  */
01404              buf += width * 2;
01405              memmove (buf + 1, buf, end - buf);
01406              *buf = 0;
01407            }
01408 
01409          if (ent->set_loc)
01410            {
01411              /* Adjust DW_CFA_set_loc.  */
01412              unsigned int cnt, width;
01413              bfd_vma new_offset;
01414 
01415              width = get_DW_EH_PE_width (ent->fde_encoding, ptr_size);
01416              new_offset = ent->new_offset + 8
01417                         + extra_augmentation_string_bytes (ent)
01418                         + extra_augmentation_data_bytes (ent);
01419 
01420              for (cnt = 1; cnt <= ent->set_loc[0]; cnt++)
01421               {
01422                 bfd_vma value;
01423                 buf = start + ent->set_loc[cnt];
01424 
01425                 value = read_value (abfd, buf, width,
01426                                   get_DW_EH_PE_signed (ent->fde_encoding));
01427                 if (!value)
01428                   continue;
01429 
01430                 if ((ent->fde_encoding & 0xf0) == DW_EH_PE_pcrel)
01431                   value += ent->offset + 8 - new_offset;
01432                 if (ent->cie_inf->make_relative)
01433                   value -= sec->output_section->vma + new_offset
01434                           + ent->set_loc[cnt];
01435                 write_value (abfd, buf, value, width);
01436               }
01437            }
01438        }
01439     }
01440 
01441   /* We don't align the section to its section alignment since the
01442      runtime library only expects all CIE/FDE records aligned at
01443      the pointer size. _bfd_elf_discard_section_eh_frame should 
01444      have padded CIE/FDE records to multiple of pointer size with
01445      size_of_output_cie_fde.  */
01446   if ((sec->size % ptr_size) != 0)
01447     abort ();
01448 
01449   return bfd_set_section_contents (abfd, sec->output_section,
01450                                contents, (file_ptr) sec->output_offset,
01451                                sec->size);
01452 }
01453 
01454 /* Helper function used to sort .eh_frame_hdr search table by increasing
01455    VMA of FDE initial location.  */
01456 
01457 static int
01458 vma_compare (const void *a, const void *b)
01459 {
01460   const struct eh_frame_array_ent *p = a;
01461   const struct eh_frame_array_ent *q = b;
01462   if (p->initial_loc > q->initial_loc)
01463     return 1;
01464   if (p->initial_loc < q->initial_loc)
01465     return -1;
01466   return 0;
01467 }
01468 
01469 /* Write out .eh_frame_hdr section.  This must be called after
01470    _bfd_elf_write_section_eh_frame has been called on all input
01471    .eh_frame sections.
01472    .eh_frame_hdr format:
01473    ubyte version            (currently 1)
01474    ubyte eh_frame_ptr_enc   (DW_EH_PE_* encoding of pointer to start of
01475                              .eh_frame section)
01476    ubyte fde_count_enc             (DW_EH_PE_* encoding of total FDE count
01477                              number (or DW_EH_PE_omit if there is no
01478                              binary search table computed))
01479    ubyte table_enc          (DW_EH_PE_* encoding of binary search table,
01480                              or DW_EH_PE_omit if not present.
01481                              DW_EH_PE_datarel is using address of
01482                              .eh_frame_hdr section start as base)
01483    [encoded] eh_frame_ptr   (pointer to start of .eh_frame section)
01484    optionally followed by:
01485    [encoded] fde_count             (total number of FDEs in .eh_frame section)
01486    fde_count x [encoded] initial_loc, fde
01487                             (array of encoded pairs containing
01488                              FDE initial_location field and FDE address,
01489                              sorted by increasing initial_loc).  */
01490 
01491 bfd_boolean
01492 _bfd_elf_write_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
01493 {
01494   struct elf_link_hash_table *htab;
01495   struct eh_frame_hdr_info *hdr_info;
01496   asection *sec;
01497   bfd_byte *contents;
01498   asection *eh_frame_sec;
01499   bfd_size_type size;
01500   bfd_boolean retval;
01501   bfd_vma encoded_eh_frame;
01502 
01503   htab = elf_hash_table (info);
01504   hdr_info = &htab->eh_info;
01505   sec = hdr_info->hdr_sec;
01506   if (sec == NULL)
01507     return TRUE;
01508 
01509   size = EH_FRAME_HDR_SIZE;
01510   if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
01511     size += 4 + hdr_info->fde_count * 8;
01512   contents = bfd_malloc (size);
01513   if (contents == NULL)
01514     return FALSE;
01515 
01516   eh_frame_sec = bfd_get_section_by_name (abfd, ".eh_frame");
01517   if (eh_frame_sec == NULL)
01518     {
01519       free (contents);
01520       return FALSE;
01521     }
01522 
01523   memset (contents, 0, EH_FRAME_HDR_SIZE);
01524   contents[0] = 1;                        /* Version.  */
01525   contents[1] = get_elf_backend_data (abfd)->elf_backend_encode_eh_address
01526     (abfd, info, eh_frame_sec, 0, sec, 4,
01527      &encoded_eh_frame);                  /* .eh_frame offset.  */
01528 
01529   if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
01530     {
01531       contents[2] = DW_EH_PE_udata4;             /* FDE count encoding.  */
01532       contents[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4; /* Search table enc.  */
01533     }
01534   else
01535     {
01536       contents[2] = DW_EH_PE_omit;
01537       contents[3] = DW_EH_PE_omit;
01538     }
01539   bfd_put_32 (abfd, encoded_eh_frame, contents + 4);
01540 
01541   if (contents[2] != DW_EH_PE_omit)
01542     {
01543       unsigned int i;
01544 
01545       bfd_put_32 (abfd, hdr_info->fde_count, contents + EH_FRAME_HDR_SIZE);
01546       qsort (hdr_info->array, hdr_info->fde_count, sizeof (*hdr_info->array),
01547             vma_compare);
01548       for (i = 0; i < hdr_info->fde_count; i++)
01549        {
01550          bfd_put_32 (abfd,
01551                     hdr_info->array[i].initial_loc
01552                     - sec->output_section->vma,
01553                     contents + EH_FRAME_HDR_SIZE + i * 8 + 4);
01554          bfd_put_32 (abfd,
01555                     hdr_info->array[i].fde - sec->output_section->vma,
01556                     contents + EH_FRAME_HDR_SIZE + i * 8 + 8);
01557        }
01558     }
01559 
01560   retval = bfd_set_section_contents (abfd, sec->output_section,
01561                                  contents, (file_ptr) sec->output_offset,
01562                                  sec->size);
01563   free (contents);
01564   return retval;
01565 }
01566 
01567 /* Return the width of FDE addresses.  This is the default implementation.  */
01568 
01569 unsigned int
01570 _bfd_elf_eh_frame_address_size (bfd *abfd, asection *sec ATTRIBUTE_UNUSED)
01571 {
01572   return elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64 ? 8 : 4;
01573 }
01574 
01575 /* Decide whether we can use a PC-relative encoding within the given
01576    EH frame section.  This is the default implementation.  */
01577 
01578 bfd_boolean
01579 _bfd_elf_can_make_relative (bfd *input_bfd ATTRIBUTE_UNUSED,
01580                          struct bfd_link_info *info ATTRIBUTE_UNUSED,
01581                          asection *eh_frame_section ATTRIBUTE_UNUSED)
01582 {
01583   return TRUE;
01584 }
01585 
01586 /* Select an encoding for the given address.  Preference is given to
01587    PC-relative addressing modes.  */
01588 
01589 bfd_byte
01590 _bfd_elf_encode_eh_address (bfd *abfd ATTRIBUTE_UNUSED,
01591                          struct bfd_link_info *info ATTRIBUTE_UNUSED,
01592                          asection *osec, bfd_vma offset,
01593                          asection *loc_sec, bfd_vma loc_offset,
01594                          bfd_vma *encoded)
01595 {
01596   *encoded = osec->vma + offset -
01597     (loc_sec->output_section->vma + loc_sec->output_offset + loc_offset);
01598   return DW_EH_PE_pcrel | DW_EH_PE_sdata4;
01599 }