* elf64-ppc.c (ppc64_elf_relocate_section): Provide section/offset
[deliverable/binutils-gdb.git] / bfd / elf-eh-frame.c
index c948df27a3de5bc33e4f02f9bbe6e633170f368d..0a2213814743be0a25948e5d59e58903fc1006df 100644 (file)
@@ -1278,13 +1278,11 @@ _bfd_elf_maybe_strip_eh_frame_hdr (struct bfd_link_info *info)
 
 bfd_vma
 _bfd_elf_eh_frame_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED,
-                                 struct bfd_link_info *info,
+                                 struct bfd_link_info *info ATTRIBUTE_UNUSED,
                                  asection *sec,
                                  bfd_vma offset)
 {
   struct eh_frame_sec_info *sec_info;
-  struct elf_link_hash_table *htab;
-  struct eh_frame_hdr_info *hdr_info;
   unsigned int lo, hi, mid;
 
   if (sec->sec_info_type != ELF_INFO_TYPE_EH_FRAME)
@@ -1294,9 +1292,6 @@ _bfd_elf_eh_frame_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED,
   if (offset >= sec->rawsize)
     return offset - sec->rawsize + sec->size;
 
-  htab = elf_hash_table (info);
-  hdr_info = &htab->eh_info;
-
   lo = 0;
   hi = sec_info->count;
   mid = 0;
@@ -1577,10 +1572,31 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
                  break;
                case DW_EH_PE_datarel:
                  {
-                   asection *got = bfd_get_section_by_name (abfd, ".got");
-
-                   BFD_ASSERT (got != NULL);
-                   address += got->vma;
+                   switch (abfd->arch_info->arch)
+                     {
+                     case bfd_arch_ia64:
+                       BFD_ASSERT (elf_gp (abfd) != 0);
+                       address += elf_gp (abfd);
+                       break;
+                     default:
+                       (*info->callbacks->einfo)
+                         (_("%P: DW_EH_PE_datarel unspecified"
+                            " for this architecture.\n"));
+                       /* Fall thru */
+                     case bfd_arch_frv:
+                     case bfd_arch_i386:
+                       BFD_ASSERT (htab->hgot != NULL
+                                   && ((htab->hgot->root.type
+                                        == bfd_link_hash_defined)
+                                       || (htab->hgot->root.type
+                                           == bfd_link_hash_defweak)));
+                       address
+                         += (htab->hgot->root.u.def.value
+                             + htab->hgot->root.u.def.section->output_offset
+                             + (htab->hgot->root.u.def.section->output_section
+                                ->vma));
+                       break;
+                     }
                  }
                  break;
                case DW_EH_PE_pcrel:
@@ -1601,6 +1617,11 @@ _bfd_elf_write_section_eh_frame (bfd *abfd,
 
          if (hdr_info)
            {
+             /* The address calculation may overflow, giving us a
+                value greater than 4G on a 32-bit target when
+                dwarf_vma is 64-bit.  */
+             if (sizeof (address) > 4 && ptr_size == 4)
+               address &= 0xffffffff;
              hdr_info->array[hdr_info->array_count].initial_loc = address;
              hdr_info->array[hdr_info->array_count++].fde
                = (sec->output_section->vma
This page took 0.023503 seconds and 4 git commands to generate.