public inbox for binutils-cvs@sourceware.org
 help / color / mirror / Atom feed
* [binutils-gdb] RISC-V: PR29342, Fix RV32 disassembler address computation
@ 2022-09-02  6:06 Nelson Chu
  0 siblings, 0 replies; only message in thread
From: Nelson Chu @ 2022-09-02  6:06 UTC (permalink / raw)
  To: bfd-cvs

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=48525554d5222d98953202b9252ff65fdead58a4

commit 48525554d5222d98953202b9252ff65fdead58a4
Author: Tsukasa OI <research_trasio@irq.a4lg.com>
Date:   Sat Aug 27 00:11:00 2022 +0000

    RISC-V: PR29342, Fix RV32 disassembler address computation
    
    If either the base register is `zero', `tp' or `gp' and XLEN is 32, an
    incorrectly sign-extended address is produced when printing.  This commit
    fixes this by fitting an address into a 32-bit value on RV32.
    
    Besides, H. Peter Anvin discovered that we have wrong address computation
    for JALR instruction (the initial bug is back in 2018).  This commit also
    fixes that based on the idea of Palmer Dabbelt.
    
    gas/
            pr29342
            * testsuite/gas/riscv/lla32.d: Reflect RV32 address computation fix.
            * testsuite/gas/riscv/dis-addr-overflow.s: New testcase.
            * testsuite/gas/riscv/dis-addr-overflow-32.d: Likewise.
            * testsuite/gas/riscv/dis-addr-overflow-64.d: Likewise.
    opcodes/
            pr29342
            * riscv-dis.c (maybe_print_address): Fit address into 32-bit on RV32.
            (print_insn_args): Fix JALR address by adding EXTRACT_ITYPE_IMM.

Diff:
---
 gas/testsuite/gas/riscv/dis-addr-overflow-32.d | 30 +++++++++++
 gas/testsuite/gas/riscv/dis-addr-overflow-64.d | 34 +++++++++++++
 gas/testsuite/gas/riscv/dis-addr-overflow.s    | 70 ++++++++++++++++++++++++++
 gas/testsuite/gas/riscv/lla32.d                |  2 +-
 opcodes/riscv-dis.c                            |  8 ++-
 5 files changed, 142 insertions(+), 2 deletions(-)

