[PATCH] RISC-V: Print symbol address for jalr w/ zero offset.

Jim Wilson jimw@sifive.com
Sat Jan 6 01:52:00 GMT 2018


If a call sequence is exactly a multiple of 4096 bytes from the target, then we
get a jalr with a zero immediate offset, and the symbol address does not get
printed in the disassembly.  For the included testcase, without the patch, I
get
   11054:	fffff097          	auipc	ra,0xfffff
   11058:	000080e7          	jalr	ra
and with the patch I get
   11054:	fffff097          	auipc	ra,0xfffff
   11058:	000080e7          	jalr	ra # 10054 <_start>
There are 8 instances of this in the compiled linux kernel that I tested the
patch against, which is where the problem was originally noticed.

Since I need a linker to resolve relocations before disassembly, I had to
add a linker testcase for the problem.  This was tested with riscv{32,64} elf
and linux builds.  There were no regressions.

Committed.

Jim

	ld/
	* testsuite/ld-riscv-elf/disas-jalr.d: New.
	* testsuite/ld-riscv-elf/disas-jalr.s: New.
	* testsuite/ld-riscv-elf/ld-riscv-elf.exp: Run new testcase.

	opcodes/
	* riscv-dis.c (print_insn_args) <'s'>: Call maybe_print_address for a
	jalr.
---
 ld/testsuite/ld-riscv-elf/disas-jalr.d     | 13 +++++++++++++
 ld/testsuite/ld-riscv-elf/disas-jalr.s     |  5 +++++
 ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp |  1 +
 opcodes/riscv-dis.c                        |  2 ++
 4 files changed, 21 insertions(+)
 create mode 100644 ld/testsuite/ld-riscv-elf/disas-jalr.d
 create mode 100644 ld/testsuite/ld-riscv-elf/disas-jalr.s

diff --git a/ld/testsuite/ld-riscv-elf/disas-jalr.d b/ld/testsuite/ld-riscv-elf/disas-jalr.d
new file mode 100644
index 0000000000..d523e95092
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/disas-jalr.d
@@ -0,0 +1,13 @@
+#name: jalr zero-offset symbols
+#source: disas-jalr.s
+#ld: --no-relax
+#objdump: -d
+
+.*:[ 	]+file format .*
+
+Disassembly of section \.text:
+
+.* <_start>:
+#...
+.*:[ 	]+fffff097[ 	]+auipc[ 	]+ra,0xfffff
+.*:[ 	]+000080e7[ 	]+jalr[ 	]+ra # .* <_start>
diff --git a/ld/testsuite/ld-riscv-elf/disas-jalr.s b/ld/testsuite/ld-riscv-elf/disas-jalr.s
new file mode 100644
index 0000000000..28ce4780a0
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/disas-jalr.s
@@ -0,0 +1,5 @@
+	.text
+	.globl _start
+_start:
+	.skip 4096
+	call _start
diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
index aaee4ac7bc..5b5d2ea004 100644
--- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
+++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
@@ -21,6 +21,7 @@
 
 if [istarget "riscv*-*-*"] {
     run_dump_test "c-lui"
+    run_dump_test "disas-jalr"
 
     set abis { rv32gc ilp32 elf32lriscv rv64gc lp64 elf64lriscv }
     foreach { arch abi emul } $abis {
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 972cbcfd2f..cc427b4b93 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -226,6 +226,8 @@ print_insn_args (const char *d, insn_t l, bfd_vma pc, disassemble_info *info)
 
 	case 'b':
 	case 's':
+	  if ((l & MASK_JALR) == MATCH_JALR)
+	    maybe_print_address (pd, rs1, 0);
 	  print (info->stream, "%s", riscv_gpr_names[rs1]);
 	  break;
 
-- 
2.14.1



More information about the Binutils mailing list