This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] [SH] Fix PR 10373
- From: Oleg Endo <oleg dot endo at t-online dot de>
- To: binutils <binutils at sourceware dot org>
- Date: Fri, 01 Aug 2014 09:14:38 +0200
- Subject: [PATCH] [SH] Fix PR 10373
- Authentication-results: sourceware.org; auth=none
Hello,
The branch relaxation stuff on SH has been broken for a while. A while
ago PRs and patches have been submitted but never applied, it seems.
Attached is the patch by Takashi Yoshii that fixes PR 10373.
Tested with 'make' for target sh-elf.
make check RUNTESTFLAGS="--target_board=sh-sim" looks OK, too.
Cheers,
Oleg
>From b89d52098380acb53c4e4cbd7256da70d6ec972e Mon Sep 17 00:00:00 2001
Message-Id: <b89d52098380acb53c4e4cbd7256da70d6ec972e.1406876579.git.olegendo@gcc.gnu.org>
From: Oleg Endo <olegendo@gcc.gnu.org>
Date: Fri, 1 Aug 2014 09:02:18 +0200
Subject: [PATCH] Fix PR 10373.
---
bfd/ChangeLog | 5 +++++
bfd/elf32-sh.c | 9 ++++++---
ld/testsuite/ChangeLog | 6 ++++++
ld/testsuite/ld-sh/sh.exp | 7 ++++---
ld/testsuite/ld-sh/sh1.s | 5 +++++
5 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index abcd4ab..d5defab 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,8 @@
+2014-08-01 Takashi Yoshii <yoshii.takashi@renesas.com>
+
+ PR 10373
+ * elf32-sh.c (sh_elf_relax_section): Add jmp to bra relaxing.
+
2014-07-29 Matthew Fortune <matthew.fortune@imgtec.com>
* elfxx-mips.c (ABI_O32_P, MIPS_ELF_ABIFLAGS_SECTION_NAME_P): New macro.
diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c
index 5085830..44a3aa7 100644
--- a/bfd/elf32-sh.c
+++ b/bfd/elf32-sh.c
@@ -702,10 +702,10 @@ sh_elf_relax_section (bfd *abfd, asection *sec,
elf_section_data (sec)->this_hdr.contents = contents;
symtab_hdr->contents = (unsigned char *) isymbuf;
- /* Replace the jsr with a bsr. */
+ /* Replace the jmp/jsr with a bra/bsr. */
/* Change the R_SH_USES reloc into an R_SH_IND12W reloc, and
- replace the jsr with a bsr. */
+ replace the jmp/jsr with a bra/bsr. */
irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irelfn->r_info), R_SH_IND12W);
/* We used to test (ELF32_R_SYM (irelfn->r_info) < symtab_hdr->sh_info)
here, but that only checks if the symbol is an external symbol,
@@ -716,7 +716,10 @@ sh_elf_relax_section (bfd *abfd, asection *sec,
/* We can't fully resolve this yet, because the external
symbol value may be changed by future relaxing. We let
the final link phase handle it. */
- bfd_put_16 (abfd, (bfd_vma) 0xb000, contents + irel->r_offset);
+ if (bfd_get_16 (abfd, contents + irel->r_offset) & 0x0020)
+ bfd_put_16 (abfd, (bfd_vma) 0xa000, contents + irel->r_offset);
+ else
+ bfd_put_16 (abfd, (bfd_vma) 0xb000, contents + irel->r_offset);
irel->r_addend = -4;
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 773a638..9114c7d 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,5 +1,11 @@
2014-08-01 Takashi Yoshii <yoshii.takashi@renesas.com>
+ PR 10373
+ * ld-sh/sh1.s: Add jmp relaxing test.
+ * ld-sh/sh.exp: Likewise.
+
+2014-08-01 Takashi Yoshii <yoshii.takashi@renesas.com>
+
PR 10378
* ld-sh/adjsw8.s: New.
* ld-sh/sh.exp: Add switch8 adjustment test.
diff --git a/ld/testsuite/ld-sh/sh.exp b/ld/testsuite/ld-sh/sh.exp
index a270400..417daf7 100644
--- a/ld/testsuite/ld-sh/sh.exp
+++ b/ld/testsuite/ld-sh/sh.exp
@@ -49,7 +49,7 @@ if ![ld_assemble $as "-relax $srcdir/$subdir/sh1.s" tmpdir/sh1.o] {
verbose "bad output from nm"
fail $testsimple
} else {
- if {$nm_output(bar) != $nm_output(foo) + 4} {
+ if {$nm_output(bar) != $nm_output(foo) + 0xc} {
send_log "foo == $nm_output(foo)\n"
verbose "foo == $nm_output(foo)"
send_log "bar == $nm_output(bar)\n"
@@ -149,7 +149,7 @@ if [istarget sh*-*linux*] {
}
if {![ld_assemble $as "-relax tmpdir/start.s" tmpdir/start.o] \
- || ![ld_compile $CC "-O -mrelax $srcdir/$subdir/sh2.c" tmpdir/sh2.o]} {
+ || ![ld_compile $CC "-O -mrelax -foptimize-sibling-calls $srcdir/$subdir/sh2.c" tmpdir/sh2.o]} {
unresolved $testlink
unresolved $testjsr
unresolved $testrun
@@ -168,7 +168,8 @@ pass $testlink
send_log "$objdump -d tmpdir/sh2\n"
verbose "$objdump -d tmpdir/sh2"
catch "exec $objdump -d tmpdir/sh2" exec_output
-if [string match "*jsr*" $exec_output] {
+if {[string match "*jsr*" $exec_output]
+ || [string match "*jmp*" $exec_output]} {
fail $testjsr
} else {
pass $testjsr
diff --git a/ld/testsuite/ld-sh/sh1.s b/ld/testsuite/ld-sh/sh1.s
index d18e439..b1f718d 100644
--- a/ld/testsuite/ld-sh/sh1.s
+++ b/ld/testsuite/ld-sh/sh1.s
@@ -4,7 +4,12 @@ L1:
mov.l L2,r0
.uses L1
jsr @r0
+ nop
+ .uses L1
+ jmp @r0
+ nop
rts
+ nop
.align 2
L2:
.long bar
--
1.7.9.5