diff --git a/gas/testsuite/gas/riscv/dis-addr-overflow-32.d b/gas/testsuite/gas/riscv/dis-addr-overflow-32.d
new file mode 100644
index 00000000000..43f712a2263
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-overflow-32.d
@@ -0,0 +1,30 @@
+#as: -march=rv32ic
+#source: dis-addr-overflow.s
+#objdump: -d
+
+.*:     file format elf32-(little|big)riscv
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+fffff2b7[ 	]+lui[  	]+t0,0xfffff
+[ 	]+[0-9a-f]+:[ 	]+ffc2a903[ 	]+lw[   	]+s2,-4\(t0\) # ffffeffc <addr_load>
+[ 	]+[0-9a-f]+:[ 	]+ffffe337[ 	]+lui[  	]+t1,0xffffe
+[ 	]+[0-9a-f]+:[ 	]+ff332c23[ 	]+sw[   	]+s3,-8\(t1\) # ffffdff8 <addr_store>
+[ 	]+[0-9a-f]+:[ 	]+ffffd3b7[ 	]+lui[  	]+t2,0xffffd
+[ 	]+[0-9a-f]+:[ 	]+000380e7[ 	]+jalr[ 	]+t2 # ffffd000 <addr_jalr_1>
+[ 	]+[0-9a-f]+:[ 	]+ffffce37[ 	]+lui[  	]+t3,0xffffc
+[ 	]+[0-9a-f]+:[ 	]+ff4e00e7[ 	]+jalr[ 	]+-12\(t3\) # ffffbff4 <addr_jalr_2>
+[ 	]+[0-9a-f]+:[ 	]+ffffbeb7[ 	]+lui[  	]+t4,0xffffb
+[ 	]+[0-9a-f]+:[ 	]+000e8a67[ 	]+jalr[ 	]+s4,t4 # ffffb000 <addr_jalr_3>
+[ 	]+[0-9a-f]+:[ 	]+ffffaf37[ 	]+lui[  	]+t5,0xffffa
+[ 	]+[0-9a-f]+:[ 	]+ff0f0a93[ 	]+addi[ 	]+s5,t5,-16 # ffff9ff0 <addr_loadaddr>
+[ 	]+[0-9a-f]+:[ 	]+ffff9fb7[ 	]+lui[  	]+t6,0xffff9
+[ 	]+[0-9a-f]+:[ 	]+1fb1[ 	]+addi[ 	]+t6,t6,-20 # ffff8fec <addr_loadaddr_c>
+[ 	]+[0-9a-f]+:[ 	]+4001a283[ 	]+lw[   	]+t0,1024\(gp\) # 600 <addr_rel_gp_pos>
+[ 	]+[0-9a-f]+:[ 	]+c001a303[ 	]+lw[   	]+t1,-1024\(gp\) # fffffe00 <addr_rel_gp_neg>
+[ 	]+[0-9a-f]+:[ 	]+10002383[ 	]+lw[   	]+t2,256\(zero\) # 100 <addr_rel_zero_pos>
+[ 	]+[0-9a-f]+:[ 	]+80002e03[ 	]+lw[   	]+t3,-2048\(zero\) # fffff800 <addr_rel_zero_neg>
+[ 	]+[0-9a-f]+:[ 	]+10400ee7[ 	]+jalr[ 	]+t4,260\(zero\) # 104 <addr_jalr_rel_zero_pos>
+[ 	]+[0-9a-f]+:[ 	]+80400f67[ 	]+jalr[ 	]+t5,-2044\(zero\) # fffff804 <addr_jalr_rel_zero_neg>
diff --git a/gas/testsuite/gas/riscv/dis-addr-overflow-64.d b/gas/testsuite/gas/riscv/dis-addr-overflow-64.d
new file mode 100644
index 00000000000..065ee2591e7
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-overflow-64.d
@@ -0,0 +1,34 @@
+#as: -march=rv64ic -defsym rv64=1
+#source: dis-addr-overflow.s
+#objdump: -d
+
+.*:     file format elf64-(little|big)riscv
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+fffff2b7[ 	]+lui[  	]+t0,0xfffff
+[ 	]+[0-9a-f]+:[ 	]+ffc2a903[ 	]+lw[   	]+s2,-4\(t0\) # ffffffffffffeffc <addr_load>
+[ 	]+[0-9a-f]+:[ 	]+ffffe337[ 	]+lui[  	]+t1,0xffffe
+[ 	]+[0-9a-f]+:[ 	]+ff332c23[ 	]+sw[   	]+s3,-8\(t1\) # ffffffffffffdff8 <addr_store>
+[ 	]+[0-9a-f]+:[ 	]+ffffd3b7[ 	]+lui[  	]+t2,0xffffd
+[ 	]+[0-9a-f]+:[ 	]+000380e7[ 	]+jalr[ 	]+t2 # ffffffffffffd000 <addr_jalr_1>
+[ 	]+[0-9a-f]+:[ 	]+ffffce37[ 	]+lui[  	]+t3,0xffffc
+[ 	]+[0-9a-f]+:[ 	]+ff4e00e7[ 	]+jalr[ 	]+-12\(t3\) # ffffffffffffbff4 <addr_jalr_2>
+[ 	]+[0-9a-f]+:[ 	]+ffffbeb7[ 	]+lui[  	]+t4,0xffffb
+[ 	]+[0-9a-f]+:[ 	]+000e8a67[ 	]+jalr[ 	]+s4,t4 # ffffffffffffb000 <addr_jalr_3>
+[ 	]+[0-9a-f]+:[ 	]+ffffaf37[ 	]+lui[  	]+t5,0xffffa
+[ 	]+[0-9a-f]+:[ 	]+ff0f0a93[ 	]+addi[ 	]+s5,t5,-16 # ffffffffffff9ff0 <addr_loadaddr>
+[ 	]+[0-9a-f]+:[ 	]+ffff9fb7[ 	]+lui[  	]+t6,0xffff9
+[ 	]+[0-9a-f]+:[ 	]+1fb1[ 	]+addi[ 	]+t6,t6,-20 # ffffffffffff8fec <addr_loadaddr_c>
+[ 	]+[0-9a-f]+:[ 	]+ffff8b37[ 	]+lui[  	]+s6,0xffff8
+[ 	]+[0-9a-f]+:[ 	]+fe8b0b9b[ 	]+addiw[ 	]+s7,s6,-24 # ffffffffffff7fe8 <addr_loadaddr_w>
+[ 	]+[0-9a-f]+:[ 	]+ffff7c37[ 	]+lui[  	]+s8,0xffff7
+[ 	]+[0-9a-f]+:[ 	]+3c11[ 	]+addiw[ 	]+s8,s8,-28 # ffffffffffff6fe4 <addr_loadaddr_w_c>
+[ 	]+[0-9a-f]+:[ 	]+4001a283[ 	]+lw[   	]+t0,1024\(gp\) # 600 <addr_rel_gp_pos>
+[ 	]+[0-9a-f]+:[ 	]+c001a303[ 	]+lw[   	]+t1,-1024\(gp\) # fffffffffffffe00 <addr_rel_gp_neg>
+[ 	]+[0-9a-f]+:[ 	]+10002383[ 	]+lw[   	]+t2,256\(zero\) # 100 <addr_rel_zero_pos>
+[ 	]+[0-9a-f]+:[ 	]+80002e03[ 	]+lw[   	]+t3,-2048\(zero\) # fffffffffffff800 <addr_rel_zero_neg>
+[ 	]+[0-9a-f]+:[ 	]+10400ee7[ 	]+jalr[ 	]+t4,260\(zero\) # 104 <addr_jalr_rel_zero_pos>
+[ 	]+[0-9a-f]+:[ 	]+80400f67[ 	]+jalr[ 	]+t5,-2044\(zero\) # fffffffffffff804 <addr_jalr_rel_zero_neg>
diff --git a/gas/testsuite/gas/riscv/dis-addr-overflow.s b/gas/testsuite/gas/riscv/dis-addr-overflow.s
new file mode 100644
index 00000000000..77ca39c07b6
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-overflow.s
@@ -0,0 +1,70 @@
+.set __global_pointer$, 0x00000200
+
+.ifdef rv64
+topbase = 0xffffffff00000000
+.else
+topbase = 0
+.endif
+
+.set addr_load,              topbase + 0xffffeffc  # -0x1000 -4
+.set addr_store,             topbase + 0xffffdff8  # -0x2000 -8
+.set addr_jalr_1,            topbase + 0xffffd000  # -0x3000
+.set addr_jalr_2,            topbase + 0xffffbff4  # -0x4000 -12
+.set addr_jalr_3,            topbase + 0xffffb000  # -0x5000
+.set addr_loadaddr,          topbase + 0xffff9ff0  # -0x6000 -16
+.set addr_loadaddr_c,        topbase + 0xffff8fec  # -0x7000 -20
+.set addr_loadaddr_w,        topbase + 0xffff7fe8  # -0x8000 -24
+.set addr_loadaddr_w_c,      topbase + 0xffff6fe4  # -0x9000 -28
+.set addr_rel_gp_pos,                  0x00000600  # __global_pointer$ + 0x400
+.set addr_rel_gp_neg,        topbase + 0xfffffe00  # __global_pointer$ - 0x400
+.set addr_rel_zero_pos,                0x00000100
+.set addr_rel_zero_neg,      topbase + 0xfffff800  # -0x800
+.set addr_jalr_rel_zero_pos,           0x00000104
+.set addr_jalr_rel_zero_neg, topbase + 0xfffff804  # -0x7fc
+
+target:
+	.option	push
+	.option	arch, -c
+	## Use hi_addr
+	# Load
+	lui	t0, 0xfffff
+	lw	s2, -4(t0)
+	# Store
+	lui	t1, 0xffffe
+	sw	s3, -8(t1)
+	# JALR (implicit destination, no offset)
+	lui	t2, 0xffffd
+	jalr	t2
+	# JALR (implicit destination, with offset)
+	lui	t3, 0xffffc
+	jalr	-12(t3)
+	# JALR (explicit destination, no offset)
+	lui	t4, 0xffffb
+	jalr	s4, t4
+	# ADDI (not compressed)
+	lui	t5, 0xffffa
+	addi	s5, t5, -16
+	# C.ADDI
+	lui	t6, 0xffff9
+	.option	pop
+	c.addi	t6, -20
+.ifdef rv64
+	.option	push
+	.option	arch, -c
+	# ADDIW (not compressed)
+	lui	s6, 0xffff8
+	addiw	s7, s6, -24
+	# C.ADDIW
+	lui	s8, 0xffff7
+	.option	pop
+	c.addiw	s8, -28
+.endif
+
+	# Use addresses relative to gp
+	lw	t0, 0x400(gp)
+	lw	t1, -0x400(gp)
+	# Use addresses relative to zero
+	lw	t2, 0x100(zero)
+	lw	t3, -0x800(zero)
+	jalr	t4, 0x104(zero)
+	jalr	t5, -0x7fc(zero)
diff --git a/gas/testsuite/gas/riscv/lla32.d b/gas/testsuite/gas/riscv/lla32.d
index 9d875629064..8e9324c1c96 100644
--- a/gas/testsuite/gas/riscv/lla32.d
+++ b/gas/testsuite/gas/riscv/lla32.d
@@ -14,6 +14,6 @@ Disassembly of section .text:
   10:	00001537          	lui	a0,0x1
   14:	fff50513          	addi	a0,a0,-1 # fff <d>
   18:	80000537          	lui	a0,0x80000
