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]

[PATCH #6407] Patch to resolve issue of non-booting Linux kernel


Oracle has a full copyright assignment in place with the FSF.

This patch provides a fix for ticket #6407 'linux kernel linked with gold fails
to boot'.  The problem reported in the ticket was found to only occur when the
kernel is configured to be relocatable (CONFIG_RELOCATABLE=y).  Tracing through
the code, and comparison of kernels built with GNU ld vs GNU gold indicated
that there was a likely problem with the data generated when --emit-relocs is
passed to gold.  Further debugging showed that gold applies the value of
offset_in_output_section in the calculation of the new offset (it is
explicitly added to the new offset, but it is already accounted for in the
view address that is added to the new offset to determine the absolute address.

The patch below corrects this problem.  It was generated against cvs HEAD.

Earlier in the code, offset_in_output_section may be added to new_offset (if
not equal to -1).  If new_offset is to be an absolute address (executable or
shared object), view_address is added to new_offset, but because that already
includes the offset_in_output_section value, we need to subtract it again if
it had been added.

Testsuite execution has been verified to be identical between the unpatched and
the patched version.  No regressions were found.


	Cheers,
	Kris

ChangeLog entry:
================
2008-05-29  Kris Van Hees  <kris.van.hees@oracle.com>

        * target-reloc.h (relocate_for_relocatable): Fix new_offset calculation.

Patch:
======
--- binutils-head/gold/target-reloc.h-old	2008-05-29 16:20:54.000000000 -0400
+++ binutils-head/gold/target-reloc.h	2008-05-29 16:09:48.000000000 -0400
@@ -542,7 +542,11 @@
       // In an executable or dynamic object, generated by
       // --emit-relocs, r_offset is an absolute address.
       if (!parameters->options().relocatable())
-	new_offset += view_address;
+	{
+	  new_offset += view_address;
+	  if (offset_in_output_section != -1)
+	    new_offset -= offset_in_output_section;
+	}
 
       reloc_write.put_r_offset(new_offset);
       reloc_write.put_r_info(elfcpp::elf_r_info<size>(new_symndx, r_type));


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