This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[Xtensa] fix regression from previous change
- From: Bob Wilson <bwilson at tensilica dot com>
- To: binutils at sources dot redhat dot com
- Date: Fri, 21 Dec 2007 15:23:51 -0800
- Subject: [Xtensa] fix regression from previous change
One of my changes from 2007-10-05 introduced a bug in the linker. I changed the
relax_section function to avoiding generating a fix record for a DIFF
relocation. That was correct in the context of that change since the relaxation
can never cause a DIFF reloc to refer to a symbol in another input file. My
change was not correct, though, because it also prevented the addend in DIFF
relocations from being updated to account for relaxation. I've committed this
patch to fix it.
2007-12-21 Bob Wilson <bob.wilson@acm.org>
* elf32-xtensa.c (relax_section): Update DIFF relocations in the
same way as other relocations.
Index: elf32-xtensa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-xtensa.c,v
retrieving revision 1.104
diff -u -p -r1.104 elf32-xtensa.c
--- elf32-xtensa.c 12 Dec 2007 21:11:10 -0000 1.104
+++ elf32-xtensa.c 21 Dec 2007 22:56:16 -0000
@@ -8240,30 +8240,28 @@ relax_section (bfd *abfd, asection *sec,
pin_contents (sec, contents);
}
+
+ /* If the relocation still references a section in the same
+ input file, modify the relocation directly instead of
+ adding a "fix" record. */
+ if (target_sec->owner == abfd)
+ {
+ unsigned r_symndx = ELF32_R_SYM (new_reloc.rela.r_info);
+ irel->r_info = ELF32_R_INFO (r_symndx, r_type);
+ irel->r_addend = new_reloc.rela.r_addend;
+ pin_internal_relocs (sec, internal_relocs);
+ }
else
{
- /* If the relocation still references a section in the same
- input file, modify the relocation directly instead of
- adding a "fix" record. */
- if (target_sec->owner == abfd)
- {
- unsigned r_symndx = ELF32_R_SYM (new_reloc.rela.r_info);
- irel->r_info = ELF32_R_INFO (r_symndx, r_type);
- irel->r_addend = new_reloc.rela.r_addend;
- pin_internal_relocs (sec, internal_relocs);
- }
- else
- {
- bfd_vma addend_displacement;
- reloc_bfd_fix *fix;
+ bfd_vma addend_displacement;
+ reloc_bfd_fix *fix;
- addend_displacement =
- new_reloc.target_offset + new_reloc.virtual_offset;
- fix = reloc_bfd_fix_init (sec, source_offset, r_type,
- target_sec,
- addend_displacement, TRUE);
- add_fix (sec, fix);
- }
+ addend_displacement =
+ new_reloc.target_offset + new_reloc.virtual_offset;
+ fix = reloc_bfd_fix_init (sec, source_offset, r_type,
+ target_sec,
+ addend_displacement, TRUE);
+ add_fix (sec, fix);
}
}
}