-  1c:	fff50513          	addi	a0,a0,-1 # 7fffffff <h\+0x80000000>
+  1c:	fff50513          	addi	a0,a0,-1 # 7fffffff <e>
   20:	00000513          	li	a0,0
   24:	fff00513          	li	a0,-1
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 164fd209dbd..b3ca680e506 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -181,10 +181,16 @@ maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
     pd->print_addr = pd->gp + offset;
   else if (base_reg == X_TP || base_reg == 0)
     pd->print_addr = offset;
+  else
+    return;  /* Don't print the address.  */
 
   /* Sign-extend a 32-bit value to a 64-bit value.  */
   if (wide)
     pd->print_addr = (bfd_vma)(int32_t) pd->print_addr;
+
+  /* Fit into a 32-bit value on RV32.  */
+  if (xlen == 32)
+    pd->print_addr = (bfd_vma)(uint32_t)pd->print_addr;
 }
 
 /* Print insn arguments for 32/64-bit code.  */
@@ -397,7 +403,7 @@ print_insn_args (const char *oparg, 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, 0);
+	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0);
 	  print (info->stream, dis_style_register, "%s", riscv_gpr_names[rs1]);
 	  break;

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-09-02  6:06 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-02  6:06 [binutils-gdb] RISC-V: PR29342, Fix RV32 disassembler address computation Nelson Chu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).