PATCH: Fix linkonce support with debug

H. J. Lu hjl@lucon.org
Fri Jun 13 17:24:00 GMT 2003


On Fri, Jun 13, 2003 at 02:26:32PM +0930, Alan Modra wrote:
> On Thu, Jun 12, 2003 at 01:01:27PM -0700, H. J. Lu wrote:
> > Alan,
> > 
> > I believe your change mentioned in
> > 
> > http://sources.redhat.com/ml/binutils/2001-09/msg00499.html
> > 
> > breaks linkonce support with debug:
> > 
> > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=7671
> 
> I doubt that changing section ordering has anything to do with this
> problem.  The real problem is that we have debug info for a removed
> section, with relocations that are left dangling.  The debug info
> ought to be removed along with the section, preferably by using
> section groups.
> 

This patch seems to work for me. We should try to preserve debug
information discarded by linkonce as much as we can. It may not be
ideal. But it is better than the current one.


H.J.
-------------- next part --------------
bfd/

2003-06-13  H.J. Lu <hongjiu.lu@intel.com>

	* section.c (struct sec): Put back kept_section.
	(STD_SECTION): Put back kept_section initialisation.
	* bfd-in2.h: Regenerate.

	* elflink.h (elf_link_input_bfd): Also check discarded linkonce
	sections for relocateable output. Use kept_section to preserve
	debug information discarded by linkonce.

ld/

2003-06-13  H.J. Lu <hongjiu.lu@intel.com>

	* ldlang.c (section_already_linked): Put back assignment of
	kept_section.

--- binutils/bfd/elflink.h.linkonce	2003-06-13 08:34:09.000000000 -0700
+++ binutils/bfd/elflink.h	2003-06-13 10:13:58.000000000 -0700
@@ -5046,9 +5046,9 @@ elf_link_input_bfd (finfo, input_bfd)
 	     from discarded sections and section symbols from
 	     removed link-once sections.  Complain about relocs
 	     against discarded sections.  Zero relocs against removed
-	     link-once sections.  */
-	  if (!finfo->info->relocateable
-	      && !elf_section_ignore_discarded_relocs (o))
+	     link-once sections.  Preserve debug information as much
+	     as we can.  */
+	  if (!elf_section_ignore_discarded_relocs (o))
 	    {
 	      Elf_Internal_Rela *rel, *relend;
 
@@ -5057,6 +5057,7 @@ elf_link_input_bfd (finfo, input_bfd)
 	      for ( ; rel < relend; rel++)
 		{
 		  unsigned long r_symndx = ELF_R_SYM (rel->r_info);
+		  asection *sec;
 
 		  if (r_symndx >= locsymcount
 		      || (elf_bad_symtab (input_bfd)
@@ -5071,14 +5072,21 @@ elf_link_input_bfd (finfo, input_bfd)
 
 		      /* Complain if the definition comes from a
 			 discarded section.  */
+		      sec = h->root.u.def.section;
 		      if ((h->root.type == bfd_link_hash_defined
 			   || h->root.type == bfd_link_hash_defweak)
-			  && elf_discarded_section (h->root.u.def.section))
+			  && elf_discarded_section (sec))
 			{
 			  if ((o->flags & SEC_DEBUGGING) != 0)
 			    {
 			      BFD_ASSERT (r_symndx != 0);
-			      memset (rel, 0, sizeof (*rel));
+			      /* Try to preserve debug information.  */
+			      if ((o->flags & SEC_DEBUGGING) != 0
+				  && sec->kept_section != NULL)
+				h->root.u.def.section
+				  = sec->kept_section;
+			      else
+				memset (rel, 0, sizeof (*rel));
 			    }
 			  else
 			    finfo->info->callbacks->error_handler
@@ -5092,7 +5100,7 @@ elf_link_input_bfd (finfo, input_bfd)
 		    }
 		  else
 		    {
-		      asection *sec = finfo->sections[r_symndx];
+		      sec = finfo->sections[r_symndx];
 
 		      if (sec != NULL && elf_discarded_section (sec))
 			{
@@ -5100,9 +5108,17 @@ elf_link_input_bfd (finfo, input_bfd)
 			      || (sec->flags & SEC_LINK_ONCE) != 0)
 			    {
 			      BFD_ASSERT (r_symndx != 0);
-			      rel->r_info
-				= ELF_R_INFO (0, ELF_R_TYPE (rel->r_info));
-			      rel->r_addend = 0;
+			      /* Try to preserve debug information.  */
+			      if ((o->flags & SEC_DEBUGGING) != 0
+				  && sec->kept_section != NULL)
+				finfo->sections[r_symndx]
+				  = sec->kept_section;
+			      else
+				{
+				  rel->r_info
+				    = ELF_R_INFO (0, ELF_R_TYPE (rel->r_info));
+				  rel->r_addend = 0;
+				}
 			    }
 			  else
 			    {
--- binutils/bfd/section.c.linkonce	2003-06-08 17:41:36.000000000 -0700
+++ binutils/bfd/section.c	2003-06-13 09:41:32.000000000 -0700
@@ -493,6 +493,10 @@ CODE_FRAGMENT
 .  {* Optional information about a COMDAT entry; NULL if not COMDAT.  *}
 .  struct bfd_comdat_info *comdat;
 .
+.  {* Points to the kept section if this section is a link-once section,
+.     and is discarded.  *}
+.  struct sec *kept_section;
+.
 .  {* When a section is being output, this value changes as more
 .     linenumbers are written out.  *}
 .  file_ptr moving_line_filepos;
@@ -640,8 +644,8 @@ static const asymbol global_syms[] =
     /* line_filepos, userdata, contents, lineno, lineno_count,       */	\
        0,            NULL,     NULL,     NULL,   0,			\
 									\
-    /* entsize, comdat, moving_line_filepos,                         */	\
-       0,       NULL,   0,						\
+    /* entsize, comdat, kept_section, moving_line_filepos,           */	\
+       0,       NULL,   NULL,	      0,				\
 									\
     /* target_index, used_by_bfd, constructor_chain, owner,          */	\
        0,            NULL,        NULL,              NULL,		\
--- binutils/ld/ldlang.c.linkonce	2003-05-13 08:45:34.000000000 -0700
+++ binutils/ld/ldlang.c	2003-06-13 08:52:42.000000000 -0700
@@ -1089,8 +1089,11 @@ section_already_linked (abfd, sec, data)
 
 	  /* Set the output_section field so that lang_add_section
 	     does not create a lang_input_section structure for this
-	     section.  */
+	     section.  Since there might be a symbol in the section
+	     being discarded, we must retain a pointer to the section
+	     which we are really going to use.  */
 	  sec->output_section = bfd_abs_section_ptr;
+	  sec->kept_section = l->sec;
 
 	  if (flags & SEC_GROUP)
 	    bfd_discard_group (abfd, sec);


More information about the Binutils mailing list