merge from gcc
[deliverable/binutils-gdb.git] / bfd / elf-eh-frame.c
index 8938ecf32dc3042d7ef8a21b5ee954337cf2b40c..77640748da9944f9352977050cb6f56e4f261ab6 100644 (file)
@@ -1,5 +1,5 @@
 /* .eh_frame section optimization.
-   Copyright 2001, 2002 Free Software Foundation, Inc.
+   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
    Written by Jakub Jelinek <jakub@redhat.com>.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -33,7 +33,7 @@ static bfd_signed_vma read_signed_leb128
 static int get_DW_EH_PE_width
   PARAMS ((int, int));
 static bfd_vma read_value
-  PARAMS ((bfd *, bfd_byte *, int));
+  PARAMS ((bfd *, bfd_byte *, int, int));
 static void write_value
   PARAMS ((bfd *, bfd_byte *, bfd_vma, int));
 static int cie_compare
@@ -141,27 +141,47 @@ int get_DW_EH_PE_width (encoding, ptr_size)
   return 0;
 }
 
+#define get_DW_EH_PE_signed(encoding) (((encoding) & DW_EH_PE_signed) != 0)
+
 /* Read a width sized value from memory.  */
 
 static bfd_vma
-read_value (abfd, buf, width)
+read_value (abfd, buf, width, is_signed)
      bfd *abfd;
      bfd_byte *buf;
      int width;
+     int is_signed;
 {
   bfd_vma value;
 
   switch (width)
     {
-    case 2: value = bfd_get_16 (abfd, buf); break;
-    case 4: value = bfd_get_32 (abfd, buf); break;
-    case 8: value = bfd_get_64 (abfd, buf); break;
-    default: BFD_FAIL (); return 0;
+    case 2:
+      if (is_signed)
+       value = bfd_get_signed_16 (abfd, buf);
+      else
+       value = bfd_get_16 (abfd, buf);
+      break;
+    case 4:
+      if (is_signed)
+       value = bfd_get_signed_32 (abfd, buf);
+      else
+       value = bfd_get_32 (abfd, buf);
+      break;
+    case 8:
+      if (is_signed)
+       value = bfd_get_signed_64 (abfd, buf);
+      else
+       value = bfd_get_64 (abfd, buf);
+      break;
+    default:
+      BFD_FAIL ();
+      return 0;
     }
 
   return value;
 }
-    
+
 /* Store a width sized value to memory.  */
 
 static void
@@ -210,16 +230,16 @@ int cie_compare (c1, c2)
 
 /* This function is called for each input file before the .eh_frame
    section is relocated.  It discards duplicate CIEs and FDEs for discarded
-   functions.  The function returns true iff any entries have been
+   functions.  The function returns TRUE iff any entries have been
    deleted.  */
 
-boolean
+bfd_boolean
 _bfd_elf_discard_section_eh_frame (abfd, info, sec,
                                   reloc_symbol_deleted_p, cookie)
      bfd *abfd;
      struct bfd_link_info *info;
      asection *sec;
