This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PR ld/12253 DW_EH_PE_datarel


DW_EH_PE_datarel is quite horrible.  Not only is its behaviour
architecture dependent, it is also context sensitive.  When used in
.eh_frame_hdr, DW_EH_PE_datarel means relative to the .eh_frame_hdr
section.  Elsewhere it is relative to a base address chosen
differently on different architectures, and unspecified on most.  i386
defines the base as DT_PLTGOT, and frv as _GLOBAL_OFFSET_TABLE_ (see
gcc/unwind-dw2-fde-glibc.c).  These two happen to be identical.  ia64
defines the base as __gp.

Committed mainline, probably should go on branch too.  Tristan?

	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.

Index: bfd/elf-eh-frame.c
===================================================================
RCS file: /cvs/src/src/bfd/elf-eh-frame.c,v
retrieving revision 1.84
diff -u -p -r1.84 elf-eh-frame.c
--- bfd/elf-eh-frame.c	9 Apr 2010 14:40:15 -0000	1.84
+++ bfd/elf-eh-frame.c	23 Nov 2010 22:37:08 -0000
@@ -1572,10 +1572,31 @@ _bfd_elf_write_section_eh_frame (bfd *ab
 		  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 *ab
 
 	  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

-- 
Alan Modra
Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]