This is the mail archive of the binutils@sources.redhat.com 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]

Re: Fix ld/418


On Wed, Oct 13, 2004 at 10:48:01PM +0100, Richard Sandiford wrote:
> Should _bfd_elf_eh_frame_section_offset be modified to cope with
> the adjusted offsets

Yes, that would be easiest I think.  I didn't consider that this
function might be called after writing eh_frame sections, which
means some extra checks are needed too.

Richard, this is the same as the patch I sent you privately yesterday.

	* elf-eh-frame.c (_bfd_elf_eh_frame_section_offset): Add "info"
	parameter.  If called after _bfd_elf_write_section_eh_frame,
	don't allow a -2 return unless need_* bit is already set, and
	handle offsets adjusted for output_offset.
	* elf-bfd.h (_bfd_elf_eh_frame_section_offset): Update prototype.
	* elf.c (_bfd_elf_section_offset): Update call.

Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.161
diff -u -p -r1.161 elf-bfd.h
--- bfd/elf-bfd.h	10 Oct 2004 13:02:00 -0000	1.161
+++ bfd/elf-bfd.h	14 Oct 2004 13:58:14 -0000
@@ -1532,7 +1532,7 @@ extern bfd_boolean _bfd_elf_discard_sect
 extern bfd_boolean _bfd_elf_discard_section_eh_frame_hdr
   (bfd *, struct bfd_link_info *);
 extern bfd_vma _bfd_elf_eh_frame_section_offset
-  (bfd *, asection *, bfd_vma);
+  (bfd *, struct bfd_link_info *, asection *, bfd_vma);
 extern bfd_boolean _bfd_elf_write_section_eh_frame
   (bfd *, struct bfd_link_info *, asection *, bfd_byte *);
 extern bfd_boolean _bfd_elf_write_section_eh_frame_hdr
Index: bfd/elf-eh-frame.c
===================================================================
RCS file: /cvs/src/src/bfd/elf-eh-frame.c,v
retrieving revision 1.34
diff -u -p -r1.34 elf-eh-frame.c
--- bfd/elf-eh-frame.c	10 Oct 2004 13:02:01 -0000	1.34
+++ bfd/elf-eh-frame.c	14 Oct 2004 13:58:15 -0000
@@ -713,10 +713,13 @@ _bfd_elf_maybe_strip_eh_frame_hdr (struc
 
 bfd_vma
 _bfd_elf_eh_frame_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED,
+				  struct bfd_link_info *info,
 				  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)
@@ -726,6 +729,11 @@ _bfd_elf_eh_frame_section_offset (bfd *o
   if (offset >= sec->rawsize)
     return offset - sec->rawsize + sec->size;
 
+  htab = elf_hash_table (info);
+  hdr_info = &htab->eh_info;
+  if (hdr_info->offsets_adjusted)
+    offset += sec->output_offset;
+
   lo = 0;
   hi = sec_info->count;
   mid = 0;
@@ -751,7 +759,9 @@ _bfd_elf_eh_frame_section_offset (bfd *o
      relocation against FDE's initial_location field.  */
   if (!sec_info->entry[mid].cie
       && sec_info->entry[mid].cie_inf->make_relative
-      && offset == sec_info->entry[mid].offset + 8)
+      && offset == sec_info->entry[mid].offset + 8
+      && (sec_info->entry[mid].cie_inf->need_relative
+	  || !hdr_info->offsets_adjusted))
     {
       sec_info->entry[mid].cie_inf->need_relative = 1;
       return (bfd_vma) -2;
@@ -762,12 +772,16 @@ _bfd_elf_eh_frame_section_offset (bfd *o
   if (!sec_info->entry[mid].cie
       && sec_info->entry[mid].cie_inf->make_lsda_relative
       && (offset == (sec_info->entry[mid].offset + 8
-		     + sec_info->entry[mid].lsda_offset)))
+		     + sec_info->entry[mid].lsda_offset))
+      && (sec_info->entry[mid].cie_inf->need_lsda_relative
+	  || !hdr_info->offsets_adjusted))
     {
       sec_info->entry[mid].cie_inf->need_lsda_relative = 1;
       return (bfd_vma) -2;
     }
 
+  if (hdr_info->offsets_adjusted)
+    offset -= sec->output_offset;
   return (offset + sec_info->entry[mid].new_offset
 	  - sec_info->entry[mid].offset);
 }
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.250
diff -u -p -r1.250 elf.c
--- bfd/elf.c	11 Oct 2004 13:48:36 -0000	1.250
+++ bfd/elf.c	14 Oct 2004 13:58:20 -0000
@@ -7746,7 +7746,7 @@ _bfd_elf_rel_local_sym (bfd *abfd,
 
 bfd_vma
 _bfd_elf_section_offset (bfd *abfd,
-			 struct bfd_link_info *info ATTRIBUTE_UNUSED,
+			 struct bfd_link_info *info,
 			 asection *sec,
 			 bfd_vma offset)
 {
@@ -7756,7 +7756,7 @@ _bfd_elf_section_offset (bfd *abfd,
       return _bfd_stab_section_offset (sec, elf_section_data (sec)->sec_info,
 				       offset);
     case ELF_INFO_TYPE_EH_FRAME:
-      return _bfd_elf_eh_frame_section_offset (abfd, sec, offset);
+      return _bfd_elf_eh_frame_section_offset (abfd, info, sec, offset);
     default:
       return offset;
     }

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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