This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[patch] mn10300: relaxing across sections buglet
- From: DJ Delorie <dj at redhat dot com>
- To: binutils at sourceware dot org
- Date: Fri, 7 Dec 2007 16:56:29 -0500
- Subject: [patch] mn10300: relaxing across sections buglet
The comment about "as the target will be two bytes closer" is not true
if the symbols are in different sections. Ok to apply?
* elf-m10300.c (mn10300_elf_relax_section): Fix edge case when
relaxing across sections.
Index: elf-m10300.c
===================================================================
RCS file: /cvs/src/src/bfd/elf-m10300.c,v
retrieving revision 1.93
diff -p -U3 -r1.93 elf-m10300.c
--- elf-m10300.c 28 Nov 2007 13:04:17 -0000 1.93
+++ elf-m10300.c 7 Dec 2007 21:54:26 -0000
@@ -2751,6 +2751,8 @@ mn10300_elf_relax_section (bfd *abfd,
for (irel = internal_relocs; irel < irelend; irel++)
{
bfd_vma symval;
+ bfd_signed_vma jump_offset;
+ asection *sym_sec = NULL;
struct elf32_mn10300_link_hash_entry *h = NULL;
/* If this isn't something that can be relaxed, then ignore
@@ -2790,7 +2792,6 @@ mn10300_elf_relax_section (bfd *abfd,
if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
{
Elf_Internal_Sym *isym;
- asection *sym_sec = NULL;
const char *sym_name;
char *new_name;
@@ -2858,6 +2859,8 @@ mn10300_elf_relax_section (bfd *abfd,
if (h->root.root.u.def.section->output_section == NULL)
continue;
+ sym_sec = h->root.root.u.def.section->output_section;
+
symval = (h->root.root.u.def.value
+ h->root.root.u.def.section->output_section->vma
+ h->root.root.u.def.section->output_offset);
@@ -2960,10 +2963,15 @@ mn10300_elf_relax_section (bfd *abfd,
/* See if the value will fit in 16 bits, note the high value is
0x7fff + 2 as the target will be two bytes closer if we are
- able to relax. */
+ able to relax, if it's in the same section. */
+ if (sec->output_section == sym_sec->output_section)
+ jump_offset = 0x8001;
+ else
+ jump_offset = 0x8000;
+
/* Account for jumps across alignment boundaries using
align_gap_adjustment. */
- if ((bfd_signed_vma) value < 0x8001 - (bfd_signed_vma) align_gap_adjustment
+ if ((bfd_signed_vma) value < jump_offset - (bfd_signed_vma) align_gap_adjustment
&& ((bfd_signed_vma) value > -0x8000 + (bfd_signed_vma) align_gap_adjustment))
{
unsigned char code;