PATCH: Fix linkonce support with debug

H. J. Lu hjl@lucon.org
Sun Jun 15 04:49:00 GMT 2003


On Sat, Jun 14, 2003 at 05:54:50PM -0400, Daniel Jacobowitz wrote:
> On Fri, Jun 13, 2003 at 11:27:00AM -0700, H. J. Lu wrote:
> > On Fri, Jun 13, 2003 at 01:58:02PM -0400, Daniel Jacobowitz wrote:
> > > > > > 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.
> > > > > 
> > > > > No, I believe it is worse.
> > > > > 
> > > > > Consider that you now have multiple sections in .debug_info covering
> > > > > the same PC range - not necessarily all identical.
> > > > 
> > > > That is why I said it was not ideal.
> > > > >
> > > > > Also consider what happens if the multiple copies of the linkonce
> > > > > function are compiled with (say) different optimization levels.  You
> > > > > will have added a lot of line information which is completely bogus.
> > > > > 
> > > > 
> > > > Isn't is completely bogus in this situation today? We are picking
> > > 
> > > Here at least the bad line number information gets thrown down at PC 0. 
> > > It's still bogus, but on most systems less likely to get in the way.
> > > 
> > > > one from 2 bad choices. I don't think mine is any worse than the
> > > > current one.
> > > 
> > > I think it's worse.  It definitely isn't any better.
> > > 
> > 
> > There is a testcase which my patch fixes. Do you have a testcase which
> > works without my patch and doesn't work with my patch?
> 
> Sure.  It was easy to construct one from my previous explanation.  This
> exploits one of the possible problems: Support that a function without
> line information is placed right after the linkonce section, and
> suppose that the copy we keep was built with -O2 -g (like libstdc++
> often is) and the copy we discarded was built with -O0 -g (like my
> development code often is).  The line number information for the larger
> copy will appear to take control of the function without debug
> information, causing GDB's prologue analyzer to place a breakpoint in
> the completely wrong location.

If it is the only problem, this new patch seems to work OK.


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-14 21:39:43.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,22 @@ 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
+				  && sec->_cooked_size == sec->kept_section->_cooked_size)
+				h->root.u.def.section
+				  = sec->kept_section;
+			      else
+				memset (rel, 0, sizeof (*rel));
 			    }
 			  else
 			    finfo->info->callbacks->error_handler
@@ -5092,7 +5101,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 +5109,18 @@ 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
+				  && sec->_cooked_size == sec->kept_section->_cooked_size)
+				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