This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH #6407] Patch to resolve issue of non-booting Linux kernel
- From: Kris Van Hees <kris dot van dot hees at oracle dot com>
- To: binutils at sourceware dot org
- Cc: Ian Lance Taylor <iant at google dot com>
- Date: Thu, 29 May 2008 16:52:12 -0400
- Subject: [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));