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: gc sections and .eh_frame


On Wed, Jun 22, 2005 at 12:46:21PM +0100, Jonathan Larmour wrote:
> I think Alan maybe didn't notice his name being mentioned :). Alan, do you 
> have any guidance on the best approach?

None of the proposed solutions is right.  If you take a look at a
typical .eh_frame, you'll see relocs pointing at text sections and
.gcc_except_table (or .rodata for broken ppc compilers).  Changing
garbage collection to process .rela.eh_frame thus runs into the problem
of distinguishing the two types of reloc:  You need to ignore the
former, and mark sections for the latter.

Try the following totally untested patch.

	* elflink.c (_bfd_elf_gc_mark): Handle .eh_frame relocs specially..
	(bfd_elf_gc_sections): ..rather than totally ignoring .eh_frame.
	Don't recheck sections we have already marked.

--- bfd/elflink.c~	2005-06-16 12:18:15.000000000 +0930
+++ bfd/elflink.c	2005-06-26 02:17:09.464213143 +0930
@@ -8733,6 +8733,7 @@
 		  gc_mark_hook_fn gc_mark_hook)
 {
   bfd_boolean ret;
+  bfd_boolean is_eh;
   asection *group_sec;
 
   sec->gc_mark = 1;
@@ -8745,6 +8746,7 @@
 
   /* Look through the section relocs.  */
   ret = TRUE;
+  is_eh = strcmp (sec->name, ".eh_frame") == 0;
   if ((sec->flags & SEC_RELOC) != 0 && sec->reloc_count > 0)
     {
       Elf_Internal_Rela *relstart, *rel, *relend;
@@ -8817,7 +8819,10 @@
 	      rsec = (*gc_mark_hook) (sec, info, rel, NULL, &isym[r_symndx]);
 	    }
 
-	  if (rsec && !rsec->gc_mark)
+	  if (rsec && !rsec->gc_mark
+	      /* Don't mark code sections referenced by .eh_frame,
+		 otherwise we'll mark all code sections in this file.  */
+	      && !(is_eh && (rsec->flags & SEC_CODE) != 0))
 	    {
 	      if (bfd_get_flavour (rsec->owner) != bfd_target_elf_flavour)
 		rsec->gc_mark = 1;
@@ -9123,18 +9128,9 @@
 	continue;
 
       for (o = sub->sections; o != NULL; o = o->next)
-	{
-	  if (o->flags & SEC_KEEP)
-	    {
-	      /* _bfd_elf_discard_section_eh_frame knows how to discard
-		 orphaned FDEs so don't mark sections referenced by the
-		 EH frame section.  */
-	      if (strcmp (o->name, ".eh_frame") == 0)
-		o->gc_mark = 1;
-	      else if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
-		return FALSE;
-	    }
-	}
+	if ((o->flags & SEC_KEEP) != 0 && !o->gc_mark)
+	  if (!_bfd_elf_gc_mark (info, o, gc_mark_hook))
+	    return FALSE;
     }
 
   /* ... and mark SEC_EXCLUDE for those that go.  */

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