PR ld/12253
authorAlan Modra <amodra@gmail.com>
Tue, 23 Nov 2010 23:30:04 +0000 (23:30 +0000)
committerAlan Modra <amodra@gmail.com>
Tue, 23 Nov 2010 23:30:04 +0000 (23:30 +0000)
* elf-eh-frame.c (_bfd_elf_write_section_eh_frame): Correct
DW_EH_PE_datarel handling.  Truncate .eh_frame_hdr address to
ptr_size.

bfd/ChangeLog
bfd/elf-eh-frame.c

index 99ada02..357feb7 100644 (file)
@@ -1,3 +1,10 @@
+2010-11-24  Alan Modra  <amodra@gmail.com>
+
+       PR ld/12253
+       * elf-eh-frame.c (_bfd_elf_write_section_eh_frame): Correct
+       DW_EH_PE_datarel handling.  Truncate .eh_frame_hdr address to
+       ptr_size.
+
 2010-11-23  Mingming Sun  <mingm.sun@gmail.com>
 
        * elfxx-mips.c (mips_set_isa_flags): Move bfd_mach_loongson_3a
index 8380ef8..0a22138 100644 (file)
@@ -1572,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:
@@ -1596,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