This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] [SH] Fix PR 10373


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]