This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[Xtensa Patch] Fixup the bits during a relocatable link
- From: Sterling Augustine <sterling at tensilica dot com>
- To: "binutils at sourceware dot org" <binutils at sourceware dot org>
- Date: Fri, 28 May 2010 11:16:55 -0700
- Subject: [Xtensa Patch] Fixup the bits during a relocatable link
The Xtensa version of ld does extensive link-time relaxation. Until
now, when it modified a section, it would only change the relevant
relocations, but not actual bits in the relevant instructions. Normally
a final link would do that part of the work.
However, linux-kernel loadable modules never go through final links, so
linker-relaxation didn't work with kernel loadable modules because the
instructions were stale vs the relocations describing them.
I have committed the attached patch which fixes this problem. It is now
possible to use linker relaxation on kernel loadable modules for Xtensa.
Sterling
sterling@tensilica.com
2010-05-28 Sterling Augustine <sterling@tensilica.com>
* elf32-xtensa.c (elf_xtensa_relocate_section): Add a
large amount of code to change the bits in the
instructions to match the changes in the relocations.
Declare dest_addr and sym_sec to help.
Index: elf32-xtensa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-xtensa.c,v
retrieving revision 1.121
diff -u -p -c -r1.121 elf32-xtensa.c
cvs diff: conflicting specifications of output style
*** elf32-xtensa.c 8 Feb 2010 13:16:24 -0000 1.121
--- elf32-xtensa.c 28 May 2010 18:03:57 -0000
*************** elf_xtensa_relocate_section (bfd *output
*** 2672,2677 ****
--- 2672,2680 ----
if (info->relocatable)
{
+ bfd_vma dest_addr;
+ asection * sym_sec = get_elf_r_symndx_section (input_bfd, r_symndx);
+
/* This is a relocatable link.
1) If the reloc is against a section symbol, adjust
according to the output section.
*************** elf_xtensa_relocate_section (bfd *output
*** 2688,2693 ****
--- 2691,2699 ----
return FALSE;
}
+ dest_addr = sym_sec->output_section->vma + sym_sec->output_offset
+ + get_elf_r_symndx_offset (input_bfd, r_symndx) + rel->r_addend;
+
if (r_type == R_XTENSA_ASM_SIMPLIFY)
{
error_message = NULL;
*************** elf_xtensa_relocate_section (bfd *output
*** 2724,2748 ****
to work around problems with DWARF in relocatable links
with some previous version of BFD. Now we can't easily get
rid of the hack without breaking backward compatibility.... */
! if (rel->r_addend)
{
! howto = &elf_howto_table[r_type];
! if (howto->partial_inplace)
{
r = elf_xtensa_do_reloc (howto, input_bfd, input_section,
! rel->r_addend, contents,
rel->r_offset, FALSE,
&error_message);
- if (r != bfd_reloc_ok)
- {
- if (!((*info->callbacks->reloc_dangerous)
- (info, error_message, input_bfd, input_section,
- rel->r_offset)))
- return FALSE;
- }
- rel->r_addend = 0;
}
}
/* Done with work for relocatable link; continue with next reloc. */
continue;
--- 2730,2770 ----
to work around problems with DWARF in relocatable links
with some previous version of BFD. Now we can't easily get
rid of the hack without breaking backward compatibility.... */
! r = bfd_reloc_ok;
! howto = &elf_howto_table[r_type];
! if (howto->partial_inplace && rel->r_addend)
! {
! r = elf_xtensa_do_reloc (howto, input_bfd, input_section,
! rel->r_addend, contents,
! rel->r_offset, FALSE,
! &error_message);
! rel->r_addend = 0;
! }
! else
{
! /* Put the correct bits in the target instruction, even
! though the relocation will still be present in the output
! file. This makes disassembly clearer, as well as
! allowing loadable kernel modules to work without needing
! relocations on anything other than calls and l32r's. */
!
! /* If it is not in the same section, there is nothing we can do. */
! if (r_type >= R_XTENSA_SLOT0_OP && r_type <= R_XTENSA_SLOT14_OP &&
! sym_sec->output_section == input_section->output_section)
{
r = elf_xtensa_do_reloc (howto, input_bfd, input_section,
! dest_addr, contents,
rel->r_offset, FALSE,
&error_message);
}
}
+ if (r != bfd_reloc_ok)
+ {
+ if (!((*info->callbacks->reloc_dangerous)
+ (info, error_message, input_bfd, input_section,
+ rel->r_offset)))
+ return FALSE;
+ }
/* Done with work for relocatable link; continue with next reloc. */
continue;