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]

Re: PATCH: PR ld/14105: Always create PLT eh_frame


On Mon, May 21, 2012 at 08:18:41PM -0700, H.J. Lu wrote:
> 	* elflink.c (bfd_elf_discard_info): Also handle PLT eh_frame
> 	created by linker.

I think we may have an ordering problem.  bfd_elf_discard_info runs
before the PLT eh_frame is completely filled out (on powerpc, before
any of it is written, so there is certainly a problem there).  On i386
and x86_64, we write the PLT offset in finish_dynamic_sections.  How
does this interact with elf-eh-frame optimisations?  Just looking at
the code I think it probably is OK, but please do check exactly what
happens with every word read out of your PLT eh_frame!

> +	  if (!plt_eh_frame_done)

It probably isn't worth bothering with a flag here.  If you leave that
out, then if we have multiple .eh_frame sections in the future for
other reasons they will be handled too.  That also allows for some
simplification.  Your bfd_get_next_section_by_name can be simplified
too.  Committing the following.  I'll leave the x86 bits to you.

	* elflink.c (bfd_elf_discard_info): Handle multiple .eh_frame
	sections attached to a BFD.
	* section.c (bfd_get_section_by_name): Rewrite description.
	(bfd_get_next_section_by_name): New function.
	* bfd-in2.h: Regenerate.

Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.441
diff -u -p -r1.441 elflink.c
--- bfd/elflink.c	16 May 2012 14:13:26 -0000	1.441
+++ bfd/elflink.c	22 May 2012 11:57:33 -0000
@@ -12522,8 +12522,8 @@ bfd_elf_discard_info (bfd *output_bfd, s
 	  fini_reloc_cookie_rels (&cookie, stab);
 	}
 
-      if (eh != NULL
-	  && init_reloc_cookie_rels (&cookie, info, abfd, eh))
+      while (eh != NULL
+	     && init_reloc_cookie_rels (&cookie, info, abfd, eh))
 	{
 	  _bfd_elf_parse_eh_frame (abfd, info, eh, &cookie);
 	  if (_bfd_elf_discard_section_eh_frame (abfd, info, eh,
@@ -12531,6 +12531,7 @@ bfd_elf_discard_info (bfd *output_bfd, s
 						 &cookie))
 	    ret = TRUE;
 	  fini_reloc_cookie_rels (&cookie, eh);
+	  eh = bfd_get_next_section_by_name (eh);
 	}
 
       if (bed->elf_backend_discard_info != NULL
Index: bfd/section.c
===================================================================
RCS file: /cvs/src/src/bfd/section.c,v
retrieving revision 1.114
diff -u -p -r1.114 section.c
--- bfd/section.c	14 May 2012 19:45:20 -0000	1.114
+++ bfd/section.c	22 May 2012 11:57:34 -0000
@@ -845,14 +845,8 @@ SYNOPSIS
 	asection *bfd_get_section_by_name (bfd *abfd, const char *name);
 
 DESCRIPTION
-	Run through @var{abfd} and return the one of the
-	<<asection>>s whose name matches @var{name}, otherwise <<NULL>>.
-	@xref{Sections}, for more information.
-
-	This should only be used in special cases; the normal way to process
-	all sections of a given name is to use <<bfd_map_over_sections>> and
-	<<strcmp>> on the name (or better yet, base it on the section flags
-	or something else) for each section.
+	Return the most recently created section attached to @var{abfd}
+	named @var{name}.  Return NULL if no such section exists.
 */
 
 asection *
@@ -869,6 +863,41 @@ bfd_get_section_by_name (bfd *abfd, cons
 
 /*
 FUNCTION
+       bfd_get_next_section_by_name
+
+SYNOPSIS
+       asection *bfd_get_next_section_by_name (asection *sec);
+
+DESCRIPTION
+       Given @var{sec} is a section returned by @code{bfd_get_section_by_name},
+       return the next most recently created section attached to the same
+       BFD with the same name.  Return NULL if no such section exists.
+*/
+
+asection *
+bfd_get_next_section_by_name (asection *sec)
+{
+  struct section_hash_entry *sh;
+  const char *name;
+  unsigned long hash;
+
+  sh = ((struct section_hash_entry *)
+	((char *) sec - offsetof (struct section_hash_entry, section)));
+
+  hash = sh->root.hash;
+  name = sec->name;
+  for (sh = (struct section_hash_entry *) sh->root.next;
+       sh != NULL;
+       sh = (struct section_hash_entry *) sh->root.next)
+    if (sh->root.hash == hash
+       && strcmp (sh->root.string, name) == 0)
+      return &sh->section;
+
+  return NULL;
+}
+
+/*
+FUNCTION
 	bfd_get_section_by_name_if
 
 SYNOPSIS


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