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]

RFC: Mark discarded debug info more thoroughly


GDB has a hack, recently improved, which lets it ignore debug
information that appears to start at address zero.  This is to match
GNU LD's behavior for debug info referring to discarded sections,
especially .gnu.linkonce.t.*.  But it's also used for COMDAT (since
GCC still doesn't generate COMDAT debug info), and for things dumped
due to /DISCARD/ in a linker script.

The hack works much better for linkonce than it does for /DISCARD/.
For example, a customer once reported that it didn't work right for
the Linux kernel, which uses /DISCARD/ to get rid of all .text.exit
sections for modules compiled in to the kernel (and thus never
unloaded).  If a file has two functions in .text.exit, and uses REL
relocations, one of them will appear to start at a low address just
after the end of the previous function.  Not at zero.

I had some patches which extended the GDB hack.  But when I was getting
ready to submit them I had a bright idea: we can fix this in the linker
fairly reliably.  Instead of just skipping such relocations, we should
apply them with the magic relocation value needed to put an actual
zero in the output file.  This makes final output files more consistent
between REL and RELA targets.

It looks like the attached.  OK?  If so, I will go through and try to
fix all the other ELF architectures which support REL.

-- 
Daniel Jacobowitz
CodeSourcery

2006-10-25  Daniel Jacobowitz  <dan@codesourcery.com>

	* libbfd-in.h (_bfd_clear_contents): New prototype.
	* reloc.c (_bfd_clear_contents): New.
	* elf32-i386.c (elf_i386_relocate_section): Use _bfd_clear_contents.
	* libbfd.h: Regenerated.

Index: elf32-i386.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-i386.c,v
retrieving revision 1.167
diff -u -p -r1.167 elf32-i386.c
--- elf32-i386.c	17 Oct 2006 13:41:46 -0000	1.167
+++ elf32-i386.c	25 Oct 2006 17:42:19 -0000
@@ -2395,17 +2395,12 @@ elf_i386_relocate_section (bfd *output_b
 
       if (r_symndx == 0)
 	{
-	/* r_symndx will be zero only for relocs against symbols from
-	   removed linkonce sections, or sections discarded by a linker
-	   script.  For these relocs, we just want the section contents
-	   zeroed.  Avoid any special processing in the switch below.  */
-	  r_type = R_386_NONE;
-
-	  relocation = 0;
-	  if (howto->pc_relative)
-	    relocation = (input_section->output_section->vma
-			  + input_section->output_offset
-			  + rel->r_offset);
+	  /* r_symndx will be zero only for relocs against symbols from
+	     removed linkonce sections, or sections discarded by a linker
+	     script.  For these relocs, we just want the section contents
+	     zeroed.  Avoid any special processing.  */
+	  _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
+	  continue;
 	}
 
       switch (r_type)
Index: libbfd-in.h
===================================================================
RCS file: /cvs/src/src/bfd/libbfd-in.h,v
retrieving revision 1.66
diff -u -p -r1.66 libbfd-in.h
--- libbfd-in.h	19 Jun 2006 13:17:43 -0000	1.66
+++ libbfd-in.h	25 Oct 2006 17:42:19 -0000
@@ -547,6 +547,10 @@ extern bfd_reloc_status_type _bfd_final_
 extern bfd_reloc_status_type _bfd_relocate_contents
   (reloc_howto_type *, bfd *, bfd_vma, bfd_byte *);
 
+/* Clear a given location using a given howto.  */
+extern void _bfd_clear_contents (reloc_howto_type *howto, bfd *input_bfd,
+				 bfd_byte *location);
+
 /* Link stabs in sections in the first pass.  */
 
 extern bfd_boolean _bfd_link_section_stabs
Index: libbfd.h
===================================================================
RCS file: /cvs/src/src/bfd/libbfd.h,v
retrieving revision 1.187
diff -u -p -r1.187 libbfd.h
--- libbfd.h	25 Oct 2006 06:49:20 -0000	1.187
+++ libbfd.h	25 Oct 2006 17:42:19 -0000
@@ -552,6 +552,10 @@ extern bfd_reloc_status_type _bfd_final_
 extern bfd_reloc_status_type _bfd_relocate_contents
   (reloc_howto_type *, bfd *, bfd_vma, bfd_byte *);
 
+/* Clear a given location using a given howto.  */
+extern void _bfd_clear_contents (reloc_howto_type *howto, bfd *input_bfd,
+				 bfd_byte *location);
+
 /* Link stabs in sections in the first pass.  */
 
 extern bfd_boolean _bfd_link_section_stabs
Index: reloc.c
===================================================================
RCS file: /cvs/src/src/bfd/reloc.c,v
retrieving revision 1.158
diff -u -p -r1.158 reloc.c
--- reloc.c	25 Oct 2006 06:49:20 -0000	1.158
+++ reloc.c	25 Oct 2006 17:42:20 -0000
@@ -1545,6 +1545,72 @@ _bfd_relocate_contents (reloc_howto_type
   return flag;
 }
 
+/* Clear a given location using a given howto, by applying a relocation value
+   of zero and discarding any in-place addend.  This is used for fixed-up
+   relocations against discarded symbols, to make ignorable debug or unwind
+   information more obvious.  */
+
+void
+_bfd_clear_contents (reloc_howto_type *howto,
+		     bfd *input_bfd,
+		     bfd_byte *location)
+{
+  int size;
+  bfd_vma x = 0;
+
+  /* Get the value we are going to relocate.  */
+  size = bfd_get_reloc_size (howto);
+  switch (size)
+    {
+    default:
+    case 0:
+      abort ();
+    case 1:
+      x = bfd_get_8 (input_bfd, location);
+      break;
+    case 2:
+      x = bfd_get_16 (input_bfd, location);
+      break;
+    case 4:
+      x = bfd_get_32 (input_bfd, location);
+      break;
+    case 8:
+#ifdef BFD64
+      x = bfd_get_64 (input_bfd, location);
+#else
+      abort ();
+#endif
+      break;
+    }
+
+  /* Zero out the unwanted bits of X.  */
+  x &= ~howto->src_mask;
+
+  /* Put the relocated value back in the object file.  */
+  switch (size)
+    {
+    default:
+    case 0:
+      abort ();
+    case 1:
+      bfd_put_8 (input_bfd, x, location);
+      break;
+    case 2:
+      bfd_put_16 (input_bfd, x, location);
+      break;
+    case 4:
+      bfd_put_32 (input_bfd, x, location);
+      break;
+    case 8:
+#ifdef BFD64
+      bfd_put_64 (input_bfd, x, location);
+#else
+      abort ();
+#endif
+      break;
+    }
+}
+
 /*
 DOCDD
 INODE


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]