This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[patch] h8300-{hms,elf}-ld: Fix a bug in relaxation.
- From: Kazu Hirata <kazu at cs dot umass dot edu>
- To: binutils at sources dot redhat dot com
- Date: Mon, 11 Nov 2002 01:04:54 -0500 (EST)
- Subject: [patch] h8300-{hms,elf}-ld: Fix a bug in relaxation.
Hi,
Attached is a patch to fix a bug in the relaxation code.
_foo:
mov.w r0,r0
beq .L1
jsr @_bar
.L1:
rts
_bar:
rts
Without the patch, the above code gets relaxed to
00000100 <_start>:
100: 0c ee mov.b r6l,r6l
102: 46 02 bne .+2 (106)
00000104 <.L1>:
104: 54 70 rts
00000106 <_bar>:
106: 54 70 rts
We have to call _bar, not jump to _bar, so the relaxation went wrong.
With the patch, I get
00000100 <_start>:
100: 0c ee mov.b r6l,r6l
102: 47 02 beq .+2 (106)
104: 55 02 bsr .+2 (108)
00000106 <.L1>:
106: 54 70 rts
00000108 <_bar>:
108: 54 70 rts
This is OK because jsr (long call) simply became bsr (short call).
The patch fixes the problem by telling the relaxation code not to not
to optimize away jsr after a short jump.
Both h8300-hms-ld and h8300-elf-ld have the above problem. OK to
apply?
Kazu Hirata
2002-11-11 Kazu Hirata <kazu@cs.umass.edu>
* coff-h8300.c (h8300_reloc16_estimate): Do not optimize away
jsr after a short jump.
* elf32-h8300.c (elf32_h8_relax_section): Likewise.
Index: coff-h8300.c
===================================================================
RCS file: /cvs/src/src/bfd/coff-h8300.c,v
retrieving revision 1.13
diff -c -r1.13 coff-h8300.c
*** coff-h8300.c 11 Nov 2002 05:05:22 -0000 1.13
--- coff-h8300.c 11 Nov 2002 05:44:19 -0000
***************
*** 483,488 ****
--- 483,496 ----
closer if we do relax this branch. */
if ((int) gap >= -128 && (int) gap <= 128)
{
+ bfd_byte code;
+
+ if (!bfd_get_section_contents (abfd, input_section,
+ &code, reloc->address,
+ 1))
+ break;
+ code = bfd_get_8 (code);
+
/* It's possible we may be able to eliminate this branch entirely;
if the previous instruction is a branch around this instruction,
and there's no label at this instruction, then we can reverse
***************
*** 496,502 ****
This saves 4 bytes instead of two, and should be relatively
common. */
! if (gap <= 126
&& last_reloc
&& last_reloc->howto->type == R_PCRBYTE)
{
--- 504,511 ----
This saves 4 bytes instead of two, and should be relatively
common. */
! if (code = 0x5a
! && gap <= 126
&& last_reloc
&& last_reloc->howto->type == R_PCRBYTE)
{
***************
*** 504,510 ****
last_value = bfd_coff_reloc16_get_value (last_reloc, link_info,
input_section) + 1;
! if (last_value == dot + 2
&& last_reloc->address + 1 == reloc->address
&& !h8300_symbol_address_p (abfd, input_section, dot - 2))
{
--- 513,520 ----
last_value = bfd_coff_reloc16_get_value (last_reloc, link_info,
input_section) + 1;
! if (code == 0x5a
! && last_value == dot + 2
&& last_reloc->address + 1 == reloc->address
&& !h8300_symbol_address_p (abfd, input_section, dot - 2))
{
Index: elf32-h8300.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-h8300.c,v
retrieving revision 1.17
diff -c -r1.17 elf32-h8300.c
*** elf32-h8300.c 11 Nov 2002 05:05:22 -0000 1.17
--- elf32-h8300.c 11 Nov 2002 05:44:20 -0000
***************
*** 819,825 ****
two bytes closer if we do relax this branch. */
if ((int) gap >= -126 && (int) gap <= 130)
{
! unsigned char code;
/* Note that we've changed the relocs, section contents,
etc. */
--- 819,826 ----
two bytes closer if we do relax this branch. */
if ((int) gap >= -126 && (int) gap <= 130)
{
! unsigned char code =
! bfd_get_8 (abfd, contents + irel->r_offset - 1);
/* Note that we've changed the relocs, section contents,
etc. */
***************
*** 834,840 ****
Such sequences are used by the compiler to deal with
long conditional branches. */
! if ((int) gap <= 130
&& (int) gap >= -128
&& last_reloc
&& ELF32_R_TYPE (last_reloc->r_info) == R_H8_PCREL8
--- 835,842 ----
Such sequences are used by the compiler to deal with
long conditional branches. */
! if (code == 0x5a
! && (int) gap <= 130
&& (int) gap >= -128
&& last_reloc
&& ELF32_R_TYPE (last_reloc->r_info) == R_H8_PCREL8
***************
*** 891,898 ****
}
/* We could not eliminate this jump, so just shorten it. */
- code = bfd_get_8 (abfd, contents + irel->r_offset - 1);
-
if (code == 0x5e)
bfd_put_8 (abfd, 0x55, contents + irel->r_offset - 1);
else if (code == 0x5a)
--- 893,898 ----