* arm-tdep.c (arm_frameless_function_invocation)
[deliverable/binutils-gdb.git] / bfd / elf-eh-frame.c
index 2436c17e37dfc44197b76f3f1b48e90384f22a1b..b479c00f3233886ffb3aab0ab74c0217dc26abf4 100644 (file)
@@ -1,5 +1,5 @@
 /* .eh_frame section optimization.
-   Copyright 2001 Free Software Foundation, Inc.
+   Copyright 2001, 2002 Free Software Foundation, Inc.
    Written by Jakub Jelinek <jakub@redhat.com>.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -701,8 +701,12 @@ _bfd_elf_discard_section_eh_frame (abfd, info, sec, ehdrsec,
       hdr_info->last_cie_offset = sec_info->entry[last_cie_ndx].new_offset;
     }
 
+  /* FIXME: Currently it is not possible to shrink sections to zero size at
+     this point, so build a fake minimal CIE.  */
+  if (new_size == 0)
+    new_size = 16;
+
   /* Shrink the sec as needed.  */
-  
   sec->_cooked_size = new_size;
   if (sec->_cooked_size == 0)
     sec->flags |= SEC_EXCLUDE;
@@ -863,8 +867,8 @@ _bfd_elf_eh_frame_section_offset (output_bfd, sec, offset)
              + sec_info->entry[mid].lsda_offset)))
     return (bfd_vma) -1;
 
-  return (offset
-         + (sec_info->entry[mid].new_offset - sec_info->entry[mid].offset));
+  return (offset + sec_info->entry[mid].new_offset
+         - sec_info->entry[mid].offset);
 }
 
 /* Write out .eh_frame section.  This is called with the relocated
@@ -915,14 +919,23 @@ _bfd_elf_write_section_eh_frame (abfd, sec, ehdrsec, contents)
        {
          if (sec_info->entry[i].cie)
            {
-             cie_offset = sec_info->entry[i].new_offset;
-             cie_offset += (sec_info->entry[i].sec->output_section->vma
-                            + sec_info->entry[i].sec->output_offset
-                            - sec->output_section->vma
-                            - sec->output_offset);
+             /* If CIE is removed due to no remaining FDEs referencing it
+                and there were no CIEs kept before it, sec_info->entry[i].sec
+                will be zero.  */
+             if (sec_info->entry[i].sec == NULL)
+               cie_offset = 0;
+             else
+               {
+                 cie_offset = sec_info->entry[i].new_offset;
+                 cie_offset += (sec_info->entry[i].sec->output_section->vma
+                                + sec_info->entry[i].sec->output_offset
+                                - sec->output_section->vma
+                                - sec->output_offset);
+               }
            }
          continue;
        }
+
       if (sec_info->entry[i].cie)
        {
          /* CIE */
@@ -1069,6 +1082,18 @@ _bfd_elf_write_section_eh_frame (abfd, sec, ehdrsec, contents)
       p += sec_info->entry[i].size;
     }
 
+  /* FIXME: Once _bfd_elf_discard_section_eh_frame will be able to
+     shrink sections to zero size, this won't be needed any more.  */
+  if (p == contents && sec->_cooked_size == 16)
+    {
+      bfd_put_32 (abfd, 12, p);                /* Fake CIE length */
+      bfd_put_32 (abfd, 0, p + 4);     /* Fake CIE id */
+      p[8] = 1;                                /* Fake CIE version */
+      memset (p + 9, 0, 7);            /* Fake CIE augmentation, 3xleb128
+                                          and 3xDW_CFA_nop as pad  */
+      p += 16;
+    }
+
   BFD_ASSERT ((bfd_size_type) (p - contents) == sec->_cooked_size);
 
   return bfd_set_section_contents (abfd, sec->output_section,
@@ -1133,6 +1158,9 @@ _bfd_elf_write_section_eh_frame_hdr (abfd, sec)
              == ELF_INFO_TYPE_EH_FRAME_HDR);
   hdr_info = (struct eh_frame_hdr_info *)
             elf_section_data (sec)->sec_info;
+  if (hdr_info->strip)
+    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;
This page took 0.026018 seconds and 4 git commands to generate.