-     boolean (*reloc_symbol_deleted_p) PARAMS ((bfd_vma, PTR));
+     bfd_boolean (*reloc_symbol_deleted_p) PARAMS ((bfd_vma, PTR));
      struct elf_reloc_cookie *cookie;
 {
   bfd_byte *ehbuf = NULL, *buf;
@@ -238,7 +258,7 @@ _bfd_elf_discard_section_eh_frame (abfd, info, sec,
   if (sec->_raw_size == 0)
     {
       /* This file does not contain .eh_frame information.  */
-      return false;
+      return FALSE;
     }
 
   if ((sec->output_section != NULL
@@ -246,7 +266,7 @@ _bfd_elf_discard_section_eh_frame (abfd, info, sec,
     {
       /* At least one of the sections is being discarded from the
          link, so we should just ignore them.  */
-      return false;
+      return FALSE;
     }
 
   htab = elf_hash_table (info);
@@ -268,7 +288,7 @@ _bfd_elf_discard_section_eh_frame (abfd, info, sec,
     {
       /* Empty .eh_frame section.  */
       free (ehbuf);
-      return false;
+      return FALSE;
     }
 
   /* If .eh_frame section size doesn't fit into int, we cannot handle
@@ -578,7 +598,7 @@ _bfd_elf_discard_section_eh_frame (abfd, info, sec,
                     which we cannot turn into PC relative,
                     don't create the binary search table,
                     since it is affected by runtime relocations.  */
-                 hdr_info->table = false;
+                 hdr_info->table = FALSE;
                }
              cie_usage_count++;
              hdr_info->fde_count++;
@@ -605,7 +625,7 @@ _bfd_elf_discard_section_eh_frame (abfd, info, sec,
     }
 
   elf_section_data (sec)->sec_info = sec_info;
-  elf_section_data (sec)->sec_info_type = ELF_INFO_TYPE_EH_FRAME;
+  sec->sec_info_type = ELF_INFO_TYPE_EH_FRAME;
 
   /* Ok, now we can assign new offsets.  */
   offset = 0;
@@ -663,16 +683,16 @@ free_no_table:
     free (ehbuf);
   if (sec_info)
     free (sec_info);
-  hdr_info->table = false;
+  hdr_info->table = FALSE;
   hdr_info->last_cie.hdr.length = 0;
-  return false;
+  return FALSE;
 }
 
 /* This function is called for .eh_frame_hdr section after
    _bfd_elf_discard_section_eh_frame has been called on all .eh_frame
    input sections.  It finalizes the size of .eh_frame_hdr section.  */
 
-boolean
+bfd_boolean
 _bfd_elf_discard_section_eh_frame_hdr (abfd, info)
      bfd *abfd;
      struct bfd_link_info *info;
@@ -685,7 +705,7 @@ _bfd_elf_discard_section_eh_frame_hdr (abfd, info)
   hdr_info = &htab->eh_info;
   sec = hdr_info->hdr_sec;
   if (sec == NULL)
-    return false;
+    return FALSE;
 
   sec->_cooked_size = EH_FRAME_HDR_SIZE;
   if (hdr_info->table)
@@ -694,7 +714,7 @@ _bfd_elf_discard_section_eh_frame_hdr (abfd, info)
   /* Request program headers to be recalculated.  */
   elf_tdata (abfd)->program_header_size = 0;
   elf_tdata (abfd)->eh_frame_hdr = sec;
-  return true;
+  return TRUE;
 }
 
 /* This function is called from size_dynamic_sections.
@@ -702,7 +722,7 @@ _bfd_elf_discard_section_eh_frame_hdr (abfd, info)
    because later on it is too late for calling _bfd_strip_section_from_output,
    since dynamic symbol table has been sized.  */
 
-boolean
+bfd_boolean
 _bfd_elf_maybe_strip_eh_frame_hdr (info)
      struct bfd_link_info *info;
 {
@@ -714,12 +734,12 @@ _bfd_elf_maybe_strip_eh_frame_hdr (info)
   htab = elf_hash_table (info);
   hdr_info = &htab->eh_info;
   if (hdr_info->hdr_sec == NULL)
-    return true;
+    return TRUE;
 
   if (bfd_is_abs_section (hdr_info->hdr_sec->output_section))
     {
       hdr_info->hdr_sec = NULL;
-      return true;
+      return TRUE;
     }
 
   abfd = NULL;
@@ -737,11 +757,11 @@ _bfd_elf_maybe_strip_eh_frame_hdr (info)
     {
       _bfd_strip_section_from_output (info, hdr_info->hdr_sec);
       hdr_info->hdr_sec = NULL;
-      return true;
+      return TRUE;
     }
 
-  hdr_info->table = true;
-  return true;
+  hdr_info->table = TRUE;
+  return TRUE;
 }
 
 /* Adjust an address in the .eh_frame section.  Given OFFSET within
@@ -758,7 +778,7 @@ _bfd_elf_eh_frame_section_offset (output_bfd, sec, offset)
   struct eh_frame_sec_info *sec_info;
   unsigned int lo, hi, mid;
 
-  if (elf_section_data (sec)->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
+  if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
     return offset;
   sec_info = (struct eh_frame_sec_info *)
             elf_section_data (sec)->sec_info;
@@ -809,7 +829,7 @@ _bfd_elf_eh_frame_section_offset (output_bfd, sec, offset)
 /* Write out .eh_frame section.  This is called with the relocated
    contents.  */
 
-boolean
+bfd_boolean
 _bfd_elf_write_section_eh_frame (abfd, info, sec, contents)
      bfd *abfd;
      struct bfd_link_info *info;
@@ -828,7 +848,7 @@ _bfd_elf_write_section_eh_frame (abfd, info, sec, contents)
   ptr_size = (elf_elfheader (sec->owner)->e_ident[EI_CLASS]
              == ELFCLASS64) ? 8 : 4;
 
-  if (elf_section_data (sec)->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
+  if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
     return bfd_set_section_contents (abfd, sec->output_section,
                                     contents,
                                     (file_ptr) sec->output_offset,
@@ -925,7 +945,9 @@ _bfd_elf_write_section_eh_frame (abfd, info, sec, contents)
                      {
                        bfd_vma value;
 
-                       value = read_value (abfd, buf, per_width);
+                       value = read_value (abfd, buf, per_width,
+                                           get_DW_EH_PE_signed
+                                           (per_encoding));
                        value += (sec_info->entry[i].offset
                                  - sec_info->entry[i].new_offset);
                        write_value (abfd, buf, value, per_width);
@@ -954,14 +976,16 @@ _bfd_elf_write_section_eh_frame (abfd, info, sec, contents)
          unsigned int width;
 
          buf = contents + sec_info->entry[i].offset;
-         /* Skip length.  */   
+         /* Skip length.  */
          buf += 4;
          bfd_put_32 (abfd,
                      sec_info->entry[i].new_offset + 4 - cie_offset, buf);
          buf += 4;
          width = get_DW_EH_PE_width (sec_info->entry[i].fde_encoding,
                                      ptr_size);
-         address = value = read_value (abfd, buf, width);
+         address = value = read_value (abfd, buf, width,
+                                       get_DW_EH_PE_signed
+                                       (sec_info->entry[i].fde_encoding));
          if (value)
            {
              switch (sec_info->entry[i].fde_encoding & 0xf0)
@@ -1005,7 +1029,9 @@ _bfd_elf_write_section_eh_frame (abfd, info, sec, contents)
              buf += sec_info->entry[i].lsda_offset;
              width = get_DW_EH_PE_width (sec_info->entry[i].lsda_encoding,
                                          ptr_size);
-             value = read_value (abfd, buf, width);
+             value = read_value (abfd, buf, width,
+                                 get_DW_EH_PE_signed
+                                 (sec_info->entry[i].lsda_encoding));
              if (value)
                {
                  if ((sec_info->entry[i].lsda_encoding & 0xf0)
@@ -1088,7 +1114,7 @@ vma_compare (a, b)
                                 FDE initial_location field and FDE address,
                                 sorted by increasing initial_loc)  */
 
-boolean
+bfd_boolean
 _bfd_elf_write_section_eh_frame_hdr (abfd, info)
      bfd *abfd;
      struct bfd_link_info *info;
@@ -1104,18 +1130,18 @@ _bfd_elf_write_section_eh_frame_hdr (abfd, info)
   hdr_info = &htab->eh_info;
   sec = hdr_info->hdr_sec;
   if (sec == NULL)
-    return true;
+    return TRUE;
 
   size = EH_FRAME_HDR_SIZE;
   if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
     size += 4 + hdr_info->fde_count * 8;
   contents = bfd_malloc (size);
   if (contents == NULL)
-    return false;
+    return FALSE;
 
   eh_frame_sec = bfd_get_section_by_name (abfd, ".eh_frame");
   if (eh_frame_sec == NULL)
-    return false;
+    return FALSE;
 
   memset (contents, 0, EH_FRAME_HDR_SIZE);
   contents[0] = 1;                             /* Version  */
This page took 0.030909 seconds and 4 git commands to generate.