PR22374 testcase, function pointer references in .data
[deliverable/binutils-gdb.git] / bfd / elf-eh-frame.c
index 1af6f30908313603b372c43d6be0626481040225..cd81b608d35befeeb10b1bd7a3ff03092a9eca24 100644 (file)
@@ -326,9 +326,9 @@ size_of_output_cie_fde (struct eh_cie_fde *entry)
 /* Return the offset of the FDE or CIE after ENT.  */
 
 static unsigned int
-next_cie_fde_offset (struct eh_cie_fde *ent,
-                    struct eh_cie_fde *last,
-                    asection *sec)
+next_cie_fde_offset (const struct eh_cie_fde *ent,
+                    const struct eh_cie_fde *last,
+                    const asection *sec)
 {
   while (++ent < last)
     {
@@ -619,15 +619,6 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
 
   REQUIRE (bfd_malloc_and_get_section (abfd, sec, &ehbuf));
 
-  if (sec->size >= 4
-      && bfd_get_32 (abfd, ehbuf) == 0
-      && cookie->rel == cookie->relend)
-    {
-      /* Empty .eh_frame section.  */
-      free (ehbuf);
-      return;
-    }
-
   /* If .eh_frame section size doesn't fit into int, we cannot handle
      it (it would need to use 64-bit .eh_frame format anyway).  */
   REQUIRE (sec->size == (unsigned int) sec->size);
@@ -669,8 +660,11 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
   REQUIRE (sec_info);
 
   /* We need to have a "struct cie" for each CIE in this section.  */
-  local_cies = (struct cie *) bfd_zmalloc (num_cies * sizeof (*local_cies));
-  REQUIRE (local_cies);
+  if (num_cies)
+    {
+      local_cies = (struct cie *) bfd_zmalloc (num_cies * sizeof (*local_cies));
+      REQUIRE (local_cies);
+    }
 
   /* FIXME: octets_per_byte.  */
 #define ENSURE_NO_RELOCS(buf)                          \
@@ -724,7 +718,9 @@ _bfd_elf_parse_eh_frame (bfd *abfd, struct bfd_link_info *info,
       if (hdr_length == 0)
        {
          /* A zero-length CIE should only be found at the end of
-            the section.  */
+            the section, but allow multiple terminators.  */
+         while (skip_bytes (&buf, ehbuf + sec->size, 4))
+           REQUIRE (bfd_get_32 (abfd, buf - 4) == 0);
          REQUIRE ((bfd_size_type) (buf - ehbuf) == sec->size);
          ENSURE_NO_RELOCS (buf);
          sec_info->count++;
@@ -1334,12 +1330,12 @@ find_merged_cie (bfd *abfd, struct bfd_link_info *info, asection *sec,
    after .eh_frame editing.  */
 
 static bfd_signed_vma
-offset_adjust (bfd_vma offset, asection *sec)
+offset_adjust (bfd_vma offset, const asection *sec)
 {
   struct eh_frame_sec_info *sec_info
     = (struct eh_frame_sec_info *) elf_section_data (sec)->sec_info;
   unsigned int lo, hi, mid;
-  struct eh_cie_fde *ent;
+  struct eh_cie_fde *ent = NULL;
   bfd_signed_vma delta;
 
   lo = 0;
@@ -1442,7 +1438,7 @@ _bfd_elf_adjust_eh_frame_global_symbol (struct elf_link_hash_entry *h,
    if any symbol was changed.  */
 
 static int
-adjust_eh_frame_local_symbols (asection *sec,
+adjust_eh_frame_local_symbols (const asection *sec,
                               struct elf_reloc_cookie *cookie)
 {
   unsigned int shndx;
@@ -1594,16 +1590,7 @@ _bfd_elf_discard_section_eh_frame
        offset += size_of_output_cie_fde (ent);
       }
 
-  /* Pad the last FDE out to the output section alignment if there are
-     following sections, in order to ensure no padding between this
-     section and the next.  (Relies on the output section alignment
-     being the maximum of all input sections alignments, which is the
-     case unless someone is overriding alignment via scripts.)  */
   eh_alignment = 4;
-  if (sec->map_head.s != NULL
-      && (sec->map_head.s->size != 4
-         || sec->map_head.s->map_head.s != NULL))
-    eh_alignment = 1 << sec->output_section->alignment_power;
   offset = (offset + eh_alignment - 1) & -eh_alignment;
   sec->rawsize = sec->size;
   sec->size = offset;
@@ -2546,7 +2533,7 @@ _bfd_elf_write_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
 /* Return the width of FDE addresses.  This is the default implementation.  */
 
 unsigned int
-_bfd_elf_eh_frame_address_size (bfd *abfd, asection *sec ATTRIBUTE_UNUSED)
+_bfd_elf_eh_frame_address_size (bfd *abfd, const asection *sec ATTRIBUTE_UNUSED)
 {
   return elf_elfheader (abfd)->e_ident[EI_CLASS] == ELFCLASS64 ? 8 : 4;
 }
This page took 0.024297 seconds and 4 git commands to generate.