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 Fri, Oct 08, 2004 at 11:39:53PM +0930, Alan Modra wrote:
> On Fri, Oct 08, 2004 at 01:58:03PM +0100, Richard Sandiford wrote:
> > need_lsda_relative is only set for FDEs and never for CIEs.
> 
> Blagh.  I was just about to go to bed.  Silly mistake on my part, but
> will require more than just a one-liner to fix.  I'll need to write
> some code that trundles through the struct eh_cie_fde info and ties
> together fdes and cies.  Tomorrow.

Like this.  Untested.  I'll commit tomorrow after some testing.

Index: bfd/elf-eh-frame.c
===================================================================
RCS file: /cvs/src/src/bfd/elf-eh-frame.c,v
retrieving revision 1.32
diff -u -p -r1.32 elf-eh-frame.c
--- bfd/elf-eh-frame.c	1 Oct 2004 00:51:37 -0000	1.32
+++ bfd/elf-eh-frame.c	8 Oct 2004 14:31:41 -0000
@@ -812,6 +812,7 @@ _bfd_elf_write_section_eh_frame (bfd *ab
   unsigned int leb128_tmp;
   unsigned int cie_offset = 0;
   unsigned int ptr_size;
+  unsigned int last_cie_ndx;
 
   ptr_size = (elf_elfheader (sec->owner)->e_ident[EI_CLASS]
 	      == ELFCLASS64) ? 8 : 4;
@@ -828,6 +829,41 @@ _bfd_elf_write_section_eh_frame (bfd *ab
   if (hdr_info->array == NULL)
     hdr_info = NULL;
 
+  /* Copy FDE's need_* flags to CIE.  */
+  last_cie_ndx = (unsigned) -1;
+  for (i = 0; i < sec_info->count; ++i)
+    {
+      if (sec_info->entry[i].removed)
+	continue;
+      if (sec_info->entry[i].cie)
+	last_cie_ndx = i;
+      else if (sec_info->entry[i].size > 4)
+	{
+	  BFD_ASSERT (last_cie_ndx != (unsigned) -1);
+	  sec_info->entry[last_cie_ndx].need_relative
+	    |= sec_info->entry[i].need_relative;
+	  sec_info->entry[last_cie_ndx].need_lsda_relative
+	    |= sec_info->entry[i].need_lsda_relative;
+	}
+    }
+  /* And now from CIE to FDEs.  */
+  last_cie_ndx = (unsigned) -1;
+  for (i = 0; i < sec_info->count; ++i)
+    {
+      if (sec_info->entry[i].removed)
+	continue;
+      if (sec_info->entry[i].cie)
+	last_cie_ndx = i;
+      else if (sec_info->entry[i].size > 4)
+	{
+	  BFD_ASSERT (last_cie_ndx != (unsigned) -1);
+	  sec_info->entry[i].need_relative
+	    |= sec_info->entry[last_cie_ndx].need_relative;
+	  sec_info->entry[i].need_lsda_relative
+	    |= sec_info->entry[last_cie_ndx].need_lsda_relative;
+	}
+    }
+
   p = contents;
   for (i = 0; i < sec_info->count; ++i)
     {

-- 
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]