public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 0/3] RISC-V: Fix address printer on the disassembler
@ 2022-07-29 13:10 Tsukasa OI
  2022-07-29 13:10 ` [PATCH 1/3] RISC-V: Print highest address on disassembler Tsukasa OI
                   ` (3 more replies)
  0 siblings, 4 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-07-29 13:10 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

Hello,

This patchset contains a fix to PR29342.

Tracker on GitHub:
<https://github.com/a4lg/binutils-gdb/wiki/riscv_dis_fix_addr>

Original Issue as reported by H. Peter Anvin:
<https://sourceware.org/bugzilla/show_bug.cgi?id=29342>

First of all, this bug is caused by address computation of maybe_print_address
on disassembling RV32 programs.

Let me show the pseudocode of `maybe_print_address':

    if (high part of the register [for address sequence] is set)
    {
        pd->print_addr = (high part) + offset;        // (1)
        unset high part (as used);
    }
    else if (base register == `gp' && __global_pointer$ is available)
        pd->print_addr = __global_pointer$ + offset;  // (2)
    else if (base register == `tp' || base register == `zero')
        pd->print_addr = offset;                      // (3)
    // Sign-extend a 32-bit value to 64-bit
    if (instruction is ADDIW or C.ADDIW)
        pd->print_addr = (bfd_vma)(int32_t)pd->print_addr;

In here, it implicitly sign-extends an `int'-typed variable `offset' to generate
an address.  (3) is the direct cause of PR29342 but other locations have
similar issue.

On an example provided by Peter, IOREG_FOO has an address value of 0xffffff00.
However, due to incorrect sign-extension, the disassembler considers that the
`sw' instruction operates on an incorrect address 0xffffffff_ffffff00 EVEN ON
RV32.  This affects symbol lookup.  So, we have to mask (and zero-extend) the
address on RV32 to get correct address 0xffffff00.

Also, the background provided by Peter gives us a context: highest address space
may be important for some systems/programs.  So, not only fixing PR29342, I
decided to make the address -1 (originally reserved as a non-printing address)
printable by separating (a) the address to print and (b) whether the address
should be printed.  This isn't zero-overhead but close to.

This patchset:

1.  fits an address into a 32-bit value on RV32 (resolves PR29342)
2.  makes the highest address printable
    (0xffffffff can be printed as a real symbol)
3.  clarifies the meaning of the `wide' argument
    (`is_addiw' fits the context).

It also has new testcases and a testcase modification (it seems lla32.d is
affected by this patchset but not harmful so that modifying the testcase
lla32.d seemed better).

Thanks,
Tsukasa




Tsukasa OI (3):
  RISC-V: Print highest address on disassembler
  RISC-V: Fix RV32 disassembler address computation
  RISC-V: Add address printer tests on disassembler

 gas/testsuite/gas/riscv/dis-addr-1-32.d | 29 ++++++++++
 gas/testsuite/gas/riscv/dis-addr-1-64.d | 33 ++++++++++++
 gas/testsuite/gas/riscv/dis-addr-1.s    | 70 +++++++++++++++++++++++++
 gas/testsuite/gas/riscv/lla32.d         |  2 +-
 opcodes/riscv-dis.c                     | 34 +++++++-----
 5 files changed, 154 insertions(+), 14 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-1-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-1-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-1.s


base-commit: b245c595aaa59812f8f3a0e8b70ea5f52e045627
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH 1/3] RISC-V: Print highest address on disassembler
  2022-07-29 13:10 [PATCH 0/3] RISC-V: Fix address printer on the disassembler Tsukasa OI
@ 2022-07-29 13:10 ` Tsukasa OI
  2022-07-29 13:10 ` [PATCH 2/3] RISC-V: Fix RV32 disassembler address computation Tsukasa OI
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-07-29 13:10 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

This patch makes possible to print the highest address (0xffffffff on RV32,
0xffffffff_ffffffff on RV64).  This is particularly useful if the highest
address space is used for I/O registers and corresponding symbols
are defined.

opcodes/ChangeLog:

	* riscv-dis.c (struct riscv_private_data): Add `to_print_addr' to
	enable printing the highest address.
	(maybe_print_address): Utilize `to_print_addr'.
	(riscv_disassemble_insn): Likewise.
---
 opcodes/riscv-dis.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 164fd209dbd..31a7e0975d2 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -52,6 +52,7 @@ struct riscv_private_data
   bfd_vma gp;
   bfd_vma print_addr;
   bfd_vma hi_addr[OP_MASK_RD + 1];
+  bool to_print_addr;
 };
 
 /* Used for mapping symbols.  */
@@ -181,6 +182,9 @@ 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;
+  pd->to_print_addr = true;
 
   /* Sign-extend a 32-bit value to a 64-bit value.  */
   if (wide)
@@ -596,7 +600,7 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
 
       pd = info->private_data = xcalloc (1, sizeof (struct riscv_private_data));
       pd->gp = -1;
-      pd->print_addr = -1;
+      pd->to_print_addr = false;
       for (i = 0; i < (int)ARRAY_SIZE (pd->hi_addr); i++)
 	pd->hi_addr[i] = -1;
 
@@ -662,13 +666,13 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
 	  print_insn_args (op->args, word, memaddr, info);
 
 	  /* Try to disassemble multi-instruction addressing sequences.  */
-	  if (pd->print_addr != (bfd_vma)-1)
+	  if (pd->to_print_addr)
 	    {
 	      info->target = pd->print_addr;
 	      (*info->fprintf_styled_func)
 		(info->stream, dis_style_comment_start, " # ");
 	      (*info->print_address_func) (info->target, info);
-	      pd->print_addr = -1;
+	      pd->to_print_addr = false;
 	    }
 
 	  /* Finish filling out insn_info fields.  */
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH 2/3] RISC-V: Fix RV32 disassembler address computation
  2022-07-29 13:10 [PATCH 0/3] RISC-V: Fix address printer on the disassembler Tsukasa OI
  2022-07-29 13:10 ` [PATCH 1/3] RISC-V: Print highest address on disassembler Tsukasa OI
@ 2022-07-29 13:10 ` Tsukasa OI
  2022-07-29 13:10 ` [PATCH 3/3] RISC-V: Add address printer tests on disassembler Tsukasa OI
  2022-08-02  5:54 ` [PATCH v2 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
  3 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-07-29 13:10 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

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 bug (including PR29342) by fitting an address into a 32-bit value
on RV32.

gas/ChangeLog:

	* testsuite/gas/riscv/lla32.d: Reflect RV32 address computation fix.

opcodes/ChangeLog:

	* riscv-dis.c (maybe_print_address): Clarify the role of the `wide'
	argument and rename to `is_addiw'.  Fit the address into 32-bit on
	RV32.  (print_insn_args): Reflect bool type of `is_addiw'.
---
 gas/testsuite/gas/riscv/lla32.d |  2 +-
 opcodes/riscv-dis.c             | 24 ++++++++++++++----------
 2 files changed, 15 insertions(+), 11 deletions(-)

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 31a7e0975d2..83438db5fe3 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -171,7 +171,7 @@ arg_print (struct disassemble_info *info, unsigned long val,
 
 static void
 maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
-		     int wide)
+		     bool is_addiw)
 {
   if (pd->hi_addr[base_reg] != (bfd_vma)-1)
     {
@@ -186,9 +186,13 @@ maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
     return;
   pd->to_print_addr = true;
 
-  /* Sign-extend a 32-bit value to a 64-bit value.  */
-  if (wide)
+  /* On ADDIW, Sign-extend a 32-bit value to a 64-bit value.  */
+  if (is_addiw)
     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.  */
@@ -238,10 +242,10 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	    case 'o':
 	    case 'j':
 	      if (((l & MASK_C_ADDI) == MATCH_C_ADDI) && rd != 0)
-		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), 0);
+		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), false);
 	      if (info->mach == bfd_mach_riscv64
 		  && ((l & MASK_C_ADDIW) == MATCH_C_ADDIW) && rd != 0)
-		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), 1);
+		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), true);
 	      print (info->stream, dis_style_immediate, "%d",
 		     (int)EXTRACT_CITYPE_IMM (l));
 	      break;
@@ -401,7 +405,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, 0, false);
 	  print (info->stream, dis_style_register, "%s", riscv_gpr_names[rs1]);
 	  break;
 
@@ -431,21 +435,21 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	  break;
 
 	case 'o':
-	  maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0);
+	  maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), false);
 	  /* Fall through.  */
 	case 'j':
 	  if (((l & MASK_ADDI) == MATCH_ADDI && rs1 != 0)
 	      || (l & MASK_JALR) == MATCH_JALR)
-	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0);
+	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), false);
 	  if (info->mach == bfd_mach_riscv64
 	      && ((l & MASK_ADDIW) == MATCH_ADDIW) && rs1 != 0)
-	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 1);
+	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), true);
 	  print (info->stream, dis_style_immediate, "%d",
 		 (int)EXTRACT_ITYPE_IMM (l));
 	  break;
 
 	case 'q':
-	  maybe_print_address (pd, rs1, EXTRACT_STYPE_IMM (l), 0);
+	  maybe_print_address (pd, rs1, EXTRACT_STYPE_IMM (l), false);
 	  print (info->stream, dis_style_address_offset, "%d",
 		 (int)EXTRACT_STYPE_IMM (l));
 	  break;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH 3/3] RISC-V: Add address printer tests on disassembler
  2022-07-29 13:10 [PATCH 0/3] RISC-V: Fix address printer on the disassembler Tsukasa OI
  2022-07-29 13:10 ` [PATCH 1/3] RISC-V: Print highest address on disassembler Tsukasa OI
  2022-07-29 13:10 ` [PATCH 2/3] RISC-V: Fix RV32 disassembler address computation Tsukasa OI
@ 2022-07-29 13:10 ` Tsukasa OI
  2022-08-02  5:54 ` [PATCH v2 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
  3 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-07-29 13:10 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

This commit adds address printer tests on the disassembler focusing on
various path to/on maybe_print_address.  It also tests whether the address
adjustment on RV32 (fix to PR29342) works as expected and whether the
highest address is printed with a symbol.

gas/ChangeLog:

	* testsuite/gas/riscv/dis-addr-1.s: New address printer tests
	on the disassembler.
	* testsuite/gas/riscv/dis-addr-1-32.d: Likewise.
	* testsuite/gas/riscv/dis-addr-1-64.d: Likewise.
---
 gas/testsuite/gas/riscv/dis-addr-1-32.d | 29 ++++++++++
 gas/testsuite/gas/riscv/dis-addr-1-64.d | 33 ++++++++++++
 gas/testsuite/gas/riscv/dis-addr-1.s    | 70 +++++++++++++++++++++++++
 3 files changed, 132 insertions(+)
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-1-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-1-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-1.s

diff --git a/gas/testsuite/gas/riscv/dis-addr-1-32.d b/gas/testsuite/gas/riscv/dis-addr-1-32.d
new file mode 100644
index 00000000000..457e6e12600
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-1-32.d
@@ -0,0 +1,29 @@
+#as: -march=rv32ic
+#source: dis-addr-1.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]+:[ 	]+fff00e83[ 	]+lb[   	]+t4,-1\(zero\) # ffffffff <addr_top>
diff --git a/gas/testsuite/gas/riscv/dis-addr-1-64.d b/gas/testsuite/gas/riscv/dis-addr-1-64.d
new file mode 100644
index 00000000000..78b03575c8c
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-1-64.d
@@ -0,0 +1,33 @@
+#as: -march=rv64ic -defsym rv64=1
+#source: dis-addr-1.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]+:[ 	]+fff00e83[ 	]+lb[   	]+t4,-1\(zero\) # ffffffffffffffff <addr_top>
diff --git a/gas/testsuite/gas/riscv/dis-addr-1.s b/gas/testsuite/gas/riscv/dis-addr-1.s
new file mode 100644
index 00000000000..492573be9bf
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-1.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_top,          topbase + 0xffffffff  # -1
+
+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)
+
+	# Access the highest address
+	lb	t4, -1(zero)
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v2 0/4] RISC-V: Fix address printer on the disassembler
  2022-07-29 13:10 [PATCH 0/3] RISC-V: Fix address printer on the disassembler Tsukasa OI
                   ` (2 preceding siblings ...)
  2022-07-29 13:10 ` [PATCH 3/3] RISC-V: Add address printer tests on disassembler Tsukasa OI
@ 2022-08-02  5:54 ` Tsukasa OI
  2022-08-02  5:54   ` [PATCH v2 1/4] RISC-V: Print highest address on disassembler Tsukasa OI
                     ` (4 more replies)
  3 siblings, 5 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-02  5:54 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

Hello,

This patchset contains a fix to PR29342.

Tracker on GitHub:
<https://github.com/a4lg/binutils-gdb/wiki/riscv_dis_fix_addr>

Original Issue as reported by H. Peter Anvin:
<https://sourceware.org/bugzilla/show_bug.cgi?id=29342>



[Changes: v1 -> v2]

-   Also allow `gp'-base symbol (__global_pointer$) to be the highest address
-   Add minor optimization (break early if multiple __global_pointer$ is found)
-   Rebase and minor copyediting



[Performance Analysis (Summary)]

This patch alone degrades the disassembler performance a bit (usually about 1%
but around 4% on binary files) but I found my next batch of the disassembler
optimization patchset somehow shadows this.  In fact, Binutils with my
optimization patchset 1 and Binutils with my optimization patchset 1 plus this
patchset has pretty much the same performance.



[Cover Letter from v1]

First of all, this bug is caused by address computation of maybe_print_address
on disassembling RV32 programs.

Let me show the pseudocode of `maybe_print_address':

    if (high part of the register [for address sequence] is set)
    {
        pd->print_addr = (high part) + offset;        // (1)
        unset high part (as used);
    }
    else if (base register == `gp' && __global_pointer$ is available)
        pd->print_addr = __global_pointer$ + offset;  // (2)
    else if (base register == `tp' || base register == `zero')
        pd->print_addr = offset;                      // (3)
    // Sign-extend a 32-bit value to 64-bit
    if (instruction is ADDIW or C.ADDIW)
        pd->print_addr = (bfd_vma)(int32_t)pd->print_addr;

In here, it implicitly sign-extends an `int'-typed variable `offset' to generate
an address.  (3) is the direct cause of PR29342 but other locations have
similar issue.

On an example provided by Peter, IOREG_FOO has an address value of 0xffffff00.
However, due to incorrect sign-extension, the disassembler considers that the
`sw' instruction operates on an incorrect address 0xffffffff_ffffff00 EVEN ON
RV32.  This affects symbol lookup.  So, we have to mask (and zero-extend) the
address on RV32 to get correct address 0xffffff00.

Also, the background provided by Peter gives us a context: highest address space
may be important for some systems/programs.  So, not only fixing PR29342, I
decided to make the address -1 (originally reserved as a non-printing address)
printable by separating (a) the address to print and (b) whether the address
should be printed.  This isn't zero-overhead but close to.

This patchset:

1.  fits an address into a 32-bit value on RV32 (resolves PR29342)
2.  makes the highest address printable
    (0xffffffff can be printed as a real symbol)
3.  clarifies the meaning of the `wide' argument
    (`is_addiw' fits the context).

It also has new testcases and a testcase modification (it seems lla32.d is
affected by this patchset but not harmful so that modifying the testcase
lla32.d seemed better).

Thanks,
Tsukasa




Tsukasa OI (4):
  RISC-V: Print highest address on disassembler
  RISC-V: Fix RV32 disassembler address computation
  RISC-V: Break early if RISCV_GP_SYMBOL is found
  RISC-V: Add address printer tests on disassembler

 gas/testsuite/gas/riscv/dis-addr-1-32.d | 29 ++++++++++
 gas/testsuite/gas/riscv/dis-addr-1-64.d | 33 ++++++++++++
 gas/testsuite/gas/riscv/dis-addr-1.s    | 70 +++++++++++++++++++++++++
 gas/testsuite/gas/riscv/dis-addr-2-32.d | 12 +++++
 gas/testsuite/gas/riscv/dis-addr-2-64.d | 12 +++++
 gas/testsuite/gas/riscv/dis-addr-2.s    | 15 ++++++
 gas/testsuite/gas/riscv/lla32.d         |  2 +-
 opcodes/riscv-dis.c                     | 47 +++++++++++------
 8 files changed, 203 insertions(+), 17 deletions(-)
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-1-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-1-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-1.s
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2.s


base-commit: f493c2174ef99a43c0a5d89179122f857955d738
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v2 1/4] RISC-V: Print highest address on disassembler
  2022-08-02  5:54 ` [PATCH v2 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
@ 2022-08-02  5:54   ` Tsukasa OI
  2022-08-02  5:54   ` [PATCH v2 2/4] RISC-V: Fix RV32 disassembler address computation Tsukasa OI
                     ` (3 subsequent siblings)
  4 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-02  5:54 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

This patch makes possible to print the highest address (0xffffffff on RV32,
0xffffffff_ffffffff on RV64).  This is particularly useful if the highest
address space is used for I/O registers and corresponding symbols
are defined.

opcodes/ChangeLog:

	* riscv-dis.c (struct riscv_private_data): Add `to_print_addr' and
	`has_gp' to enable printing the highest address.
	(maybe_print_address): Utilize `to_print_addr' and `has_gp'.
	(riscv_disassemble_insn): Likewise.
---
 opcodes/riscv-dis.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 164fd209dbd..c6d80c3ba49 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -52,6 +52,8 @@ struct riscv_private_data
   bfd_vma gp;
   bfd_vma print_addr;
   bfd_vma hi_addr[OP_MASK_RD + 1];
+  bool to_print_addr;
+  bool has_gp;
 };
 
 /* Used for mapping symbols.  */
@@ -177,10 +179,13 @@ maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
       pd->print_addr = (base_reg != 0 ? pd->hi_addr[base_reg] : 0) + offset;
       pd->hi_addr[base_reg] = -1;
     }
-  else if (base_reg == X_GP && pd->gp != (bfd_vma)-1)
+  else if (base_reg == X_GP && pd->has_gp)
     pd->print_addr = pd->gp + offset;
   else if (base_reg == X_TP || base_reg == 0)
     pd->print_addr = offset;
+  else
+    return;
+  pd->to_print_addr = true;
 
   /* Sign-extend a 32-bit value to a 64-bit value.  */
   if (wide)
@@ -595,14 +600,19 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
       int i;
 
       pd = info->private_data = xcalloc (1, sizeof (struct riscv_private_data));
-      pd->gp = -1;
-      pd->print_addr = -1;
+      pd->gp = 0;
+      pd->print_addr = 0;
       for (i = 0; i < (int)ARRAY_SIZE (pd->hi_addr); i++)
 	pd->hi_addr[i] = -1;
+      pd->to_print_addr = false;
+      pd->has_gp = false;
 
       for (i = 0; i < info->symtab_size; i++)
 	if (strcmp (bfd_asymbol_name (info->symtab[i]), RISCV_GP_SYMBOL) == 0)
-	  pd->gp = bfd_asymbol_value (info->symtab[i]);
+	  {
+	    pd->gp = bfd_asymbol_value (info->symtab[i]);
+	    pd->has_gp = true;
+	  }
     }
   else
     pd = info->private_data;
@@ -662,13 +672,13 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
 	  print_insn_args (op->args, word, memaddr, info);
 
 	  /* Try to disassemble multi-instruction addressing sequences.  */
-	  if (pd->print_addr != (bfd_vma)-1)
+	  if (pd->to_print_addr)
 	    {
 	      info->target = pd->print_addr;
 	      (*info->fprintf_styled_func)
 		(info->stream, dis_style_comment_start, " # ");
 	      (*info->print_address_func) (info->target, info);
-	      pd->print_addr = -1;
+	      pd->to_print_addr = false;
 	    }
 
 	  /* Finish filling out insn_info fields.  */
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v2 2/4] RISC-V: Fix RV32 disassembler address computation
  2022-08-02  5:54 ` [PATCH v2 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
  2022-08-02  5:54   ` [PATCH v2 1/4] RISC-V: Print highest address on disassembler Tsukasa OI
@ 2022-08-02  5:54   ` Tsukasa OI
  2022-08-02  5:54   ` [PATCH v2 3/4] RISC-V: Break early if RISCV_GP_SYMBOL is found Tsukasa OI
                     ` (2 subsequent siblings)
  4 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-02  5:54 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

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 bug (including PR29342) by fitting an address into a 32-bit value
on RV32.

gas/ChangeLog:

	* testsuite/gas/riscv/lla32.d: Reflect RV32 address computation fix.

opcodes/ChangeLog:

	* riscv-dis.c (maybe_print_address): Clarify the role of the `wide'
	argument and rename to `is_addiw'.  Fit the address into 32-bit on
	RV32.  (print_insn_args): Reflect bool type of `is_addiw'.
---
 gas/testsuite/gas/riscv/lla32.d |  2 +-
 opcodes/riscv-dis.c             | 24 ++++++++++++++----------
 2 files changed, 15 insertions(+), 11 deletions(-)

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 c6d80c3ba49..419c4746db9 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -172,7 +172,7 @@ arg_print (struct disassemble_info *info, unsigned long val,
 
 static void
 maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
-		     int wide)
+		     bool is_addiw)
 {
   if (pd->hi_addr[base_reg] != (bfd_vma)-1)
     {
@@ -187,9 +187,13 @@ maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
     return;
   pd->to_print_addr = true;
 
-  /* Sign-extend a 32-bit value to a 64-bit value.  */
-  if (wide)
+  /* On ADDIW, Sign-extend a 32-bit value to a 64-bit value.  */
+  if (is_addiw)
     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.  */
@@ -239,10 +243,10 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	    case 'o':
 	    case 'j':
 	      if (((l & MASK_C_ADDI) == MATCH_C_ADDI) && rd != 0)
-		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), 0);
+		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), false);
 	      if (info->mach == bfd_mach_riscv64
 		  && ((l & MASK_C_ADDIW) == MATCH_C_ADDIW) && rd != 0)
-		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), 1);
+		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), true);
 	      print (info->stream, dis_style_immediate, "%d",
 		     (int)EXTRACT_CITYPE_IMM (l));
 	      break;
@@ -402,7 +406,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, 0, false);
 	  print (info->stream, dis_style_register, "%s", riscv_gpr_names[rs1]);
 	  break;
 
@@ -432,21 +436,21 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	  break;
 
 	case 'o':
-	  maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0);
+	  maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), false);
 	  /* Fall through.  */
 	case 'j':
 	  if (((l & MASK_ADDI) == MATCH_ADDI && rs1 != 0)
 	      || (l & MASK_JALR) == MATCH_JALR)
-	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0);
+	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), false);
 	  if (info->mach == bfd_mach_riscv64
 	      && ((l & MASK_ADDIW) == MATCH_ADDIW) && rs1 != 0)
-	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 1);
+	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), true);
 	  print (info->stream, dis_style_immediate, "%d",
 		 (int)EXTRACT_ITYPE_IMM (l));
 	  break;
 
 	case 'q':
-	  maybe_print_address (pd, rs1, EXTRACT_STYPE_IMM (l), 0);
+	  maybe_print_address (pd, rs1, EXTRACT_STYPE_IMM (l), false);
 	  print (info->stream, dis_style_address_offset, "%d",
 		 (int)EXTRACT_STYPE_IMM (l));
 	  break;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v2 3/4] RISC-V: Break early if RISCV_GP_SYMBOL is found
  2022-08-02  5:54 ` [PATCH v2 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
  2022-08-02  5:54   ` [PATCH v2 1/4] RISC-V: Print highest address on disassembler Tsukasa OI
  2022-08-02  5:54   ` [PATCH v2 2/4] RISC-V: Fix RV32 disassembler address computation Tsukasa OI
@ 2022-08-02  5:54   ` Tsukasa OI
  2022-08-02  5:54   ` [PATCH v2 4/4] RISC-V: Add address printer tests on disassembler Tsukasa OI
  2022-08-04  4:35   ` [PATCH v3 0/3] RISC-V: Fix address printer on the disassembler Tsukasa OI
  4 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-02  5:54 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

If RISCV_GP_SYMBOL ("__global_pointer$") is found multiple times, it's
definately something is going wrong *for the disassembler* (note: would not
make the resulting ELF files invalid but at least confuses the disassembler)
and the disassembler will not produce the consistent result.

If so, it would be okay to just ignore second RISCV_GP_SYMBOL to make symbol
lookup slightly faster.  With this commit, the disassembler just breaks
early when a RISCV_GP_SYMBOL is found.

opcodes/ChangeLog:

	* riscv-dis.c (riscv_disassemble_insn): Break early if a
	RISCV_GP_SYMBOL is found.
---
 opcodes/riscv-dis.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 419c4746db9..3fd2b5a4ada 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -616,6 +616,7 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
 	  {
 	    pd->gp = bfd_asymbol_value (info->symtab[i]);
 	    pd->has_gp = true;
+	    break;
 	  }
     }
   else
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v2 4/4] RISC-V: Add address printer tests on disassembler
  2022-08-02  5:54 ` [PATCH v2 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
                     ` (2 preceding siblings ...)
  2022-08-02  5:54   ` [PATCH v2 3/4] RISC-V: Break early if RISCV_GP_SYMBOL is found Tsukasa OI
@ 2022-08-02  5:54   ` Tsukasa OI
  2022-08-04  4:35   ` [PATCH v3 0/3] RISC-V: Fix address printer on the disassembler Tsukasa OI
  4 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-02  5:54 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

This commit adds address printer tests on the disassembler focusing on
various path to/on maybe_print_address.  It also tests whether the address
adjustment on RV32 (fix to PR29342) works as expected and whether the
highest address is printed with a symbol.

gas/ChangeLog:

	* testsuite/gas/riscv/dis-addr-1.s: New address printer tests
	on the disassembler.
	* testsuite/gas/riscv/dis-addr-1-32.d: Likewise.
	* testsuite/gas/riscv/dis-addr-1-64.d: Likewise.
	* testsuite/gas/riscv/dis-addr-2.s: New address printer tests
	on the disassembler if `gp' is the highest address.
	* testsuite/gas/riscv/dis-addr-2-32.d: Likewise.
	* testsuite/gas/riscv/dis-addr-2-64.d: Likewise.
---
 gas/testsuite/gas/riscv/dis-addr-1-32.d | 29 ++++++++++
 gas/testsuite/gas/riscv/dis-addr-1-64.d | 33 ++++++++++++
 gas/testsuite/gas/riscv/dis-addr-1.s    | 70 +++++++++++++++++++++++++
 gas/testsuite/gas/riscv/dis-addr-2-32.d | 12 +++++
 gas/testsuite/gas/riscv/dis-addr-2-64.d | 12 +++++
 gas/testsuite/gas/riscv/dis-addr-2.s    | 15 ++++++
 6 files changed, 171 insertions(+)
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-1-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-1-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-1.s
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2.s

diff --git a/gas/testsuite/gas/riscv/dis-addr-1-32.d b/gas/testsuite/gas/riscv/dis-addr-1-32.d
new file mode 100644
index 00000000000..457e6e12600
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-1-32.d
@@ -0,0 +1,29 @@
+#as: -march=rv32ic
+#source: dis-addr-1.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]+:[ 	]+fff00e83[ 	]+lb[   	]+t4,-1\(zero\) # ffffffff <addr_top>
diff --git a/gas/testsuite/gas/riscv/dis-addr-1-64.d b/gas/testsuite/gas/riscv/dis-addr-1-64.d
new file mode 100644
index 00000000000..78b03575c8c
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-1-64.d
@@ -0,0 +1,33 @@
+#as: -march=rv64ic -defsym rv64=1
+#source: dis-addr-1.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]+:[ 	]+fff00e83[ 	]+lb[   	]+t4,-1\(zero\) # ffffffffffffffff <addr_top>
diff --git a/gas/testsuite/gas/riscv/dis-addr-1.s b/gas/testsuite/gas/riscv/dis-addr-1.s
new file mode 100644
index 00000000000..328fa04eb34
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-1.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_top,          topbase + 0xffffffff  # -1
+
+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)
+
+	# Access to the highest address
+	lb	t4, -1(zero)
diff --git a/gas/testsuite/gas/riscv/dis-addr-2-32.d b/gas/testsuite/gas/riscv/dis-addr-2-32.d
new file mode 100644
index 00000000000..0f784dd7dad
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-2-32.d
@@ -0,0 +1,12 @@
+#as: -march=rv32i
+#source: dis-addr-2.s
+#objdump: -d
+
+.*:     file format elf32-(little|big)riscv
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+0051a283[ 	]+lw[   	]+t0,5\(gp\) # 4 <addr_rel_gp_pos>
+[ 	]+[0-9a-f]+:[ 	]+ffd1a303[ 	]+lw[   	]+t1,-3\(gp\) # fffffffc <addr_rel_gp_neg>
diff --git a/gas/testsuite/gas/riscv/dis-addr-2-64.d b/gas/testsuite/gas/riscv/dis-addr-2-64.d
new file mode 100644
index 00000000000..0bfd10809be
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-2-64.d
@@ -0,0 +1,12 @@
+#as: -march=rv64i -defsym rv64=1
+#source: dis-addr-2.s
+#objdump: -d
+
+.*:     file format elf64-(little|big)riscv
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+0051a283[ 	]+lw[   	]+t0,5\(gp\) # 4 <addr_rel_gp_pos>
+[ 	]+[0-9a-f]+:[ 	]+ffd1a303[ 	]+lw[   	]+t1,-3\(gp\) # fffffffffffffffc <addr_rel_gp_neg>
diff --git a/gas/testsuite/gas/riscv/dis-addr-2.s b/gas/testsuite/gas/riscv/dis-addr-2.s
new file mode 100644
index 00000000000..6ba9fc7a39d
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-2.s
@@ -0,0 +1,15 @@
+.ifdef rv64
+topbase = 0xffffffff00000000
+.else
+topbase = 0
+.endif
+
+.set __global_pointer$, topbase + 0xffffffff  # -1
+.set addr_rel_gp_pos,             0x00000004  # +4
+.set addr_rel_gp_neg,   topbase + 0xfffffffc  # -4
+
+target:
+	# Use addresses relative to gp
+	# (gp is the highest address)
+	lw	t0, +5(gp)
+	lw	t1, -3(gp)
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v3 0/3] RISC-V: Fix address printer on the disassembler
  2022-08-02  5:54 ` [PATCH v2 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
                     ` (3 preceding siblings ...)
  2022-08-02  5:54   ` [PATCH v2 4/4] RISC-V: Add address printer tests on disassembler Tsukasa OI
@ 2022-08-04  4:35   ` Tsukasa OI
  2022-08-04  4:35     ` [PATCH v3 1/3] RISC-V: Print highest address on disassembler Tsukasa OI
                       ` (5 more replies)
  4 siblings, 6 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-04  4:35 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

Hello,

This patchset contains a fix to PR29342.

Tracker on GitHub:
<https://github.com/a4lg/binutils-gdb/wiki/riscv_dis_fix_addr>

Original Issue as reported by H. Peter Anvin:
<https://sourceware.org/bugzilla/show_bug.cgi?id=29342>



[Changes: v2 -> v3]

-   Remove minor optimization (v2: PATCH 3/4)
    Further optimization (my disassembler optimization batch 2) revealed that
    scanning through the symbol table is necessary.  It means that breaking
    early doesn't help to improve the performance, even if the ELF file has
    the __global_pointer$ symbol.
    Because this "minor optimization" changed the behavior slightly, it's better
    to drop this one.
-   Rename testcase auipc-x0 to dis-addr-1
    I decided to group disassembler-printed address tests.
-   Rebase



[Performance Analysis (Summary): updated per v3]

This patch alone degrades the disassembler performance a bit (usually about 1%).
But I found my next batch of the disassembler optimization patchset somehow
shadows this.  In fact, Binutils with my optimization patchset 1 and Binutils
with my optimization patchset 1 plus this patchset has pretty much
the same performance.



[Changes: v1 -> v2]

-   Also allow `gp'-base symbol (__global_pointer$) to be the highest address
-   Add minor optimization (break early if multiple __global_pointer$ is found)
-   Rebase and minor copyediting



[Cover Letter from v1]

First of all, this bug is caused by address computation of maybe_print_address
on disassembling RV32 programs.

Let me show the pseudocode of `maybe_print_address':

    if (high part of the register [for address sequence] is set)
    {
        pd->print_addr = (high part) + offset;        // (1)
        unset high part (as used);
    }
    else if (base register == `gp' && __global_pointer$ is available)
        pd->print_addr = __global_pointer$ + offset;  // (2)
    else if (base register == `tp' || base register == `zero')
        pd->print_addr = offset;                      // (3)
    // Sign-extend a 32-bit value to 64-bit
    if (instruction is ADDIW or C.ADDIW)
        pd->print_addr = (bfd_vma)(int32_t)pd->print_addr;

In here, it implicitly sign-extends an `int'-typed variable `offset' to generate
an address.  (3) is the direct cause of PR29342 but other locations have
similar issue.

On an example provided by Peter, IOREG_FOO has an address value of 0xffffff00.
However, due to incorrect sign-extension, the disassembler considers that the
`sw' instruction operates on an incorrect address 0xffffffff_ffffff00 EVEN ON
RV32.  This affects symbol lookup.  So, we have to mask (and zero-extend) the
address on RV32 to get correct address 0xffffff00.

Also, the background provided by Peter gives us a context: highest address space
may be important for some systems/programs.  So, not only fixing PR29342, I
decided to make the address -1 (originally reserved as a non-printing address)
printable by separating (a) the address to print and (b) whether the address
should be printed.  This isn't zero-overhead but close to.

This patchset:

1.  fits an address into a 32-bit value on RV32 (resolves PR29342)
2.  makes the highest address printable
    (0xffffffff can be printed as a real symbol)
3.  clarifies the meaning of the `wide' argument
    (`is_addiw' fits the context).

It also has new testcases and a testcase modification (it seems lla32.d is
affected by this patchset but not harmful so that modifying the testcase
lla32.d seemed better).

Thanks,
Tsukasa




Tsukasa OI (3):
  RISC-V: Print highest address on disassembler
  RISC-V: Fix RV32 disassembler address computation
  RISC-V: Add address printer tests on disassembler

 .../gas/riscv/{auipc-x0.d => dis-addr-1.d}    |  0
 .../gas/riscv/{auipc-x0.s => dis-addr-1.s}    |  0
 gas/testsuite/gas/riscv/dis-addr-2-32.d       | 29 ++++++++
 gas/testsuite/gas/riscv/dis-addr-2-64.d       | 33 +++++++++
 gas/testsuite/gas/riscv/dis-addr-2.s          | 70 +++++++++++++++++++
 gas/testsuite/gas/riscv/dis-addr-3-32.d       | 12 ++++
 gas/testsuite/gas/riscv/dis-addr-3-64.d       | 12 ++++
 gas/testsuite/gas/riscv/dis-addr-3.s          | 15 ++++
 gas/testsuite/gas/riscv/lla32.d               |  2 +-
 opcodes/riscv-dis.c                           | 46 +++++++-----
 10 files changed, 202 insertions(+), 17 deletions(-)
 rename gas/testsuite/gas/riscv/{auipc-x0.d => dis-addr-1.d} (100%)
 rename gas/testsuite/gas/riscv/{auipc-x0.s => dis-addr-1.s} (100%)
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2.s
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3.s


base-commit: 94e27e8e69a07d69554ee7598419646d3ee99907
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v3 1/3] RISC-V: Print highest address on disassembler
  2022-08-04  4:35   ` [PATCH v3 0/3] RISC-V: Fix address printer on the disassembler Tsukasa OI
@ 2022-08-04  4:35     ` Tsukasa OI
  2022-08-04  4:35     ` [PATCH v3 2/3] RISC-V: Fix RV32 disassembler address computation Tsukasa OI
                       ` (4 subsequent siblings)
  5 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-04  4:35 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

This patch makes possible to print the highest address (0xffffffff on RV32,
0xffffffff_ffffffff on RV64).  This is particularly useful if the highest
address space is used for I/O registers and corresponding symbols
are defined.

opcodes/ChangeLog:

	* riscv-dis.c (struct riscv_private_data): Add `to_print_addr' and
	`has_gp' to enable printing the highest address.
	(maybe_print_address): Utilize `to_print_addr' and `has_gp'.
	(riscv_disassemble_insn): Likewise.
---
 opcodes/riscv-dis.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 164fd209dbd..c6d80c3ba49 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -52,6 +52,8 @@ struct riscv_private_data
   bfd_vma gp;
   bfd_vma print_addr;
   bfd_vma hi_addr[OP_MASK_RD + 1];
+  bool to_print_addr;
+  bool has_gp;
 };
 
 /* Used for mapping symbols.  */
@@ -177,10 +179,13 @@ maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
       pd->print_addr = (base_reg != 0 ? pd->hi_addr[base_reg] : 0) + offset;
       pd->hi_addr[base_reg] = -1;
     }
-  else if (base_reg == X_GP && pd->gp != (bfd_vma)-1)
+  else if (base_reg == X_GP && pd->has_gp)
     pd->print_addr = pd->gp + offset;
   else if (base_reg == X_TP || base_reg == 0)
     pd->print_addr = offset;
+  else
+    return;
+  pd->to_print_addr = true;
 
   /* Sign-extend a 32-bit value to a 64-bit value.  */
   if (wide)
@@ -595,14 +600,19 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
       int i;
 
       pd = info->private_data = xcalloc (1, sizeof (struct riscv_private_data));
-      pd->gp = -1;
-      pd->print_addr = -1;
+      pd->gp = 0;
+      pd->print_addr = 0;
       for (i = 0; i < (int)ARRAY_SIZE (pd->hi_addr); i++)
 	pd->hi_addr[i] = -1;
+      pd->to_print_addr = false;
+      pd->has_gp = false;
 
       for (i = 0; i < info->symtab_size; i++)
 	if (strcmp (bfd_asymbol_name (info->symtab[i]), RISCV_GP_SYMBOL) == 0)
-	  pd->gp = bfd_asymbol_value (info->symtab[i]);
+	  {
+	    pd->gp = bfd_asymbol_value (info->symtab[i]);
+	    pd->has_gp = true;
+	  }
     }
   else
     pd = info->private_data;
@@ -662,13 +672,13 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
 	  print_insn_args (op->args, word, memaddr, info);
 
 	  /* Try to disassemble multi-instruction addressing sequences.  */
-	  if (pd->print_addr != (bfd_vma)-1)
+	  if (pd->to_print_addr)
 	    {
 	      info->target = pd->print_addr;
 	      (*info->fprintf_styled_func)
 		(info->stream, dis_style_comment_start, " # ");
 	      (*info->print_address_func) (info->target, info);
-	      pd->print_addr = -1;
+	      pd->to_print_addr = false;
 	    }
 
 	  /* Finish filling out insn_info fields.  */
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v3 2/3] RISC-V: Fix RV32 disassembler address computation
  2022-08-04  4:35   ` [PATCH v3 0/3] RISC-V: Fix address printer on the disassembler Tsukasa OI
  2022-08-04  4:35     ` [PATCH v3 1/3] RISC-V: Print highest address on disassembler Tsukasa OI
@ 2022-08-04  4:35     ` Tsukasa OI
  2022-08-04  4:35     ` [PATCH v3 3/3] RISC-V: Add address printer tests on disassembler Tsukasa OI
                       ` (3 subsequent siblings)
  5 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-04  4:35 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

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 bug (including PR29342) by fitting an address into a 32-bit value
on RV32.

gas/ChangeLog:

	* testsuite/gas/riscv/lla32.d: Reflect RV32 address computation fix.

opcodes/ChangeLog:

	* riscv-dis.c (maybe_print_address): Clarify the role of the `wide'
	argument and rename to `is_addiw'.  Fit the address into 32-bit on
	RV32.  (print_insn_args): Reflect bool type of `is_addiw'.
---
 gas/testsuite/gas/riscv/lla32.d |  2 +-
 opcodes/riscv-dis.c             | 24 ++++++++++++++----------
 2 files changed, 15 insertions(+), 11 deletions(-)

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 c6d80c3ba49..419c4746db9 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -172,7 +172,7 @@ arg_print (struct disassemble_info *info, unsigned long val,
 
 static void
 maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
-		     int wide)
+		     bool is_addiw)
 {
   if (pd->hi_addr[base_reg] != (bfd_vma)-1)
     {
@@ -187,9 +187,13 @@ maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
     return;
   pd->to_print_addr = true;
 
-  /* Sign-extend a 32-bit value to a 64-bit value.  */
-  if (wide)
+  /* On ADDIW, Sign-extend a 32-bit value to a 64-bit value.  */
+  if (is_addiw)
     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.  */
@@ -239,10 +243,10 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	    case 'o':
 	    case 'j':
 	      if (((l & MASK_C_ADDI) == MATCH_C_ADDI) && rd != 0)
-		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), 0);
+		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), false);
 	      if (info->mach == bfd_mach_riscv64
 		  && ((l & MASK_C_ADDIW) == MATCH_C_ADDIW) && rd != 0)
-		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), 1);
+		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), true);
 	      print (info->stream, dis_style_immediate, "%d",
 		     (int)EXTRACT_CITYPE_IMM (l));
 	      break;
@@ -402,7 +406,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, 0, false);
 	  print (info->stream, dis_style_register, "%s", riscv_gpr_names[rs1]);
 	  break;
 
@@ -432,21 +436,21 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	  break;
 
 	case 'o':
-	  maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0);
+	  maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), false);
 	  /* Fall through.  */
 	case 'j':
 	  if (((l & MASK_ADDI) == MATCH_ADDI && rs1 != 0)
 	      || (l & MASK_JALR) == MATCH_JALR)
-	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0);
+	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), false);
 	  if (info->mach == bfd_mach_riscv64
 	      && ((l & MASK_ADDIW) == MATCH_ADDIW) && rs1 != 0)
-	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 1);
+	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), true);
 	  print (info->stream, dis_style_immediate, "%d",
 		 (int)EXTRACT_ITYPE_IMM (l));
 	  break;
 
 	case 'q':
-	  maybe_print_address (pd, rs1, EXTRACT_STYPE_IMM (l), 0);
+	  maybe_print_address (pd, rs1, EXTRACT_STYPE_IMM (l), false);
 	  print (info->stream, dis_style_address_offset, "%d",
 		 (int)EXTRACT_STYPE_IMM (l));
 	  break;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v3 3/3] RISC-V: Add address printer tests on disassembler
  2022-08-04  4:35   ` [PATCH v3 0/3] RISC-V: Fix address printer on the disassembler Tsukasa OI
  2022-08-04  4:35     ` [PATCH v3 1/3] RISC-V: Print highest address on disassembler Tsukasa OI
  2022-08-04  4:35     ` [PATCH v3 2/3] RISC-V: Fix RV32 disassembler address computation Tsukasa OI
@ 2022-08-04  4:35     ` Tsukasa OI
  2022-08-08 18:31     ` [PATCH v3 0/3] RISC-V: Fix address printer on the disassembler H. Peter Anvin
                       ` (2 subsequent siblings)
  5 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-04  4:35 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

This commit adds address printer tests on the disassembler focusing on
various path to/on maybe_print_address.  It also tests whether the address
adjustment on RV32 (fix to PR29342) works as expected and whether the
highest address is printed with a symbol.

gas/ChangeLog:

	* testsuite/gas/riscv/dis-addr-a.s: Rename from auipc-x0.s.
	* testsuite/gas/riscv/dis-addr-a.d: Rename from auipc-x0.d.
	* testsuite/gas/riscv/dis-addr-2.s: New address printer tests
	on the disassembler.
	* testsuite/gas/riscv/dis-addr-2-32.d: Likewise.
	* testsuite/gas/riscv/dis-addr-2-64.d: Likewise.
	* testsuite/gas/riscv/dis-addr-3.s: New address printer tests
	on the disassembler if `gp' is the highest address.
	* testsuite/gas/riscv/dis-addr-3-32.d: Likewise.
	* testsuite/gas/riscv/dis-addr-3-64.d: Likewise.
---
 .../gas/riscv/{auipc-x0.d => dis-addr-1.d}    |  0
 .../gas/riscv/{auipc-x0.s => dis-addr-1.s}    |  0
 gas/testsuite/gas/riscv/dis-addr-2-32.d       | 29 ++++++++
 gas/testsuite/gas/riscv/dis-addr-2-64.d       | 33 +++++++++
 gas/testsuite/gas/riscv/dis-addr-2.s          | 70 +++++++++++++++++++
 gas/testsuite/gas/riscv/dis-addr-3-32.d       | 12 ++++
 gas/testsuite/gas/riscv/dis-addr-3-64.d       | 12 ++++
 gas/testsuite/gas/riscv/dis-addr-3.s          | 15 ++++
 8 files changed, 171 insertions(+)
 rename gas/testsuite/gas/riscv/{auipc-x0.d => dis-addr-1.d} (100%)
 rename gas/testsuite/gas/riscv/{auipc-x0.s => dis-addr-1.s} (100%)
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2.s
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3.s

diff --git a/gas/testsuite/gas/riscv/auipc-x0.d b/gas/testsuite/gas/riscv/dis-addr-1.d
similarity index 100%
rename from gas/testsuite/gas/riscv/auipc-x0.d
rename to gas/testsuite/gas/riscv/dis-addr-1.d
diff --git a/gas/testsuite/gas/riscv/auipc-x0.s b/gas/testsuite/gas/riscv/dis-addr-1.s
similarity index 100%
rename from gas/testsuite/gas/riscv/auipc-x0.s
rename to gas/testsuite/gas/riscv/dis-addr-1.s
diff --git a/gas/testsuite/gas/riscv/dis-addr-2-32.d b/gas/testsuite/gas/riscv/dis-addr-2-32.d
new file mode 100644
index 00000000000..184ac0d0973
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-2-32.d
@@ -0,0 +1,29 @@
+#as: -march=rv32ic
+#source: dis-addr-2.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]+:[ 	]+fff00e83[ 	]+lb[   	]+t4,-1\(zero\) # ffffffff <addr_top>
diff --git a/gas/testsuite/gas/riscv/dis-addr-2-64.d b/gas/testsuite/gas/riscv/dis-addr-2-64.d
new file mode 100644
index 00000000000..2fd98d3d46a
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-2-64.d
@@ -0,0 +1,33 @@
+#as: -march=rv64ic -defsym rv64=1
+#source: dis-addr-2.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]+:[ 	]+fff00e83[ 	]+lb[   	]+t4,-1\(zero\) # ffffffffffffffff <addr_top>
diff --git a/gas/testsuite/gas/riscv/dis-addr-2.s b/gas/testsuite/gas/riscv/dis-addr-2.s
new file mode 100644
index 00000000000..328fa04eb34
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-2.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_top,          topbase + 0xffffffff  # -1
+
+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)
+
+	# Access to the highest address
+	lb	t4, -1(zero)
diff --git a/gas/testsuite/gas/riscv/dis-addr-3-32.d b/gas/testsuite/gas/riscv/dis-addr-3-32.d
new file mode 100644
index 00000000000..42ca89850ac
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-3-32.d
@@ -0,0 +1,12 @@
+#as: -march=rv32i
+#source: dis-addr-3.s
+#objdump: -d
+
+.*:     file format elf32-(little|big)riscv
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+0051a283[ 	]+lw[   	]+t0,5\(gp\) # 4 <addr_rel_gp_pos>
+[ 	]+[0-9a-f]+:[ 	]+ffd1a303[ 	]+lw[   	]+t1,-3\(gp\) # fffffffc <addr_rel_gp_neg>
diff --git a/gas/testsuite/gas/riscv/dis-addr-3-64.d b/gas/testsuite/gas/riscv/dis-addr-3-64.d
new file mode 100644
index 00000000000..394c58fac96
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-3-64.d
@@ -0,0 +1,12 @@
+#as: -march=rv64i -defsym rv64=1
+#source: dis-addr-3.s
+#objdump: -d
+
+.*:     file format elf64-(little|big)riscv
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+0051a283[ 	]+lw[   	]+t0,5\(gp\) # 4 <addr_rel_gp_pos>
+[ 	]+[0-9a-f]+:[ 	]+ffd1a303[ 	]+lw[   	]+t1,-3\(gp\) # fffffffffffffffc <addr_rel_gp_neg>
diff --git a/gas/testsuite/gas/riscv/dis-addr-3.s b/gas/testsuite/gas/riscv/dis-addr-3.s
new file mode 100644
index 00000000000..6ba9fc7a39d
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-3.s
@@ -0,0 +1,15 @@
+.ifdef rv64
+topbase = 0xffffffff00000000
+.else
+topbase = 0
+.endif
+
+.set __global_pointer$, topbase + 0xffffffff  # -1
+.set addr_rel_gp_pos,             0x00000004  # +4
+.set addr_rel_gp_neg,   topbase + 0xfffffffc  # -4
+
+target:
+	# Use addresses relative to gp
+	# (gp is the highest address)
+	lw	t0, +5(gp)
+	lw	t1, -3(gp)
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v3 0/3] RISC-V: Fix address printer on the disassembler
  2022-08-04  4:35   ` [PATCH v3 0/3] RISC-V: Fix address printer on the disassembler Tsukasa OI
                       ` (2 preceding siblings ...)
  2022-08-04  4:35     ` [PATCH v3 3/3] RISC-V: Add address printer tests on disassembler Tsukasa OI
@ 2022-08-08 18:31     ` H. Peter Anvin
  2022-08-08 19:46       ` Palmer Dabbelt
  2022-08-09  3:39     ` [PATCH v3 0/4] " Tsukasa OI
  2022-08-09  3:44     ` [PATCH v4 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
  5 siblings, 1 reply; 48+ messages in thread
From: H. Peter Anvin @ 2022-08-08 18:31 UTC (permalink / raw)
  To: Tsukasa OI, Nelson Chu, Kito Cheng, Palmer Dabbelt; +Cc: binutils

Hi,

I tried out this patch, but I noticed that it still gets jalr with a 
(zero) register base wrong:

40003764:       454000e7                jalr    1108(zero) # 0 <_NULL>

The address here is obviously 1108 (0x454), not 0; there is a symbol at 
address 0x454:

00000454 T memcpy

	-hpa

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v3 0/3] RISC-V: Fix address printer on the disassembler
  2022-08-08 18:31     ` [PATCH v3 0/3] RISC-V: Fix address printer on the disassembler H. Peter Anvin
@ 2022-08-08 19:46       ` Palmer Dabbelt
  0 siblings, 0 replies; 48+ messages in thread
From: Palmer Dabbelt @ 2022-08-08 19:46 UTC (permalink / raw)
  To: hpa; +Cc: research_trasio, Nelson Chu, kito.cheng, binutils

On Mon, 08 Aug 2022 11:31:18 PDT (-0700), hpa@zytor.com wrote:
> Hi,
>
> I tried out this patch, but I noticed that it still gets jalr with a
> (zero) register base wrong:
>
> 40003764:       454000e7                jalr    1108(zero) # 0 <_NULL>
>
> The address here is obviously 1108 (0x454), not 0; there is a symbol at
> address 0x454:
>
> 00000454 T memcpy

I think this should do it

diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 164fd209dbd..4c03f113650 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -397,7 +397,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;

I haven't had a chance to look at the patch set in question, though, so 
I'm not sure if I'm a bit behind.

^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v3 0/4] RISC-V: Fix address printer on the disassembler
  2022-08-04  4:35   ` [PATCH v3 0/3] RISC-V: Fix address printer on the disassembler Tsukasa OI
                       ` (3 preceding siblings ...)
  2022-08-08 18:31     ` [PATCH v3 0/3] RISC-V: Fix address printer on the disassembler H. Peter Anvin
@ 2022-08-09  3:39     ` Tsukasa OI
  2022-08-09  3:39       ` [PATCH v3 1/4] RISC-V: Print highest address on disassembler Tsukasa OI
                         ` (3 more replies)
  2022-08-09  3:44     ` [PATCH v4 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
  5 siblings, 4 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-09  3:39 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

Hello,

This patchset contains a fix to PR29342.

Tracker on GitHub:
<https://github.com/a4lg/binutils-gdb/wiki/riscv_dis_fix_addr>

Original Issue as reported by H. Peter Anvin:
<https://sourceware.org/bugzilla/show_bug.cgi?id=29342>



[Changes: v3 -> v4]

-   Added a bug fix discovered by Palmer Dabbelt.
    The original bug was in 2018.
-   Added testcases to make sure that the bug is fixed.
-   Rebase (again)



[Changes: v2 -> v3]

-   Remove minor optimization (v2: PATCH 3/4)
    Further optimization (my disassembler optimization batch 2) revealed that
    scanning through the symbol table is necessary.  It means that breaking
    early doesn't help to improve the performance, even if the ELF file has
    the __global_pointer$ symbol.
    Because this "minor optimization" changed the behavior slightly, it's better
    to drop this one.
-   Rename testcase auipc-x0 to dis-addr-1
    I decided to group disassembler-printed address tests.
-   Rebase



[Performance Analysis (Summary): updated per v3]

This patch alone degrades the disassembler performance a bit (usually about 1%).
But I found my next batch of the disassembler optimization patchset somehow
shadows this.  In fact, Binutils with my optimization patchset 1 and Binutils
with my optimization patchset 1 plus this patchset has pretty much
the same performance.



[Changes: v1 -> v2]

-   Also allow `gp'-base symbol (__global_pointer$) to be the highest address
-   Add minor optimization (break early if multiple __global_pointer$ is found)
-   Rebase and minor copyediting



[Cover Letter from v1]

First of all, this bug is caused by address computation of maybe_print_address
on disassembling RV32 programs.

Let me show the pseudocode of `maybe_print_address':

    if (high part of the register [for address sequence] is set)
    {
        pd->print_addr = (high part) + offset;        // (1)
        unset high part (as used);
    }
    else if (base register == `gp' && __global_pointer$ is available)
        pd->print_addr = __global_pointer$ + offset;  // (2)
    else if (base register == `tp' || base register == `zero')
        pd->print_addr = offset;                      // (3)
    // Sign-extend a 32-bit value to 64-bit
    if (instruction is ADDIW or C.ADDIW)
        pd->print_addr = (bfd_vma)(int32_t)pd->print_addr;

In here, it implicitly sign-extends an `int'-typed variable `offset' to generate
an address.  (3) is the direct cause of PR29342 but other locations have
similar issue.

On an example provided by Peter, IOREG_FOO has an address value of 0xffffff00.
However, due to incorrect sign-extension, the disassembler considers that the
`sw' instruction operates on an incorrect address 0xffffffff_ffffff00 EVEN ON
RV32.  This affects symbol lookup.  So, we have to mask (and zero-extend) the
address on RV32 to get correct address 0xffffff00.

Also, the background provided by Peter gives us a context: highest address space
may be important for some systems/programs.  So, not only fixing PR29342, I
decided to make the address -1 (originally reserved as a non-printing address)
printable by separating (a) the address to print and (b) whether the address
should be printed.  This isn't zero-overhead but close to.

This patchset:

1.  fits an address into a 32-bit value on RV32 (resolves PR29342)
2.  makes the highest address printable
    (0xffffffff can be printed as a real symbol)
3.  clarifies the meaning of the `wide' argument
    (`is_addiw' fits the context).

It also has new testcases and a testcase modification (it seems lla32.d is
affected by this patchset but not harmful so that modifying the testcase
lla32.d seemed better).

Thanks,
Tsukasa




Tsukasa OI (4):
  RISC-V: Print highest address on disassembler
  RISC-V: Fix RV32 disassembler address computation
  RISC-V: Fix JALR target address computation
  RISC-V: Add address printer tests on disassembler

 .../gas/riscv/{auipc-x0.d => dis-addr-1.d}    |  0
 .../gas/riscv/{auipc-x0.s => dis-addr-1.s}    |  0
 gas/testsuite/gas/riscv/dis-addr-2-32.d       | 31 ++++++++
 gas/testsuite/gas/riscv/dis-addr-2-64.d       | 35 +++++++++
 gas/testsuite/gas/riscv/dis-addr-2.s          | 74 +++++++++++++++++++
 gas/testsuite/gas/riscv/dis-addr-3-32.d       | 12 +++
 gas/testsuite/gas/riscv/dis-addr-3-64.d       | 12 +++
 gas/testsuite/gas/riscv/dis-addr-3.s          | 15 ++++
 gas/testsuite/gas/riscv/lla32.d               |  2 +-
 opcodes/riscv-dis.c                           | 46 ++++++++----
 10 files changed, 210 insertions(+), 17 deletions(-)
 rename gas/testsuite/gas/riscv/{auipc-x0.d => dis-addr-1.d} (100%)
 rename gas/testsuite/gas/riscv/{auipc-x0.s => dis-addr-1.s} (100%)
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2.s
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3.s


base-commit: 65c9841b6fee984714509acef6e52366363072b6
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v3 1/4] RISC-V: Print highest address on disassembler
  2022-08-09  3:39     ` [PATCH v3 0/4] " Tsukasa OI
@ 2022-08-09  3:39       ` Tsukasa OI
  2022-08-09  3:39       ` [PATCH v3 2/4] RISC-V: Fix RV32 disassembler address computation Tsukasa OI
                         ` (2 subsequent siblings)
  3 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-09  3:39 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

This patch makes possible to print the highest address (0xffffffff on RV32,
0xffffffff_ffffffff on RV64).  This is particularly useful if the highest
address space is used for I/O registers and corresponding symbols
are defined.

opcodes/ChangeLog:

	* riscv-dis.c (struct riscv_private_data): Add `to_print_addr' and
	`has_gp' to enable printing the highest address.
	(maybe_print_address): Utilize `to_print_addr' and `has_gp'.
	(riscv_disassemble_insn): Likewise.
---
 opcodes/riscv-dis.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 164fd209dbd..c6d80c3ba49 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -52,6 +52,8 @@ struct riscv_private_data
   bfd_vma gp;
   bfd_vma print_addr;
   bfd_vma hi_addr[OP_MASK_RD + 1];
+  bool to_print_addr;
+  bool has_gp;
 };
 
 /* Used for mapping symbols.  */
@@ -177,10 +179,13 @@ maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
       pd->print_addr = (base_reg != 0 ? pd->hi_addr[base_reg] : 0) + offset;
       pd->hi_addr[base_reg] = -1;
     }
-  else if (base_reg == X_GP && pd->gp != (bfd_vma)-1)
+  else if (base_reg == X_GP && pd->has_gp)
     pd->print_addr = pd->gp + offset;
   else if (base_reg == X_TP || base_reg == 0)
     pd->print_addr = offset;
+  else
+    return;
+  pd->to_print_addr = true;
 
   /* Sign-extend a 32-bit value to a 64-bit value.  */
   if (wide)
@@ -595,14 +600,19 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
       int i;
 
       pd = info->private_data = xcalloc (1, sizeof (struct riscv_private_data));
-      pd->gp = -1;
-      pd->print_addr = -1;
+      pd->gp = 0;
+      pd->print_addr = 0;
       for (i = 0; i < (int)ARRAY_SIZE (pd->hi_addr); i++)
 	pd->hi_addr[i] = -1;
+      pd->to_print_addr = false;
+      pd->has_gp = false;
 
       for (i = 0; i < info->symtab_size; i++)
 	if (strcmp (bfd_asymbol_name (info->symtab[i]), RISCV_GP_SYMBOL) == 0)
-	  pd->gp = bfd_asymbol_value (info->symtab[i]);
+	  {
+	    pd->gp = bfd_asymbol_value (info->symtab[i]);
+	    pd->has_gp = true;
+	  }
     }
   else
     pd = info->private_data;
@@ -662,13 +672,13 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
 	  print_insn_args (op->args, word, memaddr, info);
 
 	  /* Try to disassemble multi-instruction addressing sequences.  */
-	  if (pd->print_addr != (bfd_vma)-1)
+	  if (pd->to_print_addr)
 	    {
 	      info->target = pd->print_addr;
 	      (*info->fprintf_styled_func)
 		(info->stream, dis_style_comment_start, " # ");
 	      (*info->print_address_func) (info->target, info);
-	      pd->print_addr = -1;
+	      pd->to_print_addr = false;
 	    }
 
 	  /* Finish filling out insn_info fields.  */
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v3 2/4] RISC-V: Fix RV32 disassembler address computation
  2022-08-09  3:39     ` [PATCH v3 0/4] " Tsukasa OI
  2022-08-09  3:39       ` [PATCH v3 1/4] RISC-V: Print highest address on disassembler Tsukasa OI
@ 2022-08-09  3:39       ` Tsukasa OI
  2022-08-09  3:39       ` [PATCH v3 3/4] RISC-V: Fix JALR target " Tsukasa OI
  2022-08-09  3:39       ` [PATCH v3 4/4] RISC-V: Add address printer tests on disassembler Tsukasa OI
  3 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-09  3:39 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

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 bug (including PR29342) by fitting an address into a 32-bit value
on RV32.

gas/ChangeLog:

	* testsuite/gas/riscv/lla32.d: Reflect RV32 address computation fix.

opcodes/ChangeLog:

	* riscv-dis.c (maybe_print_address): Clarify the role of the `wide'
	argument and rename to `is_addiw'.  Fit the address into 32-bit on
	RV32.  (print_insn_args): Reflect bool type of `is_addiw'.
---
 gas/testsuite/gas/riscv/lla32.d |  2 +-
 opcodes/riscv-dis.c             | 24 ++++++++++++++----------
 2 files changed, 15 insertions(+), 11 deletions(-)

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 c6d80c3ba49..419c4746db9 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -172,7 +172,7 @@ arg_print (struct disassemble_info *info, unsigned long val,
 
 static void
 maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
-		     int wide)
+		     bool is_addiw)
 {
   if (pd->hi_addr[base_reg] != (bfd_vma)-1)
     {
@@ -187,9 +187,13 @@ maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
     return;
   pd->to_print_addr = true;
 
-  /* Sign-extend a 32-bit value to a 64-bit value.  */
-  if (wide)
+  /* On ADDIW, Sign-extend a 32-bit value to a 64-bit value.  */
+  if (is_addiw)
     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.  */
@@ -239,10 +243,10 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	    case 'o':
 	    case 'j':
 	      if (((l & MASK_C_ADDI) == MATCH_C_ADDI) && rd != 0)
-		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), 0);
+		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), false);
 	      if (info->mach == bfd_mach_riscv64
 		  && ((l & MASK_C_ADDIW) == MATCH_C_ADDIW) && rd != 0)
-		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), 1);
+		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), true);
 	      print (info->stream, dis_style_immediate, "%d",
 		     (int)EXTRACT_CITYPE_IMM (l));
 	      break;
@@ -402,7 +406,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, 0, false);
 	  print (info->stream, dis_style_register, "%s", riscv_gpr_names[rs1]);
 	  break;
 
@@ -432,21 +436,21 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	  break;
 
 	case 'o':
-	  maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0);
+	  maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), false);
 	  /* Fall through.  */
 	case 'j':
 	  if (((l & MASK_ADDI) == MATCH_ADDI && rs1 != 0)
 	      || (l & MASK_JALR) == MATCH_JALR)
-	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0);
+	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), false);
 	  if (info->mach == bfd_mach_riscv64
 	      && ((l & MASK_ADDIW) == MATCH_ADDIW) && rs1 != 0)
-	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 1);
+	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), true);
 	  print (info->stream, dis_style_immediate, "%d",
 		 (int)EXTRACT_ITYPE_IMM (l));
 	  break;
 
 	case 'q':
-	  maybe_print_address (pd, rs1, EXTRACT_STYPE_IMM (l), 0);
+	  maybe_print_address (pd, rs1, EXTRACT_STYPE_IMM (l), false);
 	  print (info->stream, dis_style_address_offset, "%d",
 		 (int)EXTRACT_STYPE_IMM (l));
 	  break;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v3 3/4] RISC-V: Fix JALR target address computation
  2022-08-09  3:39     ` [PATCH v3 0/4] " Tsukasa OI
  2022-08-09  3:39       ` [PATCH v3 1/4] RISC-V: Print highest address on disassembler Tsukasa OI
  2022-08-09  3:39       ` [PATCH v3 2/4] RISC-V: Fix RV32 disassembler address computation Tsukasa OI
@ 2022-08-09  3:39       ` Tsukasa OI
  2022-08-09  3:39       ` [PATCH v3 4/4] RISC-V: Add address printer tests on disassembler Tsukasa OI
  3 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-09  3:39 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

Palmer Dabbelt discovered that we have wrong address computation for JALR
instruction (the initial bug is back in 2018).  This commit will fix that.

opcodes/ChangeLog:

	* riscv-dis.c (print_insn_args): Fix JALR address computation.
---
 opcodes/riscv-dis.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 419c4746db9..162a2971320 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -406,7 +406,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, false);
+	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), false);
 	  print (info->stream, dis_style_register, "%s", riscv_gpr_names[rs1]);
 	  break;
 
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v3 4/4] RISC-V: Add address printer tests on disassembler
  2022-08-09  3:39     ` [PATCH v3 0/4] " Tsukasa OI
                         ` (2 preceding siblings ...)
  2022-08-09  3:39       ` [PATCH v3 3/4] RISC-V: Fix JALR target " Tsukasa OI
@ 2022-08-09  3:39       ` Tsukasa OI
  3 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-09  3:39 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

This commit adds address printer tests on the disassembler focusing on
various path to/on maybe_print_address.  It also tests whether the address
adjustment on RV32 (fix to PR29342) works as expected, whether the highest
address is printed with a symbol and JALR address computation is fixed.

gas/ChangeLog:

	* testsuite/gas/riscv/dis-addr-a.s: Rename from auipc-x0.s.
	* testsuite/gas/riscv/dis-addr-a.d: Rename from auipc-x0.d.
	* testsuite/gas/riscv/dis-addr-2.s: New address printer tests
	on the disassembler.
	* testsuite/gas/riscv/dis-addr-2-32.d: Likewise.
	* testsuite/gas/riscv/dis-addr-2-64.d: Likewise.
	* testsuite/gas/riscv/dis-addr-3.s: New address printer tests
	on the disassembler if `gp' is the highest address.
	* testsuite/gas/riscv/dis-addr-3-32.d: Likewise.
	* testsuite/gas/riscv/dis-addr-3-64.d: Likewise.
---
 .../gas/riscv/{auipc-x0.d => dis-addr-1.d}    |  0
 .../gas/riscv/{auipc-x0.s => dis-addr-1.s}    |  0
 gas/testsuite/gas/riscv/dis-addr-2-32.d       | 31 ++++++++
 gas/testsuite/gas/riscv/dis-addr-2-64.d       | 35 +++++++++
 gas/testsuite/gas/riscv/dis-addr-2.s          | 74 +++++++++++++++++++
 gas/testsuite/gas/riscv/dis-addr-3-32.d       | 12 +++
 gas/testsuite/gas/riscv/dis-addr-3-64.d       | 12 +++
 gas/testsuite/gas/riscv/dis-addr-3.s          | 15 ++++
 8 files changed, 179 insertions(+)
 rename gas/testsuite/gas/riscv/{auipc-x0.d => dis-addr-1.d} (100%)
 rename gas/testsuite/gas/riscv/{auipc-x0.s => dis-addr-1.s} (100%)
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2.s
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3.s

diff --git a/gas/testsuite/gas/riscv/auipc-x0.d b/gas/testsuite/gas/riscv/dis-addr-1.d
similarity index 100%
rename from gas/testsuite/gas/riscv/auipc-x0.d
rename to gas/testsuite/gas/riscv/dis-addr-1.d
diff --git a/gas/testsuite/gas/riscv/auipc-x0.s b/gas/testsuite/gas/riscv/dis-addr-1.s
similarity index 100%
rename from gas/testsuite/gas/riscv/auipc-x0.s
rename to gas/testsuite/gas/riscv/dis-addr-1.s
diff --git a/gas/testsuite/gas/riscv/dis-addr-2-32.d b/gas/testsuite/gas/riscv/dis-addr-2-32.d
new file mode 100644
index 00000000000..5117c3d8a0c
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-2-32.d
@@ -0,0 +1,31 @@
+#as: -march=rv32ic
+#source: dis-addr-2.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>
+[ 	]+[0-9a-f]+:[ 	]+fff00f83[ 	]+lb[   	]+t6,-1\(zero\) # ffffffff <addr_top>
diff --git a/gas/testsuite/gas/riscv/dis-addr-2-64.d b/gas/testsuite/gas/riscv/dis-addr-2-64.d
new file mode 100644
index 00000000000..d806bad25b4
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-2-64.d
@@ -0,0 +1,35 @@
+#as: -march=rv64ic -defsym rv64=1
+#source: dis-addr-2.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>
+[ 	]+[0-9a-f]+:[ 	]+fff00f83[ 	]+lb[   	]+t6,-1\(zero\) # ffffffffffffffff <addr_top>
diff --git a/gas/testsuite/gas/riscv/dis-addr-2.s b/gas/testsuite/gas/riscv/dis-addr-2.s
new file mode 100644
index 00000000000..cb7f0cd9dc2
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-2.s
@@ -0,0 +1,74 @@
+.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  # 0x104
+.set addr_jalr_rel_zero_neg, topbase + 0xfffff804  # -0x7fc
+.set addr_top,               topbase + 0xffffffff  # -1
+
+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)
+
+	# Access to the highest address
+	lb	t6, -1(zero)
diff --git a/gas/testsuite/gas/riscv/dis-addr-3-32.d b/gas/testsuite/gas/riscv/dis-addr-3-32.d
new file mode 100644
index 00000000000..42ca89850ac
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-3-32.d
@@ -0,0 +1,12 @@
+#as: -march=rv32i
+#source: dis-addr-3.s
+#objdump: -d
+
+.*:     file format elf32-(little|big)riscv
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+0051a283[ 	]+lw[   	]+t0,5\(gp\) # 4 <addr_rel_gp_pos>
+[ 	]+[0-9a-f]+:[ 	]+ffd1a303[ 	]+lw[   	]+t1,-3\(gp\) # fffffffc <addr_rel_gp_neg>
diff --git a/gas/testsuite/gas/riscv/dis-addr-3-64.d b/gas/testsuite/gas/riscv/dis-addr-3-64.d
new file mode 100644
index 00000000000..394c58fac96
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-3-64.d
@@ -0,0 +1,12 @@
+#as: -march=rv64i -defsym rv64=1
+#source: dis-addr-3.s
+#objdump: -d
+
+.*:     file format elf64-(little|big)riscv
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+0051a283[ 	]+lw[   	]+t0,5\(gp\) # 4 <addr_rel_gp_pos>
+[ 	]+[0-9a-f]+:[ 	]+ffd1a303[ 	]+lw[   	]+t1,-3\(gp\) # fffffffffffffffc <addr_rel_gp_neg>
diff --git a/gas/testsuite/gas/riscv/dis-addr-3.s b/gas/testsuite/gas/riscv/dis-addr-3.s
new file mode 100644
index 00000000000..6ba9fc7a39d
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-3.s
@@ -0,0 +1,15 @@
+.ifdef rv64
+topbase = 0xffffffff00000000
+.else
+topbase = 0
+.endif
+
+.set __global_pointer$, topbase + 0xffffffff  # -1
+.set addr_rel_gp_pos,             0x00000004  # +4
+.set addr_rel_gp_neg,   topbase + 0xfffffffc  # -4
+
+target:
+	# Use addresses relative to gp
+	# (gp is the highest address)
+	lw	t0, +5(gp)
+	lw	t1, -3(gp)
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v4 0/4] RISC-V: Fix address printer on the disassembler
  2022-08-04  4:35   ` [PATCH v3 0/3] RISC-V: Fix address printer on the disassembler Tsukasa OI
                       ` (4 preceding siblings ...)
  2022-08-09  3:39     ` [PATCH v3 0/4] " Tsukasa OI
@ 2022-08-09  3:44     ` Tsukasa OI
  2022-08-09  3:44       ` [PATCH v4 1/4] RISC-V: Print highest address on disassembler Tsukasa OI
                         ` (4 more replies)
  5 siblings, 5 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-09  3:44 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

Hello,

This patchset contains a fix to PR29342.

Tracker on GitHub:
<https://github.com/a4lg/binutils-gdb/wiki/riscv_dis_fix_addr>

Original Issue as reported by H. Peter Anvin:
<https://sourceware.org/bugzilla/show_bug.cgi?id=29342>



[Changes: v3 -> v4]

-   Added a bug fix discovered by Palmer Dabbelt.
    The original bug was in 2018.
-   Added testcases to make sure that the bug is fixed.
-   Rebase (again)



[Changes: v2 -> v3]

-   Remove minor optimization (v2: PATCH 3/4)
    Further optimization (my disassembler optimization batch 2) revealed that
    scanning through the symbol table is necessary.  It means that breaking
    early doesn't help to improve the performance, even if the ELF file has
    the __global_pointer$ symbol.
    Because this "minor optimization" changed the behavior slightly, it's better
    to drop this one.
-   Rename testcase auipc-x0 to dis-addr-1
    I decided to group disassembler-printed address tests.
-   Rebase



[Performance Analysis (Summary): updated per v3]

This patch alone degrades the disassembler performance a bit (usually about 1%).
But I found my next batch of the disassembler optimization patchset somehow
shadows this.  In fact, Binutils with my optimization patchset 1 and Binutils
with my optimization patchset 1 plus this patchset has pretty much
the same performance.



[Changes: v1 -> v2]

-   Also allow `gp'-base symbol (__global_pointer$) to be the highest address
-   Add minor optimization (break early if multiple __global_pointer$ is found)
-   Rebase and minor copyediting



[Cover Letter from v1]

First of all, this bug is caused by address computation of maybe_print_address
on disassembling RV32 programs.

Let me show the pseudocode of `maybe_print_address':

    if (high part of the register [for address sequence] is set)
    {
        pd->print_addr = (high part) + offset;        // (1)
        unset high part (as used);
    }
    else if (base register == `gp' && __global_pointer$ is available)
        pd->print_addr = __global_pointer$ + offset;  // (2)
    else if (base register == `tp' || base register == `zero')
        pd->print_addr = offset;                      // (3)
    // Sign-extend a 32-bit value to 64-bit
    if (instruction is ADDIW or C.ADDIW)
        pd->print_addr = (bfd_vma)(int32_t)pd->print_addr;

In here, it implicitly sign-extends an `int'-typed variable `offset' to generate
an address.  (3) is the direct cause of PR29342 but other locations have
similar issue.

On an example provided by Peter, IOREG_FOO has an address value of 0xffffff00.
However, due to incorrect sign-extension, the disassembler considers that the
`sw' instruction operates on an incorrect address 0xffffffff_ffffff00 EVEN ON
RV32.  This affects symbol lookup.  So, we have to mask (and zero-extend) the
address on RV32 to get correct address 0xffffff00.

Also, the background provided by Peter gives us a context: highest address space
may be important for some systems/programs.  So, not only fixing PR29342, I
decided to make the address -1 (originally reserved as a non-printing address)
printable by separating (a) the address to print and (b) whether the address
should be printed.  This isn't zero-overhead but close to.

This patchset:

1.  fits an address into a 32-bit value on RV32 (resolves PR29342)
2.  makes the highest address printable
    (0xffffffff can be printed as a real symbol)
3.  clarifies the meaning of the `wide' argument
    (`is_addiw' fits the context).

It also has new testcases and a testcase modification (it seems lla32.d is
affected by this patchset but not harmful so that modifying the testcase
lla32.d seemed better).

Thanks,
Tsukasa




Tsukasa OI (4):
  RISC-V: Print highest address on disassembler
  RISC-V: Fix RV32 disassembler address computation
  RISC-V: Fix JALR target address computation
  RISC-V: Add address printer tests on disassembler

 .../gas/riscv/{auipc-x0.d => dis-addr-1.d}    |  0
 .../gas/riscv/{auipc-x0.s => dis-addr-1.s}    |  0
 gas/testsuite/gas/riscv/dis-addr-2-32.d       | 31 ++++++++
 gas/testsuite/gas/riscv/dis-addr-2-64.d       | 35 +++++++++
 gas/testsuite/gas/riscv/dis-addr-2.s          | 74 +++++++++++++++++++
 gas/testsuite/gas/riscv/dis-addr-3-32.d       | 12 +++
 gas/testsuite/gas/riscv/dis-addr-3-64.d       | 12 +++
 gas/testsuite/gas/riscv/dis-addr-3.s          | 15 ++++
 gas/testsuite/gas/riscv/lla32.d               |  2 +-
 opcodes/riscv-dis.c                           | 46 ++++++++----
 10 files changed, 210 insertions(+), 17 deletions(-)
 rename gas/testsuite/gas/riscv/{auipc-x0.d => dis-addr-1.d} (100%)
 rename gas/testsuite/gas/riscv/{auipc-x0.s => dis-addr-1.s} (100%)
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2.s
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3.s


base-commit: 65c9841b6fee984714509acef6e52366363072b6
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v4 1/4] RISC-V: Print highest address on disassembler
  2022-08-09  3:44     ` [PATCH v4 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
@ 2022-08-09  3:44       ` Tsukasa OI
  2022-08-09  3:44       ` [PATCH v4 2/4] RISC-V: Fix RV32 disassembler address computation Tsukasa OI
                         ` (3 subsequent siblings)
  4 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-09  3:44 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

This patch makes possible to print the highest address (0xffffffff on RV32,
0xffffffff_ffffffff on RV64).  This is particularly useful if the highest
address space is used for I/O registers and corresponding symbols
are defined.

opcodes/ChangeLog:

	* riscv-dis.c (struct riscv_private_data): Add `to_print_addr' and
	`has_gp' to enable printing the highest address.
	(maybe_print_address): Utilize `to_print_addr' and `has_gp'.
	(riscv_disassemble_insn): Likewise.
---
 opcodes/riscv-dis.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 164fd209dbd..c6d80c3ba49 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -52,6 +52,8 @@ struct riscv_private_data
   bfd_vma gp;
   bfd_vma print_addr;
   bfd_vma hi_addr[OP_MASK_RD + 1];
+  bool to_print_addr;
+  bool has_gp;
 };
 
 /* Used for mapping symbols.  */
@@ -177,10 +179,13 @@ maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
       pd->print_addr = (base_reg != 0 ? pd->hi_addr[base_reg] : 0) + offset;
       pd->hi_addr[base_reg] = -1;
     }
-  else if (base_reg == X_GP && pd->gp != (bfd_vma)-1)
+  else if (base_reg == X_GP && pd->has_gp)
     pd->print_addr = pd->gp + offset;
   else if (base_reg == X_TP || base_reg == 0)
     pd->print_addr = offset;
+  else
+    return;
+  pd->to_print_addr = true;
 
   /* Sign-extend a 32-bit value to a 64-bit value.  */
   if (wide)
@@ -595,14 +600,19 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
       int i;
 
       pd = info->private_data = xcalloc (1, sizeof (struct riscv_private_data));
-      pd->gp = -1;
-      pd->print_addr = -1;
+      pd->gp = 0;
+      pd->print_addr = 0;
       for (i = 0; i < (int)ARRAY_SIZE (pd->hi_addr); i++)
 	pd->hi_addr[i] = -1;
+      pd->to_print_addr = false;
+      pd->has_gp = false;
 
       for (i = 0; i < info->symtab_size; i++)
 	if (strcmp (bfd_asymbol_name (info->symtab[i]), RISCV_GP_SYMBOL) == 0)
-	  pd->gp = bfd_asymbol_value (info->symtab[i]);
+	  {
+	    pd->gp = bfd_asymbol_value (info->symtab[i]);
+	    pd->has_gp = true;
+	  }
     }
   else
     pd = info->private_data;
@@ -662,13 +672,13 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
 	  print_insn_args (op->args, word, memaddr, info);
 
 	  /* Try to disassemble multi-instruction addressing sequences.  */
-	  if (pd->print_addr != (bfd_vma)-1)
+	  if (pd->to_print_addr)
 	    {
 	      info->target = pd->print_addr;
 	      (*info->fprintf_styled_func)
 		(info->stream, dis_style_comment_start, " # ");
 	      (*info->print_address_func) (info->target, info);
-	      pd->print_addr = -1;
+	      pd->to_print_addr = false;
 	    }
 
 	  /* Finish filling out insn_info fields.  */
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v4 2/4] RISC-V: Fix RV32 disassembler address computation
  2022-08-09  3:44     ` [PATCH v4 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
  2022-08-09  3:44       ` [PATCH v4 1/4] RISC-V: Print highest address on disassembler Tsukasa OI
@ 2022-08-09  3:44       ` Tsukasa OI
  2022-08-09  3:44       ` [PATCH v4 3/4] RISC-V: Fix JALR target " Tsukasa OI
                         ` (2 subsequent siblings)
  4 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-09  3:44 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

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 bug (including PR29342) by fitting an address into a 32-bit value
on RV32.

gas/ChangeLog:

	* testsuite/gas/riscv/lla32.d: Reflect RV32 address computation fix.

opcodes/ChangeLog:

	* riscv-dis.c (maybe_print_address): Clarify the role of the `wide'
	argument and rename to `is_addiw'.  Fit the address into 32-bit on
	RV32.  (print_insn_args): Reflect bool type of `is_addiw'.
---
 gas/testsuite/gas/riscv/lla32.d |  2 +-
 opcodes/riscv-dis.c             | 24 ++++++++++++++----------
 2 files changed, 15 insertions(+), 11 deletions(-)

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 c6d80c3ba49..419c4746db9 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -172,7 +172,7 @@ arg_print (struct disassemble_info *info, unsigned long val,
 
 static void
 maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
-		     int wide)
+		     bool is_addiw)
 {
   if (pd->hi_addr[base_reg] != (bfd_vma)-1)
     {
@@ -187,9 +187,13 @@ maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
     return;
   pd->to_print_addr = true;
 
-  /* Sign-extend a 32-bit value to a 64-bit value.  */
-  if (wide)
+  /* On ADDIW, Sign-extend a 32-bit value to a 64-bit value.  */
+  if (is_addiw)
     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.  */
@@ -239,10 +243,10 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	    case 'o':
 	    case 'j':
 	      if (((l & MASK_C_ADDI) == MATCH_C_ADDI) && rd != 0)
-		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), 0);
+		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), false);
 	      if (info->mach == bfd_mach_riscv64
 		  && ((l & MASK_C_ADDIW) == MATCH_C_ADDIW) && rd != 0)
-		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), 1);
+		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), true);
 	      print (info->stream, dis_style_immediate, "%d",
 		     (int)EXTRACT_CITYPE_IMM (l));
 	      break;
@@ -402,7 +406,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, 0, false);
 	  print (info->stream, dis_style_register, "%s", riscv_gpr_names[rs1]);
 	  break;
 
@@ -432,21 +436,21 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	  break;
 
 	case 'o':
-	  maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0);
+	  maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), false);
 	  /* Fall through.  */
 	case 'j':
 	  if (((l & MASK_ADDI) == MATCH_ADDI && rs1 != 0)
 	      || (l & MASK_JALR) == MATCH_JALR)
-	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0);
+	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), false);
 	  if (info->mach == bfd_mach_riscv64
 	      && ((l & MASK_ADDIW) == MATCH_ADDIW) && rs1 != 0)
-	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 1);
+	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), true);
 	  print (info->stream, dis_style_immediate, "%d",
 		 (int)EXTRACT_ITYPE_IMM (l));
 	  break;
 
 	case 'q':
-	  maybe_print_address (pd, rs1, EXTRACT_STYPE_IMM (l), 0);
+	  maybe_print_address (pd, rs1, EXTRACT_STYPE_IMM (l), false);
 	  print (info->stream, dis_style_address_offset, "%d",
 		 (int)EXTRACT_STYPE_IMM (l));
 	  break;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v4 3/4] RISC-V: Fix JALR target address computation
  2022-08-09  3:44     ` [PATCH v4 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
  2022-08-09  3:44       ` [PATCH v4 1/4] RISC-V: Print highest address on disassembler Tsukasa OI
  2022-08-09  3:44       ` [PATCH v4 2/4] RISC-V: Fix RV32 disassembler address computation Tsukasa OI
@ 2022-08-09  3:44       ` Tsukasa OI
  2022-08-09  3:44       ` [PATCH v4 4/4] RISC-V: Add address printer tests on disassembler Tsukasa OI
  2022-08-09  4:41       ` [PATCH v5 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
  4 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-09  3:44 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

Palmer Dabbelt discovered that we have wrong address computation for JALR
instruction (the initial bug is back in 2018).  This commit will fix that.

opcodes/ChangeLog:

	* riscv-dis.c (print_insn_args): Fix JALR address computation.
---
 opcodes/riscv-dis.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 419c4746db9..162a2971320 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -406,7 +406,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, false);
+	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), false);
 	  print (info->stream, dis_style_register, "%s", riscv_gpr_names[rs1]);
 	  break;
 
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v4 4/4] RISC-V: Add address printer tests on disassembler
  2022-08-09  3:44     ` [PATCH v4 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
                         ` (2 preceding siblings ...)
  2022-08-09  3:44       ` [PATCH v4 3/4] RISC-V: Fix JALR target " Tsukasa OI
@ 2022-08-09  3:44       ` Tsukasa OI
  2022-08-09  4:41       ` [PATCH v5 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
  4 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-09  3:44 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

This commit adds address printer tests on the disassembler focusing on
various path to/on maybe_print_address.  It also tests whether the address
adjustment on RV32 (fix to PR29342) works as expected, whether the highest
address is printed with a symbol and JALR address computation is fixed.

gas/ChangeLog:

	* testsuite/gas/riscv/dis-addr-a.s: Rename from auipc-x0.s.
	* testsuite/gas/riscv/dis-addr-a.d: Rename from auipc-x0.d.
	* testsuite/gas/riscv/dis-addr-2.s: New address printer tests
	on the disassembler.
	* testsuite/gas/riscv/dis-addr-2-32.d: Likewise.
	* testsuite/gas/riscv/dis-addr-2-64.d: Likewise.
	* testsuite/gas/riscv/dis-addr-3.s: New address printer tests
	on the disassembler if `gp' is the highest address.
	* testsuite/gas/riscv/dis-addr-3-32.d: Likewise.
	* testsuite/gas/riscv/dis-addr-3-64.d: Likewise.
---
 .../gas/riscv/{auipc-x0.d => dis-addr-1.d}    |  0
 .../gas/riscv/{auipc-x0.s => dis-addr-1.s}    |  0
 gas/testsuite/gas/riscv/dis-addr-2-32.d       | 31 ++++++++
 gas/testsuite/gas/riscv/dis-addr-2-64.d       | 35 +++++++++
 gas/testsuite/gas/riscv/dis-addr-2.s          | 74 +++++++++++++++++++
 gas/testsuite/gas/riscv/dis-addr-3-32.d       | 12 +++
 gas/testsuite/gas/riscv/dis-addr-3-64.d       | 12 +++
 gas/testsuite/gas/riscv/dis-addr-3.s          | 15 ++++
 8 files changed, 179 insertions(+)
 rename gas/testsuite/gas/riscv/{auipc-x0.d => dis-addr-1.d} (100%)
 rename gas/testsuite/gas/riscv/{auipc-x0.s => dis-addr-1.s} (100%)
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2.s
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3.s

diff --git a/gas/testsuite/gas/riscv/auipc-x0.d b/gas/testsuite/gas/riscv/dis-addr-1.d
similarity index 100%
rename from gas/testsuite/gas/riscv/auipc-x0.d
rename to gas/testsuite/gas/riscv/dis-addr-1.d
diff --git a/gas/testsuite/gas/riscv/auipc-x0.s b/gas/testsuite/gas/riscv/dis-addr-1.s
similarity index 100%
rename from gas/testsuite/gas/riscv/auipc-x0.s
rename to gas/testsuite/gas/riscv/dis-addr-1.s
diff --git a/gas/testsuite/gas/riscv/dis-addr-2-32.d b/gas/testsuite/gas/riscv/dis-addr-2-32.d
new file mode 100644
index 00000000000..5117c3d8a0c
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-2-32.d
@@ -0,0 +1,31 @@
+#as: -march=rv32ic
+#source: dis-addr-2.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>
+[ 	]+[0-9a-f]+:[ 	]+fff00f83[ 	]+lb[   	]+t6,-1\(zero\) # ffffffff <addr_top>
diff --git a/gas/testsuite/gas/riscv/dis-addr-2-64.d b/gas/testsuite/gas/riscv/dis-addr-2-64.d
new file mode 100644
index 00000000000..d806bad25b4
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-2-64.d
@@ -0,0 +1,35 @@
+#as: -march=rv64ic -defsym rv64=1
+#source: dis-addr-2.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>
+[ 	]+[0-9a-f]+:[ 	]+fff00f83[ 	]+lb[   	]+t6,-1\(zero\) # ffffffffffffffff <addr_top>
diff --git a/gas/testsuite/gas/riscv/dis-addr-2.s b/gas/testsuite/gas/riscv/dis-addr-2.s
new file mode 100644
index 00000000000..cb7f0cd9dc2
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-2.s
@@ -0,0 +1,74 @@
+.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  # 0x104
+.set addr_jalr_rel_zero_neg, topbase + 0xfffff804  # -0x7fc
+.set addr_top,               topbase + 0xffffffff  # -1
+
+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)
+
+	# Access to the highest address
+	lb	t6, -1(zero)
diff --git a/gas/testsuite/gas/riscv/dis-addr-3-32.d b/gas/testsuite/gas/riscv/dis-addr-3-32.d
new file mode 100644
index 00000000000..42ca89850ac
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-3-32.d
@@ -0,0 +1,12 @@
+#as: -march=rv32i
+#source: dis-addr-3.s
+#objdump: -d
+
+.*:     file format elf32-(little|big)riscv
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+0051a283[ 	]+lw[   	]+t0,5\(gp\) # 4 <addr_rel_gp_pos>
+[ 	]+[0-9a-f]+:[ 	]+ffd1a303[ 	]+lw[   	]+t1,-3\(gp\) # fffffffc <addr_rel_gp_neg>
diff --git a/gas/testsuite/gas/riscv/dis-addr-3-64.d b/gas/testsuite/gas/riscv/dis-addr-3-64.d
new file mode 100644
index 00000000000..394c58fac96
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-3-64.d
@@ -0,0 +1,12 @@
+#as: -march=rv64i -defsym rv64=1
+#source: dis-addr-3.s
+#objdump: -d
+
+.*:     file format elf64-(little|big)riscv
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+0051a283[ 	]+lw[   	]+t0,5\(gp\) # 4 <addr_rel_gp_pos>
+[ 	]+[0-9a-f]+:[ 	]+ffd1a303[ 	]+lw[   	]+t1,-3\(gp\) # fffffffffffffffc <addr_rel_gp_neg>
diff --git a/gas/testsuite/gas/riscv/dis-addr-3.s b/gas/testsuite/gas/riscv/dis-addr-3.s
new file mode 100644
index 00000000000..6ba9fc7a39d
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-3.s
@@ -0,0 +1,15 @@
+.ifdef rv64
+topbase = 0xffffffff00000000
+.else
+topbase = 0
+.endif
+
+.set __global_pointer$, topbase + 0xffffffff  # -1
+.set addr_rel_gp_pos,             0x00000004  # +4
+.set addr_rel_gp_neg,   topbase + 0xfffffffc  # -4
+
+target:
+	# Use addresses relative to gp
+	# (gp is the highest address)
+	lw	t0, +5(gp)
+	lw	t1, -3(gp)
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v5 0/4] RISC-V: Fix address printer on the disassembler
  2022-08-09  3:44     ` [PATCH v4 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
                         ` (3 preceding siblings ...)
  2022-08-09  3:44       ` [PATCH v4 4/4] RISC-V: Add address printer tests on disassembler Tsukasa OI
@ 2022-08-09  4:41       ` Tsukasa OI
  2022-08-09  4:41         ` [PATCH v5 1/4] RISC-V: Print highest address on disassembler Tsukasa OI
                           ` (4 more replies)
  4 siblings, 5 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-09  4:41 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

Sorry Peter and Palmer,

I had put wrong attribution in the commit message.  I've fixed it (Peter found a
bug and Palmer suggested a fix: I reflected the fact).



Hello,

This patchset contains a fix to PR29342.

Tracker on GitHub:
<https://github.com/a4lg/binutils-gdb/wiki/riscv_dis_fix_addr>

Original Issue as reported by H. Peter Anvin:
<https://sourceware.org/bugzilla/show_bug.cgi?id=29342>



[Changes: v4 -> v5]

-   Fix incorrect attribution in the commit message.



[Changes: v3 -> v4]

-   Added a bug fix discovered by Palmer Dabbelt.
    The original bug was in 2018.
-   Added testcases to make sure that the bug is fixed.
-   Rebase (again)



[Changes: v2 -> v3]

-   Remove minor optimization (v2: PATCH 3/4)
    Further optimization (my disassembler optimization batch 2) revealed that
    scanning through the symbol table is necessary.  It means that breaking
    early doesn't help to improve the performance, even if the ELF file has
    the __global_pointer$ symbol.
    Because this "minor optimization" changed the behavior slightly, it's better
    to drop this one.
-   Rename testcase auipc-x0 to dis-addr-1
    I decided to group disassembler-printed address tests.
-   Rebase



[Performance Analysis (Summary): updated per v3]

This patch alone degrades the disassembler performance a bit (usually about 1%).
But I found my next batch of the disassembler optimization patchset somehow
shadows this.  In fact, Binutils with my optimization patchset 1 and Binutils
with my optimization patchset 1 plus this patchset has pretty much
the same performance.



[Changes: v1 -> v2]

-   Also allow `gp'-base symbol (__global_pointer$) to be the highest address
-   Add minor optimization (break early if multiple __global_pointer$ is found)
-   Rebase and minor copyediting



[Cover Letter from v1]

First of all, this bug is caused by address computation of maybe_print_address
on disassembling RV32 programs.

Let me show the pseudocode of `maybe_print_address':

    if (high part of the register [for address sequence] is set)
    {
        pd->print_addr = (high part) + offset;        // (1)
        unset high part (as used);
    }
    else if (base register == `gp' && __global_pointer$ is available)
        pd->print_addr = __global_pointer$ + offset;  // (2)
    else if (base register == `tp' || base register == `zero')
        pd->print_addr = offset;                      // (3)
    // Sign-extend a 32-bit value to 64-bit
    if (instruction is ADDIW or C.ADDIW)
        pd->print_addr = (bfd_vma)(int32_t)pd->print_addr;

In here, it implicitly sign-extends an `int'-typed variable `offset' to generate
an address.  (3) is the direct cause of PR29342 but other locations have
similar issue.

On an example provided by Peter, IOREG_FOO has an address value of 0xffffff00.
However, due to incorrect sign-extension, the disassembler considers that the
`sw' instruction operates on an incorrect address 0xffffffff_ffffff00 EVEN ON
RV32.  This affects symbol lookup.  So, we have to mask (and zero-extend) the
address on RV32 to get correct address 0xffffff00.

Also, the background provided by Peter gives us a context: highest address space
may be important for some systems/programs.  So, not only fixing PR29342, I
decided to make the address -1 (originally reserved as a non-printing address)
printable by separating (a) the address to print and (b) whether the address
should be printed.  This isn't zero-overhead but close to.

This patchset:

1.  fits an address into a 32-bit value on RV32 (resolves PR29342)
2.  makes the highest address printable
    (0xffffffff can be printed as a real symbol)
3.  clarifies the meaning of the `wide' argument
    (`is_addiw' fits the context).

It also has new testcases and a testcase modification (it seems lla32.d is
affected by this patchset but not harmful so that modifying the testcase
lla32.d seemed better).

Thanks,
Tsukasa




Tsukasa OI (4):
  RISC-V: Print highest address on disassembler
  RISC-V: Fix RV32 disassembler address computation
  RISC-V: Fix JALR target address computation
  RISC-V: Add address printer tests on disassembler

 .../gas/riscv/{auipc-x0.d => dis-addr-1.d}    |  0
 .../gas/riscv/{auipc-x0.s => dis-addr-1.s}    |  0
 gas/testsuite/gas/riscv/dis-addr-2-32.d       | 31 ++++++++
 gas/testsuite/gas/riscv/dis-addr-2-64.d       | 35 +++++++++
 gas/testsuite/gas/riscv/dis-addr-2.s          | 74 +++++++++++++++++++
 gas/testsuite/gas/riscv/dis-addr-3-32.d       | 12 +++
 gas/testsuite/gas/riscv/dis-addr-3-64.d       | 12 +++
 gas/testsuite/gas/riscv/dis-addr-3.s          | 15 ++++
 gas/testsuite/gas/riscv/lla32.d               |  2 +-
 opcodes/riscv-dis.c                           | 46 ++++++++----
 10 files changed, 210 insertions(+), 17 deletions(-)
 rename gas/testsuite/gas/riscv/{auipc-x0.d => dis-addr-1.d} (100%)
 rename gas/testsuite/gas/riscv/{auipc-x0.s => dis-addr-1.s} (100%)
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2.s
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3.s


base-commit: 65c9841b6fee984714509acef6e52366363072b6
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v5 1/4] RISC-V: Print highest address on disassembler
  2022-08-09  4:41       ` [PATCH v5 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
@ 2022-08-09  4:41         ` Tsukasa OI
  2022-08-09  4:41         ` [PATCH v5 2/4] RISC-V: Fix RV32 disassembler address computation Tsukasa OI
                           ` (3 subsequent siblings)
  4 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-09  4:41 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

This patch makes possible to print the highest address (0xffffffff on RV32,
0xffffffff_ffffffff on RV64).  This is particularly useful if the highest
address space is used for I/O registers and corresponding symbols
are defined.

opcodes/ChangeLog:

	* riscv-dis.c (struct riscv_private_data): Add `to_print_addr' and
	`has_gp' to enable printing the highest address.
	(maybe_print_address): Utilize `to_print_addr' and `has_gp'.
	(riscv_disassemble_insn): Likewise.
---
 opcodes/riscv-dis.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 164fd209dbd..c6d80c3ba49 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -52,6 +52,8 @@ struct riscv_private_data
   bfd_vma gp;
   bfd_vma print_addr;
   bfd_vma hi_addr[OP_MASK_RD + 1];
+  bool to_print_addr;
+  bool has_gp;
 };
 
 /* Used for mapping symbols.  */
@@ -177,10 +179,13 @@ maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
       pd->print_addr = (base_reg != 0 ? pd->hi_addr[base_reg] : 0) + offset;
       pd->hi_addr[base_reg] = -1;
     }
-  else if (base_reg == X_GP && pd->gp != (bfd_vma)-1)
+  else if (base_reg == X_GP && pd->has_gp)
     pd->print_addr = pd->gp + offset;
   else if (base_reg == X_TP || base_reg == 0)
     pd->print_addr = offset;
+  else
+    return;
+  pd->to_print_addr = true;
 
   /* Sign-extend a 32-bit value to a 64-bit value.  */
   if (wide)
@@ -595,14 +600,19 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
       int i;
 
       pd = info->private_data = xcalloc (1, sizeof (struct riscv_private_data));
-      pd->gp = -1;
-      pd->print_addr = -1;
+      pd->gp = 0;
+      pd->print_addr = 0;
       for (i = 0; i < (int)ARRAY_SIZE (pd->hi_addr); i++)
 	pd->hi_addr[i] = -1;
+      pd->to_print_addr = false;
+      pd->has_gp = false;
 
       for (i = 0; i < info->symtab_size; i++)
 	if (strcmp (bfd_asymbol_name (info->symtab[i]), RISCV_GP_SYMBOL) == 0)
-	  pd->gp = bfd_asymbol_value (info->symtab[i]);
+	  {
+	    pd->gp = bfd_asymbol_value (info->symtab[i]);
+	    pd->has_gp = true;
+	  }
     }
   else
     pd = info->private_data;
@@ -662,13 +672,13 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
 	  print_insn_args (op->args, word, memaddr, info);
 
 	  /* Try to disassemble multi-instruction addressing sequences.  */
-	  if (pd->print_addr != (bfd_vma)-1)
+	  if (pd->to_print_addr)
 	    {
 	      info->target = pd->print_addr;
 	      (*info->fprintf_styled_func)
 		(info->stream, dis_style_comment_start, " # ");
 	      (*info->print_address_func) (info->target, info);
-	      pd->print_addr = -1;
+	      pd->to_print_addr = false;
 	    }
 
 	  /* Finish filling out insn_info fields.  */
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v5 2/4] RISC-V: Fix RV32 disassembler address computation
  2022-08-09  4:41       ` [PATCH v5 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
  2022-08-09  4:41         ` [PATCH v5 1/4] RISC-V: Print highest address on disassembler Tsukasa OI
@ 2022-08-09  4:41         ` Tsukasa OI
  2022-08-09  4:41         ` [PATCH v5 3/4] RISC-V: Fix JALR target " Tsukasa OI
                           ` (2 subsequent siblings)
  4 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-09  4:41 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

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 bug (including PR29342) by fitting an address into a 32-bit value
on RV32.

gas/ChangeLog:

	* testsuite/gas/riscv/lla32.d: Reflect RV32 address computation fix.

opcodes/ChangeLog:

	* riscv-dis.c (maybe_print_address): Clarify the role of the `wide'
	argument and rename to `is_addiw'.  Fit the address into 32-bit on
	RV32.  (print_insn_args): Reflect bool type of `is_addiw'.
---
 gas/testsuite/gas/riscv/lla32.d |  2 +-
 opcodes/riscv-dis.c             | 24 ++++++++++++++----------
 2 files changed, 15 insertions(+), 11 deletions(-)

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 c6d80c3ba49..419c4746db9 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -172,7 +172,7 @@ arg_print (struct disassemble_info *info, unsigned long val,
 
 static void
 maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
-		     int wide)
+		     bool is_addiw)
 {
   if (pd->hi_addr[base_reg] != (bfd_vma)-1)
     {
@@ -187,9 +187,13 @@ maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
     return;
   pd->to_print_addr = true;
 
-  /* Sign-extend a 32-bit value to a 64-bit value.  */
-  if (wide)
+  /* On ADDIW, Sign-extend a 32-bit value to a 64-bit value.  */
+  if (is_addiw)
     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.  */
@@ -239,10 +243,10 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	    case 'o':
 	    case 'j':
 	      if (((l & MASK_C_ADDI) == MATCH_C_ADDI) && rd != 0)
-		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), 0);
+		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), false);
 	      if (info->mach == bfd_mach_riscv64
 		  && ((l & MASK_C_ADDIW) == MATCH_C_ADDIW) && rd != 0)
-		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), 1);
+		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), true);
 	      print (info->stream, dis_style_immediate, "%d",
 		     (int)EXTRACT_CITYPE_IMM (l));
 	      break;
@@ -402,7 +406,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, 0, false);
 	  print (info->stream, dis_style_register, "%s", riscv_gpr_names[rs1]);
 	  break;
 
@@ -432,21 +436,21 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	  break;
 
 	case 'o':
-	  maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0);
+	  maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), false);
 	  /* Fall through.  */
 	case 'j':
 	  if (((l & MASK_ADDI) == MATCH_ADDI && rs1 != 0)
 	      || (l & MASK_JALR) == MATCH_JALR)
-	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0);
+	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), false);
 	  if (info->mach == bfd_mach_riscv64
 	      && ((l & MASK_ADDIW) == MATCH_ADDIW) && rs1 != 0)
-	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 1);
+	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), true);
 	  print (info->stream, dis_style_immediate, "%d",
 		 (int)EXTRACT_ITYPE_IMM (l));
 	  break;
 
 	case 'q':
-	  maybe_print_address (pd, rs1, EXTRACT_STYPE_IMM (l), 0);
+	  maybe_print_address (pd, rs1, EXTRACT_STYPE_IMM (l), false);
 	  print (info->stream, dis_style_address_offset, "%d",
 		 (int)EXTRACT_STYPE_IMM (l));
 	  break;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v5 3/4] RISC-V: Fix JALR target address computation
  2022-08-09  4:41       ` [PATCH v5 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
  2022-08-09  4:41         ` [PATCH v5 1/4] RISC-V: Print highest address on disassembler Tsukasa OI
  2022-08-09  4:41         ` [PATCH v5 2/4] RISC-V: Fix RV32 disassembler address computation Tsukasa OI
@ 2022-08-09  4:41         ` Tsukasa OI
  2022-08-09  4:41         ` [PATCH v5 4/4] RISC-V: Add address printer tests on disassembler Tsukasa OI
  2022-08-13 10:10         ` [PATCH v6 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
  4 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-09  4:41 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

H. Peter Anvin discovered that we have wrong address computation for JALR
instruction (the initial bug is back in 2018).  This commit will fix that
based on the idea of Palmer Dabbelt.

opcodes/ChangeLog:

	* riscv-dis.c (print_insn_args): Fix JALR address computation.
---
 opcodes/riscv-dis.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 419c4746db9..162a2971320 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -406,7 +406,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, false);
+	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), false);
 	  print (info->stream, dis_style_register, "%s", riscv_gpr_names[rs1]);
 	  break;
 
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v5 4/4] RISC-V: Add address printer tests on disassembler
  2022-08-09  4:41       ` [PATCH v5 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
                           ` (2 preceding siblings ...)
  2022-08-09  4:41         ` [PATCH v5 3/4] RISC-V: Fix JALR target " Tsukasa OI
@ 2022-08-09  4:41         ` Tsukasa OI
  2022-08-13 10:10         ` [PATCH v6 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
  4 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-09  4:41 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

This commit adds address printer tests on the disassembler focusing on
various path to/on maybe_print_address.  It also tests whether the address
adjustment on RV32 (fix to PR29342) works as expected, whether the highest
address is printed with a symbol and JALR address computation is fixed.

gas/ChangeLog:

	* testsuite/gas/riscv/dis-addr-a.s: Rename from auipc-x0.s.
	* testsuite/gas/riscv/dis-addr-a.d: Rename from auipc-x0.d.
	* testsuite/gas/riscv/dis-addr-2.s: New address printer tests
	on the disassembler.
	* testsuite/gas/riscv/dis-addr-2-32.d: Likewise.
	* testsuite/gas/riscv/dis-addr-2-64.d: Likewise.
	* testsuite/gas/riscv/dis-addr-3.s: New address printer tests
	on the disassembler if `gp' is the highest address.
	* testsuite/gas/riscv/dis-addr-3-32.d: Likewise.
	* testsuite/gas/riscv/dis-addr-3-64.d: Likewise.
---
 .../gas/riscv/{auipc-x0.d => dis-addr-1.d}    |  0
 .../gas/riscv/{auipc-x0.s => dis-addr-1.s}    |  0
 gas/testsuite/gas/riscv/dis-addr-2-32.d       | 31 ++++++++
 gas/testsuite/gas/riscv/dis-addr-2-64.d       | 35 +++++++++
 gas/testsuite/gas/riscv/dis-addr-2.s          | 74 +++++++++++++++++++
 gas/testsuite/gas/riscv/dis-addr-3-32.d       | 12 +++
 gas/testsuite/gas/riscv/dis-addr-3-64.d       | 12 +++
 gas/testsuite/gas/riscv/dis-addr-3.s          | 15 ++++
 8 files changed, 179 insertions(+)
 rename gas/testsuite/gas/riscv/{auipc-x0.d => dis-addr-1.d} (100%)
 rename gas/testsuite/gas/riscv/{auipc-x0.s => dis-addr-1.s} (100%)
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2.s
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3.s

diff --git a/gas/testsuite/gas/riscv/auipc-x0.d b/gas/testsuite/gas/riscv/dis-addr-1.d
similarity index 100%
rename from gas/testsuite/gas/riscv/auipc-x0.d
rename to gas/testsuite/gas/riscv/dis-addr-1.d
diff --git a/gas/testsuite/gas/riscv/auipc-x0.s b/gas/testsuite/gas/riscv/dis-addr-1.s
similarity index 100%
rename from gas/testsuite/gas/riscv/auipc-x0.s
rename to gas/testsuite/gas/riscv/dis-addr-1.s
diff --git a/gas/testsuite/gas/riscv/dis-addr-2-32.d b/gas/testsuite/gas/riscv/dis-addr-2-32.d
new file mode 100644
index 00000000000..5117c3d8a0c
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-2-32.d
@@ -0,0 +1,31 @@
+#as: -march=rv32ic
+#source: dis-addr-2.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>
+[ 	]+[0-9a-f]+:[ 	]+fff00f83[ 	]+lb[   	]+t6,-1\(zero\) # ffffffff <addr_top>
diff --git a/gas/testsuite/gas/riscv/dis-addr-2-64.d b/gas/testsuite/gas/riscv/dis-addr-2-64.d
new file mode 100644
index 00000000000..d806bad25b4
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-2-64.d
@@ -0,0 +1,35 @@
+#as: -march=rv64ic -defsym rv64=1
+#source: dis-addr-2.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>
+[ 	]+[0-9a-f]+:[ 	]+fff00f83[ 	]+lb[   	]+t6,-1\(zero\) # ffffffffffffffff <addr_top>
diff --git a/gas/testsuite/gas/riscv/dis-addr-2.s b/gas/testsuite/gas/riscv/dis-addr-2.s
new file mode 100644
index 00000000000..cb7f0cd9dc2
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-2.s
@@ -0,0 +1,74 @@
+.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  # 0x104
+.set addr_jalr_rel_zero_neg, topbase + 0xfffff804  # -0x7fc
+.set addr_top,               topbase + 0xffffffff  # -1
+
+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)
+
+	# Access to the highest address
+	lb	t6, -1(zero)
diff --git a/gas/testsuite/gas/riscv/dis-addr-3-32.d b/gas/testsuite/gas/riscv/dis-addr-3-32.d
new file mode 100644
index 00000000000..42ca89850ac
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-3-32.d
@@ -0,0 +1,12 @@
+#as: -march=rv32i
+#source: dis-addr-3.s
+#objdump: -d
+
+.*:     file format elf32-(little|big)riscv
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+0051a283[ 	]+lw[   	]+t0,5\(gp\) # 4 <addr_rel_gp_pos>
+[ 	]+[0-9a-f]+:[ 	]+ffd1a303[ 	]+lw[   	]+t1,-3\(gp\) # fffffffc <addr_rel_gp_neg>
diff --git a/gas/testsuite/gas/riscv/dis-addr-3-64.d b/gas/testsuite/gas/riscv/dis-addr-3-64.d
new file mode 100644
index 00000000000..394c58fac96
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-3-64.d
@@ -0,0 +1,12 @@
+#as: -march=rv64i -defsym rv64=1
+#source: dis-addr-3.s
+#objdump: -d
+
+.*:     file format elf64-(little|big)riscv
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+0051a283[ 	]+lw[   	]+t0,5\(gp\) # 4 <addr_rel_gp_pos>
+[ 	]+[0-9a-f]+:[ 	]+ffd1a303[ 	]+lw[   	]+t1,-3\(gp\) # fffffffffffffffc <addr_rel_gp_neg>
diff --git a/gas/testsuite/gas/riscv/dis-addr-3.s b/gas/testsuite/gas/riscv/dis-addr-3.s
new file mode 100644
index 00000000000..6ba9fc7a39d
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-3.s
@@ -0,0 +1,15 @@
+.ifdef rv64
+topbase = 0xffffffff00000000
+.else
+topbase = 0
+.endif
+
+.set __global_pointer$, topbase + 0xffffffff  # -1
+.set addr_rel_gp_pos,             0x00000004  # +4
+.set addr_rel_gp_neg,   topbase + 0xfffffffc  # -4
+
+target:
+	# Use addresses relative to gp
+	# (gp is the highest address)
+	lw	t0, +5(gp)
+	lw	t1, -3(gp)
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v6 0/4] RISC-V: Fix address printer on the disassembler
  2022-08-09  4:41       ` [PATCH v5 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
                           ` (3 preceding siblings ...)
  2022-08-09  4:41         ` [PATCH v5 4/4] RISC-V: Add address printer tests on disassembler Tsukasa OI
@ 2022-08-13 10:10         ` Tsukasa OI
  2022-08-13 10:10           ` [PATCH v6 1/4] RISC-V: Print highest address on disassembler Tsukasa OI
                             ` (4 more replies)
  4 siblings, 5 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-13 10:10 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

Hello,

This patchset contains a fix to PR29342.
Not only this patchset fixes a Bugzilla issue, it's also a requirement of
my future core disassembler changes.  So, it would be nice that this fix
is merged soon.

Tracker on GitHub:
<https://github.com/a4lg/binutils-gdb/wiki/riscv_dis_fix_addr>

Original Issue as reported by H. Peter Anvin:
<https://sourceware.org/bugzilla/show_bug.cgi?id=29342>



[Changes: v5 -> v6]

-   Fix wrong file name in the ChangeLog
    Sorry for making small mistakes repeatedly...
-   Rebase (again)



[Changes: v4 -> v5]

-   Fix incorrect attribution in the commit message.



[Changes: v3 -> v4]

-   Added a bug fix discovered by Palmer Dabbelt.
    The original bug was in 2018.
-   Added testcases to make sure that the bug is fixed.
-   Rebase (again)



[Changes: v2 -> v3]

-   Remove minor optimization (v2: PATCH 3/4)
    Further optimization (my disassembler optimization batch 2) revealed that
    scanning through the symbol table is necessary.  It means that breaking
    early doesn't help to improve the performance, even if the ELF file has
    the __global_pointer$ symbol.
    Because this "minor optimization" changed the behavior slightly, it's better
    to drop this one.
-   Rename testcase auipc-x0 to dis-addr-1
    I decided to group disassembler-printed address tests.
-   Rebase



[Performance Analysis (Summary): updated per v3]

This patch alone degrades the disassembler performance a bit (usually about 1%).
But I found my next batch of the disassembler optimization patchset somehow
shadows this.  In fact, Binutils with my optimization patchset 1 and Binutils
with my optimization patchset 1 plus this patchset has pretty much
the same performance.



[Changes: v1 -> v2]

-   Also allow `gp'-base symbol (__global_pointer$) to be the highest address
-   Add minor optimization (break early if multiple __global_pointer$ is found)
-   Rebase and minor copyediting



[Cover Letter from v1]

First of all, this bug is caused by address computation of maybe_print_address
on disassembling RV32 programs.

Let me show the pseudocode of `maybe_print_address':

    if (high part of the register [for address sequence] is set)
    {
        pd->print_addr = (high part) + offset;        // (1)
        unset high part (as used);
    }
    else if (base register == `gp' && __global_pointer$ is available)
        pd->print_addr = __global_pointer$ + offset;  // (2)
    else if (base register == `tp' || base register == `zero')
        pd->print_addr = offset;                      // (3)
    // Sign-extend a 32-bit value to 64-bit
    if (instruction is ADDIW or C.ADDIW)
        pd->print_addr = (bfd_vma)(int32_t)pd->print_addr;

In here, it implicitly sign-extends an `int'-typed variable `offset' to generate
an address.  (3) is the direct cause of PR29342 but other locations have
similar issue.

On an example provided by Peter, IOREG_FOO has an address value of 0xffffff00.
However, due to incorrect sign-extension, the disassembler considers that the
`sw' instruction operates on an incorrect address 0xffffffff_ffffff00 EVEN ON
RV32.  This affects symbol lookup.  So, we have to mask (and zero-extend) the
address on RV32 to get correct address 0xffffff00.

Also, the background provided by Peter gives us a context: highest address space
may be important for some systems/programs.  So, not only fixing PR29342, I
decided to make the address -1 (originally reserved as a non-printing address)
printable by separating (a) the address to print and (b) whether the address
should be printed.  This isn't zero-overhead but close to.

This patchset:

1.  fits an address into a 32-bit value on RV32 (resolves PR29342)
2.  makes the highest address printable
    (0xffffffff can be printed as a real symbol)
3.  clarifies the meaning of the `wide' argument
    (`is_addiw' fits the context).

It also has new testcases and a testcase modification (it seems lla32.d is
affected by this patchset but not harmful so that modifying the testcase
lla32.d seemed better).

Thanks,
Tsukasa




Tsukasa OI (4):
  RISC-V: Print highest address on disassembler
  RISC-V: Fix RV32 disassembler address computation
  RISC-V: Fix JALR target address computation
  RISC-V: Add address printer tests on disassembler

 .../gas/riscv/{auipc-x0.d => dis-addr-1.d}    |  0
 .../gas/riscv/{auipc-x0.s => dis-addr-1.s}    |  0
 gas/testsuite/gas/riscv/dis-addr-2-32.d       | 31 ++++++++
 gas/testsuite/gas/riscv/dis-addr-2-64.d       | 35 +++++++++
 gas/testsuite/gas/riscv/dis-addr-2.s          | 74 +++++++++++++++++++
 gas/testsuite/gas/riscv/dis-addr-3-32.d       | 12 +++
 gas/testsuite/gas/riscv/dis-addr-3-64.d       | 12 +++
 gas/testsuite/gas/riscv/dis-addr-3.s          | 15 ++++
 gas/testsuite/gas/riscv/lla32.d               |  2 +-
 opcodes/riscv-dis.c                           | 46 ++++++++----
 10 files changed, 210 insertions(+), 17 deletions(-)
 rename gas/testsuite/gas/riscv/{auipc-x0.d => dis-addr-1.d} (100%)
 rename gas/testsuite/gas/riscv/{auipc-x0.s => dis-addr-1.s} (100%)
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2.s
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3.s


base-commit: ef186fe54aa6d281a3ff8a9528417e5cc614c797
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v6 1/4] RISC-V: Print highest address on disassembler
  2022-08-13 10:10         ` [PATCH v6 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
@ 2022-08-13 10:10           ` Tsukasa OI
  2022-08-13 10:10           ` [PATCH v6 2/4] RISC-V: Fix RV32 disassembler address computation Tsukasa OI
                             ` (3 subsequent siblings)
  4 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-13 10:10 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

This patch makes possible to print the highest address (0xffffffff on RV32,
0xffffffff_ffffffff on RV64).  This is particularly useful if the highest
address space is used for I/O registers and corresponding symbols
are defined.

opcodes/ChangeLog:

	* riscv-dis.c (struct riscv_private_data): Add `to_print_addr' and
	`has_gp' to enable printing the highest address.
	(maybe_print_address): Utilize `to_print_addr' and `has_gp'.
	(riscv_disassemble_insn): Likewise.
---
 opcodes/riscv-dis.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 164fd209dbd..c6d80c3ba49 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -52,6 +52,8 @@ struct riscv_private_data
   bfd_vma gp;
   bfd_vma print_addr;
   bfd_vma hi_addr[OP_MASK_RD + 1];
+  bool to_print_addr;
+  bool has_gp;
 };
 
 /* Used for mapping symbols.  */
@@ -177,10 +179,13 @@ maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
       pd->print_addr = (base_reg != 0 ? pd->hi_addr[base_reg] : 0) + offset;
       pd->hi_addr[base_reg] = -1;
     }
-  else if (base_reg == X_GP && pd->gp != (bfd_vma)-1)
+  else if (base_reg == X_GP && pd->has_gp)
     pd->print_addr = pd->gp + offset;
   else if (base_reg == X_TP || base_reg == 0)
     pd->print_addr = offset;
+  else
+    return;
+  pd->to_print_addr = true;
 
   /* Sign-extend a 32-bit value to a 64-bit value.  */
   if (wide)
@@ -595,14 +600,19 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
       int i;
 
       pd = info->private_data = xcalloc (1, sizeof (struct riscv_private_data));
-      pd->gp = -1;
-      pd->print_addr = -1;
+      pd->gp = 0;
+      pd->print_addr = 0;
       for (i = 0; i < (int)ARRAY_SIZE (pd->hi_addr); i++)
 	pd->hi_addr[i] = -1;
+      pd->to_print_addr = false;
+      pd->has_gp = false;
 
       for (i = 0; i < info->symtab_size; i++)
 	if (strcmp (bfd_asymbol_name (info->symtab[i]), RISCV_GP_SYMBOL) == 0)
-	  pd->gp = bfd_asymbol_value (info->symtab[i]);
+	  {
+	    pd->gp = bfd_asymbol_value (info->symtab[i]);
+	    pd->has_gp = true;
+	  }
     }
   else
     pd = info->private_data;
@@ -662,13 +672,13 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
 	  print_insn_args (op->args, word, memaddr, info);
 
 	  /* Try to disassemble multi-instruction addressing sequences.  */
-	  if (pd->print_addr != (bfd_vma)-1)
+	  if (pd->to_print_addr)
 	    {
 	      info->target = pd->print_addr;
 	      (*info->fprintf_styled_func)
 		(info->stream, dis_style_comment_start, " # ");
 	      (*info->print_address_func) (info->target, info);
-	      pd->print_addr = -1;
+	      pd->to_print_addr = false;
 	    }
 
 	  /* Finish filling out insn_info fields.  */
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v6 2/4] RISC-V: Fix RV32 disassembler address computation
  2022-08-13 10:10         ` [PATCH v6 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
  2022-08-13 10:10           ` [PATCH v6 1/4] RISC-V: Print highest address on disassembler Tsukasa OI
@ 2022-08-13 10:10           ` Tsukasa OI
  2022-08-13 10:10           ` [PATCH v6 3/4] RISC-V: Fix JALR target " Tsukasa OI
                             ` (2 subsequent siblings)
  4 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-13 10:10 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

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 bug (including PR29342) by fitting an address into a 32-bit value
on RV32.

gas/ChangeLog:

	* testsuite/gas/riscv/lla32.d: Reflect RV32 address computation fix.

opcodes/ChangeLog:

	* riscv-dis.c (maybe_print_address): Clarify the role of the `wide'
	argument and rename to `is_addiw'.  Fit the address into 32-bit on
	RV32.  (print_insn_args): Reflect bool type of `is_addiw'.
---
 gas/testsuite/gas/riscv/lla32.d |  2 +-
 opcodes/riscv-dis.c             | 24 ++++++++++++++----------
 2 files changed, 15 insertions(+), 11 deletions(-)

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 c6d80c3ba49..419c4746db9 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -172,7 +172,7 @@ arg_print (struct disassemble_info *info, unsigned long val,
 
 static void
 maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
-		     int wide)
+		     bool is_addiw)
 {
   if (pd->hi_addr[base_reg] != (bfd_vma)-1)
     {
@@ -187,9 +187,13 @@ maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
     return;
   pd->to_print_addr = true;
 
-  /* Sign-extend a 32-bit value to a 64-bit value.  */
-  if (wide)
+  /* On ADDIW, Sign-extend a 32-bit value to a 64-bit value.  */
+  if (is_addiw)
     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.  */
@@ -239,10 +243,10 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	    case 'o':
 	    case 'j':
 	      if (((l & MASK_C_ADDI) == MATCH_C_ADDI) && rd != 0)
-		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), 0);
+		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), false);
 	      if (info->mach == bfd_mach_riscv64
 		  && ((l & MASK_C_ADDIW) == MATCH_C_ADDIW) && rd != 0)
-		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), 1);
+		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), true);
 	      print (info->stream, dis_style_immediate, "%d",
 		     (int)EXTRACT_CITYPE_IMM (l));
 	      break;
@@ -402,7 +406,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, 0, false);
 	  print (info->stream, dis_style_register, "%s", riscv_gpr_names[rs1]);
 	  break;
 
@@ -432,21 +436,21 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	  break;
 
 	case 'o':
-	  maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0);
+	  maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), false);
 	  /* Fall through.  */
 	case 'j':
 	  if (((l & MASK_ADDI) == MATCH_ADDI && rs1 != 0)
 	      || (l & MASK_JALR) == MATCH_JALR)
-	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0);
+	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), false);
 	  if (info->mach == bfd_mach_riscv64
 	      && ((l & MASK_ADDIW) == MATCH_ADDIW) && rs1 != 0)
-	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 1);
+	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), true);
 	  print (info->stream, dis_style_immediate, "%d",
 		 (int)EXTRACT_ITYPE_IMM (l));
 	  break;
 
 	case 'q':
-	  maybe_print_address (pd, rs1, EXTRACT_STYPE_IMM (l), 0);
+	  maybe_print_address (pd, rs1, EXTRACT_STYPE_IMM (l), false);
 	  print (info->stream, dis_style_address_offset, "%d",
 		 (int)EXTRACT_STYPE_IMM (l));
 	  break;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v6 3/4] RISC-V: Fix JALR target address computation
  2022-08-13 10:10         ` [PATCH v6 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
  2022-08-13 10:10           ` [PATCH v6 1/4] RISC-V: Print highest address on disassembler Tsukasa OI
  2022-08-13 10:10           ` [PATCH v6 2/4] RISC-V: Fix RV32 disassembler address computation Tsukasa OI
@ 2022-08-13 10:10           ` Tsukasa OI
  2022-08-13 10:10           ` [PATCH v6 4/4] RISC-V: Add address printer tests on disassembler Tsukasa OI
  2022-08-24  1:26           ` [PATCH v7 0/5] RISC-V: Fix address printer on the disassembler Tsukasa OI
  4 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-13 10:10 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

H. Peter Anvin discovered that we have wrong address computation for JALR
instruction (the initial bug is back in 2018).  This commit will fix that
based on the idea of Palmer Dabbelt.

opcodes/ChangeLog:

	* riscv-dis.c (print_insn_args): Fix JALR address computation.
---
 opcodes/riscv-dis.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 419c4746db9..162a2971320 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -406,7 +406,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, false);
+	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), false);
 	  print (info->stream, dis_style_register, "%s", riscv_gpr_names[rs1]);
 	  break;
 
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v6 4/4] RISC-V: Add address printer tests on disassembler
  2022-08-13 10:10         ` [PATCH v6 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
                             ` (2 preceding siblings ...)
  2022-08-13 10:10           ` [PATCH v6 3/4] RISC-V: Fix JALR target " Tsukasa OI
@ 2022-08-13 10:10           ` Tsukasa OI
  2022-08-24  1:26           ` [PATCH v7 0/5] RISC-V: Fix address printer on the disassembler Tsukasa OI
  4 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-13 10:10 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Nelson Chu, Kito Cheng, Palmer Dabbelt
  Cc: binutils

This commit adds address printer tests on the disassembler focusing on
various path to/on maybe_print_address.  It also tests whether the address
adjustment on RV32 (fix to PR29342) works as expected, whether the highest
address is printed with a symbol and JALR address computation is fixed.

gas/ChangeLog:

	* testsuite/gas/riscv/dis-addr-1.s: Rename from auipc-x0.s.
	* testsuite/gas/riscv/dis-addr-1.d: Rename from auipc-x0.d.
	* testsuite/gas/riscv/dis-addr-2.s: New address printer tests
	on the disassembler.
	* testsuite/gas/riscv/dis-addr-2-32.d: Likewise.
	* testsuite/gas/riscv/dis-addr-2-64.d: Likewise.
	* testsuite/gas/riscv/dis-addr-3.s: New address printer tests
	on the disassembler if `gp' is the highest address.
	* testsuite/gas/riscv/dis-addr-3-32.d: Likewise.
	* testsuite/gas/riscv/dis-addr-3-64.d: Likewise.
---
 .../gas/riscv/{auipc-x0.d => dis-addr-1.d}    |  0
 .../gas/riscv/{auipc-x0.s => dis-addr-1.s}    |  0
 gas/testsuite/gas/riscv/dis-addr-2-32.d       | 31 ++++++++
 gas/testsuite/gas/riscv/dis-addr-2-64.d       | 35 +++++++++
 gas/testsuite/gas/riscv/dis-addr-2.s          | 74 +++++++++++++++++++
 gas/testsuite/gas/riscv/dis-addr-3-32.d       | 12 +++
 gas/testsuite/gas/riscv/dis-addr-3-64.d       | 12 +++
 gas/testsuite/gas/riscv/dis-addr-3.s          | 15 ++++
 8 files changed, 179 insertions(+)
 rename gas/testsuite/gas/riscv/{auipc-x0.d => dis-addr-1.d} (100%)
 rename gas/testsuite/gas/riscv/{auipc-x0.s => dis-addr-1.s} (100%)
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2.s
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3.s

diff --git a/gas/testsuite/gas/riscv/auipc-x0.d b/gas/testsuite/gas/riscv/dis-addr-1.d
similarity index 100%
rename from gas/testsuite/gas/riscv/auipc-x0.d
rename to gas/testsuite/gas/riscv/dis-addr-1.d
diff --git a/gas/testsuite/gas/riscv/auipc-x0.s b/gas/testsuite/gas/riscv/dis-addr-1.s
similarity index 100%
rename from gas/testsuite/gas/riscv/auipc-x0.s
rename to gas/testsuite/gas/riscv/dis-addr-1.s
diff --git a/gas/testsuite/gas/riscv/dis-addr-2-32.d b/gas/testsuite/gas/riscv/dis-addr-2-32.d
new file mode 100644
index 00000000000..5117c3d8a0c
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-2-32.d
@@ -0,0 +1,31 @@
+#as: -march=rv32ic
+#source: dis-addr-2.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>
+[ 	]+[0-9a-f]+:[ 	]+fff00f83[ 	]+lb[   	]+t6,-1\(zero\) # ffffffff <addr_top>
diff --git a/gas/testsuite/gas/riscv/dis-addr-2-64.d b/gas/testsuite/gas/riscv/dis-addr-2-64.d
new file mode 100644
index 00000000000..d806bad25b4
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-2-64.d
@@ -0,0 +1,35 @@
+#as: -march=rv64ic -defsym rv64=1
+#source: dis-addr-2.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>
+[ 	]+[0-9a-f]+:[ 	]+fff00f83[ 	]+lb[   	]+t6,-1\(zero\) # ffffffffffffffff <addr_top>
diff --git a/gas/testsuite/gas/riscv/dis-addr-2.s b/gas/testsuite/gas/riscv/dis-addr-2.s
new file mode 100644
index 00000000000..cb7f0cd9dc2
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-2.s
@@ -0,0 +1,74 @@
+.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  # 0x104
+.set addr_jalr_rel_zero_neg, topbase + 0xfffff804  # -0x7fc
+.set addr_top,               topbase + 0xffffffff  # -1
+
+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)
+
+	# Access to the highest address
+	lb	t6, -1(zero)
diff --git a/gas/testsuite/gas/riscv/dis-addr-3-32.d b/gas/testsuite/gas/riscv/dis-addr-3-32.d
new file mode 100644
index 00000000000..42ca89850ac
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-3-32.d
@@ -0,0 +1,12 @@
+#as: -march=rv32i
+#source: dis-addr-3.s
+#objdump: -d
+
+.*:     file format elf32-(little|big)riscv
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+0051a283[ 	]+lw[   	]+t0,5\(gp\) # 4 <addr_rel_gp_pos>
+[ 	]+[0-9a-f]+:[ 	]+ffd1a303[ 	]+lw[   	]+t1,-3\(gp\) # fffffffc <addr_rel_gp_neg>
diff --git a/gas/testsuite/gas/riscv/dis-addr-3-64.d b/gas/testsuite/gas/riscv/dis-addr-3-64.d
new file mode 100644
index 00000000000..394c58fac96
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-3-64.d
@@ -0,0 +1,12 @@
+#as: -march=rv64i -defsym rv64=1
+#source: dis-addr-3.s
+#objdump: -d
+
+.*:     file format elf64-(little|big)riscv
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+0051a283[ 	]+lw[   	]+t0,5\(gp\) # 4 <addr_rel_gp_pos>
+[ 	]+[0-9a-f]+:[ 	]+ffd1a303[ 	]+lw[   	]+t1,-3\(gp\) # fffffffffffffffc <addr_rel_gp_neg>
diff --git a/gas/testsuite/gas/riscv/dis-addr-3.s b/gas/testsuite/gas/riscv/dis-addr-3.s
new file mode 100644
index 00000000000..6ba9fc7a39d
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-3.s
@@ -0,0 +1,15 @@
+.ifdef rv64
+topbase = 0xffffffff00000000
+.else
+topbase = 0
+.endif
+
+.set __global_pointer$, topbase + 0xffffffff  # -1
+.set addr_rel_gp_pos,             0x00000004  # +4
+.set addr_rel_gp_neg,   topbase + 0xfffffffc  # -4
+
+target:
+	# Use addresses relative to gp
+	# (gp is the highest address)
+	lw	t0, +5(gp)
+	lw	t1, -3(gp)
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v7 0/5] RISC-V: Fix address printer on the disassembler
  2022-08-13 10:10         ` [PATCH v6 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
                             ` (3 preceding siblings ...)
  2022-08-13 10:10           ` [PATCH v6 4/4] RISC-V: Add address printer tests on disassembler Tsukasa OI
@ 2022-08-24  1:26           ` Tsukasa OI
  2022-08-24  1:26             ` [PATCH v7 1/5] RISC-V: Print highest address on disassembler Tsukasa OI
                               ` (4 more replies)
  4 siblings, 5 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-24  1:26 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Palmer Dabbelt, Andrew Waterman,
	Jim Wilson, Nelson Chu
  Cc: binutils

Hello,

This patchset contains a fix to PR29342.
Not only this patchset fixes a Bugzilla issue, it's also a requirement of
my future core disassembler changes.  So, it would be nice that this fix
is merged soon.

Tracker on GitHub:
<https://github.com/a4lg/binutils-gdb/wiki/riscv_dis_fix_addr>

Original Issue as reported by H. Peter Anvin:
<https://sourceware.org/bugzilla/show_bug.cgi?id=29342>



[Changes: v6 -> v7]

-   Add tests involving ADDIW/C.ADDIW instructions
    I found that some MIPS tests used `--adjust-vma' and that can be used
    to adjust text segment to pretty much any location.  Using this, it
    enabled to test ADDIW/C.ADDIW corner cases.
    Note that regular section (with non-zero base address) and non-linked
    section (with zero base address) with --adjust-vma is indistinguishable
    from the view of libopcodes.
-   Rebase (every time)



[Changes: v5 -> v6]

-   Fix wrong file name in the ChangeLog
    Sorry for making small mistakes repeatedly...
-   Rebase (again)



[Changes: v4 -> v5]

-   Fix incorrect attribution in the commit message.



[Changes: v3 -> v4]

-   Added a bug fix discovered by Palmer Dabbelt.
    The original bug was in 2018.
-   Added testcases to make sure that the bug is fixed.
-   Rebase (again)



[Changes: v2 -> v3]

-   Remove minor optimization (v2: PATCH 3/4)
    Further optimization (my disassembler optimization batch 2) revealed that
    scanning through the symbol table is necessary.  It means that breaking
    early doesn't help to improve the performance, even if the ELF file has
    the __global_pointer$ symbol.
    Because this "minor optimization" changed the behavior slightly, it's better
    to drop this one.
-   Rename testcase auipc-x0 to dis-addr-1
    I decided to group disassembler-printed address tests.
-   Rebase



[Performance Analysis (Summary): updated per v3]

This patch alone degrades the disassembler performance a bit (usually about 1%).
But I found my next batch of the disassembler optimization patchset somehow
shadows this.  In fact, Binutils with my optimization patchset 1 and Binutils
with my optimization patchset 1 plus this patchset has pretty much
the same performance.



[Changes: v1 -> v2]

-   Also allow `gp'-base symbol (__global_pointer$) to be the highest address
-   Add minor optimization (break early if multiple __global_pointer$ is found)
-   Rebase and minor copyediting



[Cover Letter from v1]

First of all, this bug is caused by address computation of maybe_print_address
on disassembling RV32 programs.

Let me show the pseudocode of `maybe_print_address':

    if (high part of the register [for address sequence] is set)
    {
        pd->print_addr = (high part) + offset;        // (1)
        unset high part (as used);
    }
    else if (base register == `gp' && __global_pointer$ is available)
        pd->print_addr = __global_pointer$ + offset;  // (2)
    else if (base register == `tp' || base register == `zero')
        pd->print_addr = offset;                      // (3)
    // Sign-extend a 32-bit value to 64-bit
    if (instruction is ADDIW or C.ADDIW)
        pd->print_addr = (bfd_vma)(int32_t)pd->print_addr;

In here, it implicitly sign-extends an `int'-typed variable `offset' to generate
an address.  (3) is the direct cause of PR29342 but other locations have
similar issue.

On an example provided by Peter, IOREG_FOO has an address value of 0xffffff00.
However, due to incorrect sign-extension, the disassembler considers that the
`sw' instruction operates on an incorrect address 0xffffffff_ffffff00 EVEN ON
RV32.  This affects symbol lookup.  So, we have to mask (and zero-extend) the
address on RV32 to get correct address 0xffffff00.

Also, the background provided by Peter gives us a context: highest address space
may be important for some systems/programs.  So, not only fixing PR29342, I
decided to make the address -1 (originally reserved as a non-printing address)
printable by separating (a) the address to print and (b) whether the address
should be printed.  This isn't zero-overhead but close to.

This patchset:

1.  fits an address into a 32-bit value on RV32 (resolves PR29342)
2.  makes the highest address printable
    (0xffffffff can be printed as a real symbol)
3.  clarifies the meaning of the `wide' argument
    (`is_addiw' fits the context).

It also has new testcases and a testcase modification (it seems lla32.d is
affected by this patchset but not harmful so that modifying the testcase
lla32.d seemed better).

Thanks,
Tsukasa




Tsukasa OI (5):
  RISC-V: Print highest address on disassembler
  RISC-V: Fix RV32 disassembler address computation
  RISC-V: Fix JALR target address computation
  RISC-V: Add address printer tests on disassembler
  RISC-V: Add address printer tests with ADDIW

 .../gas/riscv/{auipc-x0.d => dis-addr-1.d}    |  0
 .../gas/riscv/{auipc-x0.s => dis-addr-1.s}    |  0
 gas/testsuite/gas/riscv/dis-addr-2-32.d       | 31 ++++++++
 gas/testsuite/gas/riscv/dis-addr-2-64.d       | 35 +++++++++
 gas/testsuite/gas/riscv/dis-addr-2.s          | 74 +++++++++++++++++++
 gas/testsuite/gas/riscv/dis-addr-3-32.d       | 12 +++
 gas/testsuite/gas/riscv/dis-addr-3-64.d       | 12 +++
 gas/testsuite/gas/riscv/dis-addr-3.s          | 15 ++++
 gas/testsuite/gas/riscv/dis-addr-4.s          | 28 +++++++
 gas/testsuite/gas/riscv/dis-addr-4a.d         | 18 +++++
 gas/testsuite/gas/riscv/dis-addr-4b.d         | 18 +++++
 gas/testsuite/gas/riscv/lla32.d               |  2 +-
 opcodes/riscv-dis.c                           | 46 ++++++++----
 13 files changed, 274 insertions(+), 17 deletions(-)
 rename gas/testsuite/gas/riscv/{auipc-x0.d => dis-addr-1.d} (100%)
 rename gas/testsuite/gas/riscv/{auipc-x0.s => dis-addr-1.s} (100%)
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2.s
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3.s
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-4.s
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-4a.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-4b.d


base-commit: 044193ebf6a2197a36c75cbc1ec7e77440a37b26
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v7 1/5] RISC-V: Print highest address on disassembler
  2022-08-24  1:26           ` [PATCH v7 0/5] RISC-V: Fix address printer on the disassembler Tsukasa OI
@ 2022-08-24  1:26             ` Tsukasa OI
  2022-08-24 11:22               ` Nelson Chu
  2022-08-24  1:26             ` [PATCH v7 2/5] RISC-V: Fix RV32 disassembler address computation Tsukasa OI
                               ` (3 subsequent siblings)
  4 siblings, 1 reply; 48+ messages in thread
From: Tsukasa OI @ 2022-08-24  1:26 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Palmer Dabbelt, Andrew Waterman,
	Jim Wilson, Nelson Chu
  Cc: binutils

This patch makes possible to print the highest address (0xffffffff on RV32,
0xffffffff_ffffffff on RV64).  This is particularly useful if the highest
address space is used for I/O registers and corresponding symbols
are defined.

opcodes/ChangeLog:

	* riscv-dis.c (struct riscv_private_data): Add `to_print_addr' and
	`has_gp' to enable printing the highest address.
	(maybe_print_address): Utilize `to_print_addr' and `has_gp'.
	(riscv_disassemble_insn): Likewise.
---
 opcodes/riscv-dis.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 164fd209dbd..c6d80c3ba49 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -52,6 +52,8 @@ struct riscv_private_data
   bfd_vma gp;
   bfd_vma print_addr;
   bfd_vma hi_addr[OP_MASK_RD + 1];
+  bool to_print_addr;
+  bool has_gp;
 };
 
 /* Used for mapping symbols.  */
@@ -177,10 +179,13 @@ maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
       pd->print_addr = (base_reg != 0 ? pd->hi_addr[base_reg] : 0) + offset;
       pd->hi_addr[base_reg] = -1;
     }
-  else if (base_reg == X_GP && pd->gp != (bfd_vma)-1)
+  else if (base_reg == X_GP && pd->has_gp)
     pd->print_addr = pd->gp + offset;
   else if (base_reg == X_TP || base_reg == 0)
     pd->print_addr = offset;
+  else
+    return;
+  pd->to_print_addr = true;
 
   /* Sign-extend a 32-bit value to a 64-bit value.  */
   if (wide)
@@ -595,14 +600,19 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
       int i;
 
       pd = info->private_data = xcalloc (1, sizeof (struct riscv_private_data));
-      pd->gp = -1;
-      pd->print_addr = -1;
+      pd->gp = 0;
+      pd->print_addr = 0;
       for (i = 0; i < (int)ARRAY_SIZE (pd->hi_addr); i++)
 	pd->hi_addr[i] = -1;
+      pd->to_print_addr = false;
+      pd->has_gp = false;
 
       for (i = 0; i < info->symtab_size; i++)
 	if (strcmp (bfd_asymbol_name (info->symtab[i]), RISCV_GP_SYMBOL) == 0)
-	  pd->gp = bfd_asymbol_value (info->symtab[i]);
+	  {
+	    pd->gp = bfd_asymbol_value (info->symtab[i]);
+	    pd->has_gp = true;
+	  }
     }
   else
     pd = info->private_data;
@@ -662,13 +672,13 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
 	  print_insn_args (op->args, word, memaddr, info);
 
 	  /* Try to disassemble multi-instruction addressing sequences.  */
-	  if (pd->print_addr != (bfd_vma)-1)
+	  if (pd->to_print_addr)
 	    {
 	      info->target = pd->print_addr;
 	      (*info->fprintf_styled_func)
 		(info->stream, dis_style_comment_start, " # ");
 	      (*info->print_address_func) (info->target, info);
-	      pd->print_addr = -1;
+	      pd->to_print_addr = false;
 	    }
 
 	  /* Finish filling out insn_info fields.  */
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v7 2/5] RISC-V: Fix RV32 disassembler address computation
  2022-08-24  1:26           ` [PATCH v7 0/5] RISC-V: Fix address printer on the disassembler Tsukasa OI
  2022-08-24  1:26             ` [PATCH v7 1/5] RISC-V: Print highest address on disassembler Tsukasa OI
@ 2022-08-24  1:26             ` Tsukasa OI
  2022-08-24 11:35               ` Nelson Chu
  2022-08-24  1:26             ` [PATCH v7 3/5] RISC-V: Fix JALR target " Tsukasa OI
                               ` (2 subsequent siblings)
  4 siblings, 1 reply; 48+ messages in thread
From: Tsukasa OI @ 2022-08-24  1:26 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Palmer Dabbelt, Andrew Waterman,
	Jim Wilson, Nelson Chu
  Cc: binutils

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 bug (including PR29342) by fitting an address into a 32-bit value
on RV32.

gas/ChangeLog:

	* testsuite/gas/riscv/lla32.d: Reflect RV32 address computation fix.

opcodes/ChangeLog:

	* riscv-dis.c (maybe_print_address): Clarify the role of the `wide'
	argument and rename to `is_addiw'.  Fit the address into 32-bit on
	RV32.  (print_insn_args): Reflect bool type of `is_addiw'.
---
 gas/testsuite/gas/riscv/lla32.d |  2 +-
 opcodes/riscv-dis.c             | 24 ++++++++++++++----------
 2 files changed, 15 insertions(+), 11 deletions(-)

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 c6d80c3ba49..419c4746db9 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -172,7 +172,7 @@ arg_print (struct disassemble_info *info, unsigned long val,
 
 static void
 maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
-		     int wide)
+		     bool is_addiw)
 {
   if (pd->hi_addr[base_reg] != (bfd_vma)-1)
     {
@@ -187,9 +187,13 @@ maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
     return;
   pd->to_print_addr = true;
 
-  /* Sign-extend a 32-bit value to a 64-bit value.  */
-  if (wide)
+  /* On ADDIW, Sign-extend a 32-bit value to a 64-bit value.  */
+  if (is_addiw)
     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.  */
@@ -239,10 +243,10 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	    case 'o':
 	    case 'j':
 	      if (((l & MASK_C_ADDI) == MATCH_C_ADDI) && rd != 0)
-		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), 0);
+		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), false);
 	      if (info->mach == bfd_mach_riscv64
 		  && ((l & MASK_C_ADDIW) == MATCH_C_ADDIW) && rd != 0)
-		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), 1);
+		maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), true);
 	      print (info->stream, dis_style_immediate, "%d",
 		     (int)EXTRACT_CITYPE_IMM (l));
 	      break;
@@ -402,7 +406,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, 0, false);
 	  print (info->stream, dis_style_register, "%s", riscv_gpr_names[rs1]);
 	  break;
 
@@ -432,21 +436,21 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
 	  break;
 
 	case 'o':
-	  maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0);
+	  maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), false);
 	  /* Fall through.  */
 	case 'j':
 	  if (((l & MASK_ADDI) == MATCH_ADDI && rs1 != 0)
 	      || (l & MASK_JALR) == MATCH_JALR)
-	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0);
+	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), false);
 	  if (info->mach == bfd_mach_riscv64
 	      && ((l & MASK_ADDIW) == MATCH_ADDIW) && rs1 != 0)
-	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 1);
+	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), true);
 	  print (info->stream, dis_style_immediate, "%d",
 		 (int)EXTRACT_ITYPE_IMM (l));
 	  break;
 
 	case 'q':
-	  maybe_print_address (pd, rs1, EXTRACT_STYPE_IMM (l), 0);
+	  maybe_print_address (pd, rs1, EXTRACT_STYPE_IMM (l), false);
 	  print (info->stream, dis_style_address_offset, "%d",
 		 (int)EXTRACT_STYPE_IMM (l));
 	  break;
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v7 3/5] RISC-V: Fix JALR target address computation
  2022-08-24  1:26           ` [PATCH v7 0/5] RISC-V: Fix address printer on the disassembler Tsukasa OI
  2022-08-24  1:26             ` [PATCH v7 1/5] RISC-V: Print highest address on disassembler Tsukasa OI
  2022-08-24  1:26             ` [PATCH v7 2/5] RISC-V: Fix RV32 disassembler address computation Tsukasa OI
@ 2022-08-24  1:26             ` Tsukasa OI
  2022-08-24 11:36               ` Nelson Chu
  2022-08-24  1:26             ` [PATCH v7 4/5] RISC-V: Add address printer tests on disassembler Tsukasa OI
  2022-08-24  1:26             ` [PATCH v7 5/5] RISC-V: Add address printer tests with ADDIW Tsukasa OI
  4 siblings, 1 reply; 48+ messages in thread
From: Tsukasa OI @ 2022-08-24  1:26 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Palmer Dabbelt, Andrew Waterman,
	Jim Wilson, Nelson Chu
  Cc: binutils

H. Peter Anvin discovered that we have wrong address computation for JALR
instruction (the initial bug is back in 2018).  This commit will fix that
based on the idea of Palmer Dabbelt.

opcodes/ChangeLog:

	* riscv-dis.c (print_insn_args): Fix JALR address computation.
---
 opcodes/riscv-dis.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
index 419c4746db9..162a2971320 100644
--- a/opcodes/riscv-dis.c
+++ b/opcodes/riscv-dis.c
@@ -406,7 +406,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, false);
+	    maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), false);
 	  print (info->stream, dis_style_register, "%s", riscv_gpr_names[rs1]);
 	  break;
 
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v7 4/5] RISC-V: Add address printer tests on disassembler
  2022-08-24  1:26           ` [PATCH v7 0/5] RISC-V: Fix address printer on the disassembler Tsukasa OI
                               ` (2 preceding siblings ...)
  2022-08-24  1:26             ` [PATCH v7 3/5] RISC-V: Fix JALR target " Tsukasa OI
@ 2022-08-24  1:26             ` Tsukasa OI
  2022-08-24 11:42               ` Nelson Chu
  2022-08-24  1:26             ` [PATCH v7 5/5] RISC-V: Add address printer tests with ADDIW Tsukasa OI
  4 siblings, 1 reply; 48+ messages in thread
From: Tsukasa OI @ 2022-08-24  1:26 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Palmer Dabbelt, Andrew Waterman,
	Jim Wilson, Nelson Chu
  Cc: binutils

This commit adds address printer tests on the disassembler focusing on
various path to/on maybe_print_address.  It also tests whether the address
adjustment on RV32 (fix to PR29342) works as expected, whether the highest
address is printed with a symbol and JALR address computation is fixed.

gas/ChangeLog:

	* testsuite/gas/riscv/dis-addr-1.s: Rename from auipc-x0.s.
	* testsuite/gas/riscv/dis-addr-1.d: Rename from auipc-x0.d.
	* testsuite/gas/riscv/dis-addr-2.s: New address printer tests
	on the disassembler.
	* testsuite/gas/riscv/dis-addr-2-32.d: Likewise.
	* testsuite/gas/riscv/dis-addr-2-64.d: Likewise.
	* testsuite/gas/riscv/dis-addr-3.s: New address printer tests
	on the disassembler if `gp' is the highest address.
	* testsuite/gas/riscv/dis-addr-3-32.d: Likewise.
	* testsuite/gas/riscv/dis-addr-3-64.d: Likewise.
---
 .../gas/riscv/{auipc-x0.d => dis-addr-1.d}    |  0
 .../gas/riscv/{auipc-x0.s => dis-addr-1.s}    |  0
 gas/testsuite/gas/riscv/dis-addr-2-32.d       | 31 ++++++++
 gas/testsuite/gas/riscv/dis-addr-2-64.d       | 35 +++++++++
 gas/testsuite/gas/riscv/dis-addr-2.s          | 74 +++++++++++++++++++
 gas/testsuite/gas/riscv/dis-addr-3-32.d       | 12 +++
 gas/testsuite/gas/riscv/dis-addr-3-64.d       | 12 +++
 gas/testsuite/gas/riscv/dis-addr-3.s          | 15 ++++
 8 files changed, 179 insertions(+)
 rename gas/testsuite/gas/riscv/{auipc-x0.d => dis-addr-1.d} (100%)
 rename gas/testsuite/gas/riscv/{auipc-x0.s => dis-addr-1.s} (100%)
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-2.s
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-32.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-64.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-3.s

diff --git a/gas/testsuite/gas/riscv/auipc-x0.d b/gas/testsuite/gas/riscv/dis-addr-1.d
similarity index 100%
rename from gas/testsuite/gas/riscv/auipc-x0.d
rename to gas/testsuite/gas/riscv/dis-addr-1.d
diff --git a/gas/testsuite/gas/riscv/auipc-x0.s b/gas/testsuite/gas/riscv/dis-addr-1.s
similarity index 100%
rename from gas/testsuite/gas/riscv/auipc-x0.s
rename to gas/testsuite/gas/riscv/dis-addr-1.s
diff --git a/gas/testsuite/gas/riscv/dis-addr-2-32.d b/gas/testsuite/gas/riscv/dis-addr-2-32.d
new file mode 100644
index 00000000000..5117c3d8a0c
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-2-32.d
@@ -0,0 +1,31 @@
+#as: -march=rv32ic
+#source: dis-addr-2.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>
+[ 	]+[0-9a-f]+:[ 	]+fff00f83[ 	]+lb[   	]+t6,-1\(zero\) # ffffffff <addr_top>
diff --git a/gas/testsuite/gas/riscv/dis-addr-2-64.d b/gas/testsuite/gas/riscv/dis-addr-2-64.d
new file mode 100644
index 00000000000..d806bad25b4
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-2-64.d
@@ -0,0 +1,35 @@
+#as: -march=rv64ic -defsym rv64=1
+#source: dis-addr-2.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>
+[ 	]+[0-9a-f]+:[ 	]+fff00f83[ 	]+lb[   	]+t6,-1\(zero\) # ffffffffffffffff <addr_top>
diff --git a/gas/testsuite/gas/riscv/dis-addr-2.s b/gas/testsuite/gas/riscv/dis-addr-2.s
new file mode 100644
index 00000000000..cb7f0cd9dc2
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-2.s
@@ -0,0 +1,74 @@
+.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  # 0x104
+.set addr_jalr_rel_zero_neg, topbase + 0xfffff804  # -0x7fc
+.set addr_top,               topbase + 0xffffffff  # -1
+
+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)
+
+	# Access to the highest address
+	lb	t6, -1(zero)
diff --git a/gas/testsuite/gas/riscv/dis-addr-3-32.d b/gas/testsuite/gas/riscv/dis-addr-3-32.d
new file mode 100644
index 00000000000..42ca89850ac
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-3-32.d
@@ -0,0 +1,12 @@
+#as: -march=rv32i
+#source: dis-addr-3.s
+#objdump: -d
+
+.*:     file format elf32-(little|big)riscv
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+0051a283[ 	]+lw[   	]+t0,5\(gp\) # 4 <addr_rel_gp_pos>
+[ 	]+[0-9a-f]+:[ 	]+ffd1a303[ 	]+lw[   	]+t1,-3\(gp\) # fffffffc <addr_rel_gp_neg>
diff --git a/gas/testsuite/gas/riscv/dis-addr-3-64.d b/gas/testsuite/gas/riscv/dis-addr-3-64.d
new file mode 100644
index 00000000000..394c58fac96
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-3-64.d
@@ -0,0 +1,12 @@
+#as: -march=rv64i -defsym rv64=1
+#source: dis-addr-3.s
+#objdump: -d
+
+.*:     file format elf64-(little|big)riscv
+
+
+Disassembly of section .text:
+
+0+000 <target>:
+[ 	]+[0-9a-f]+:[ 	]+0051a283[ 	]+lw[   	]+t0,5\(gp\) # 4 <addr_rel_gp_pos>
+[ 	]+[0-9a-f]+:[ 	]+ffd1a303[ 	]+lw[   	]+t1,-3\(gp\) # fffffffffffffffc <addr_rel_gp_neg>
diff --git a/gas/testsuite/gas/riscv/dis-addr-3.s b/gas/testsuite/gas/riscv/dis-addr-3.s
new file mode 100644
index 00000000000..6ba9fc7a39d
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-3.s
@@ -0,0 +1,15 @@
+.ifdef rv64
+topbase = 0xffffffff00000000
+.else
+topbase = 0
+.endif
+
+.set __global_pointer$, topbase + 0xffffffff  # -1
+.set addr_rel_gp_pos,             0x00000004  # +4
+.set addr_rel_gp_neg,   topbase + 0xfffffffc  # -4
+
+target:
+	# Use addresses relative to gp
+	# (gp is the highest address)
+	lw	t0, +5(gp)
+	lw	t1, -3(gp)
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* [PATCH v7 5/5] RISC-V: Add address printer tests with ADDIW
  2022-08-24  1:26           ` [PATCH v7 0/5] RISC-V: Fix address printer on the disassembler Tsukasa OI
                               ` (3 preceding siblings ...)
  2022-08-24  1:26             ` [PATCH v7 4/5] RISC-V: Add address printer tests on disassembler Tsukasa OI
@ 2022-08-24  1:26             ` Tsukasa OI
  4 siblings, 0 replies; 48+ messages in thread
From: Tsukasa OI @ 2022-08-24  1:26 UTC (permalink / raw)
  To: Tsukasa OI, H . Peter Anvin, Palmer Dabbelt, Andrew Waterman,
	Jim Wilson, Nelson Chu
  Cc: binutils

Address sequences involving ADDIW/C.ADDIW instructions require special
handling to sign-extend lower 32-bits of the original result.

This commit tests whether this sign-extension works.

gas/ChangeLog:

	* testsuite/gas/riscv/dis-addr-4.s: New to test the address
	computation with sign extension as used in ADDIW/C.ADDIW.
	* testsuite/gas/riscv/dis-addr-4a.d: Test PC sign bit 0.
	* testsuite/gas/riscv/dis-addr-4b.d: Test PC sign bit 1.
---
 gas/testsuite/gas/riscv/dis-addr-4.s  | 28 +++++++++++++++++++++++++++
 gas/testsuite/gas/riscv/dis-addr-4a.d | 18 +++++++++++++++++
 gas/testsuite/gas/riscv/dis-addr-4b.d | 18 +++++++++++++++++
 3 files changed, 64 insertions(+)
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-4.s
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-4a.d
 create mode 100644 gas/testsuite/gas/riscv/dis-addr-4b.d

diff --git a/gas/testsuite/gas/riscv/dis-addr-4.s b/gas/testsuite/gas/riscv/dis-addr-4.s
new file mode 100644
index 00000000000..7c878f86dd6
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-4.s
@@ -0,0 +1,28 @@
+.set addr_rv64_addiw_0a,   0xfffffffffffffff8  # 0xffffffe0 + 0x18 (sext:32->64)
+.set addr_rv64_c_addiw_0a, 0xfffffffffffffffc  # 0xfffffff0 + 0x0c (sext:32->64)
+.set addr_rv64_addiw_0b,           0x00000004  # 0xffffffe8 + 0x1c
+.set addr_rv64_c_addiw_0b,         0x00000008  # 0xfffffff6 + 0x12
+.set addr_rv64_addiw_1a,           0x7ffffff8  # 0x7fffffe0 + 0x18
+.set addr_rv64_c_addiw_1a,         0x7ffffffc  # 0x7ffffff0 + 0x0c
+.set addr_rv64_addiw_1b,   0xffffffff80000004  # 0x7fffffe8 + 0x1c (sext:32->64)
+.set addr_rv64_c_addiw_1b, 0xffffffff80000008  # 0x7ffffff6 + 0x12 (sext:32->64)
+
+	.text
+	.global	_start
+_start:
+	.option	push
+	.option	arch, -c
+	# _start + 0x00
+	auipc	t0, 0
+	addiw	t1, t0, 0x18
+	# _start + 0x08
+	auipc	t2, 0
+	addiw	t3, t2, 0x1c
+
+	.option	pop
+	# _start + 0x10
+	auipc	t4, 0
+	c.addiw	t4, 0x0c
+	# _start + 0x16
+	auipc	t5, 0
+	c.addiw	t5, 0x12
diff --git a/gas/testsuite/gas/riscv/dis-addr-4a.d b/gas/testsuite/gas/riscv/dis-addr-4a.d
new file mode 100644
index 00000000000..91816b9f0d9
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-4a.d
@@ -0,0 +1,18 @@
+#as: -march=rv64ic
+#source: dis-addr-4.s
+#objdump: -d --adjust-vma=0xffffffe0
+
+.*:     file format elf64-(little|big)riscv
+
+
+Disassembly of section .text:
+
+0+ffffffe0 <_start>:
+[ 	]+ffffffe0:[ 	]+00000297[ 	]+auipc[ 	]+t0,0x0
+[ 	]+ffffffe4:[ 	]+0182831b[ 	]+addiw[ 	]+t1,t0,24 # fffffffffffffff8 <addr_rv64_addiw_0a>
+[ 	]+ffffffe8:[ 	]+00000397[ 	]+auipc[ 	]+t2,0x0
+[ 	]+ffffffec:[ 	]+01c38e1b[ 	]+addiw[ 	]+t3,t2,28 # 4 <addr_rv64_addiw_0b>
+[ 	]+fffffff0:[ 	]+00000e97[ 	]+auipc[ 	]+t4,0x0
+[ 	]+fffffff4:[ 	]+2eb1[ 	]+addiw[ 	]+t4,t4,12 # fffffffffffffffc <addr_rv64_c_addiw_0a>
+[ 	]+fffffff6:[ 	]+00000f17[ 	]+auipc[ 	]+t5,0x0
+[ 	]+fffffffa:[ 	]+2f49[ 	]+addiw[ 	]+t5,t5,18 # 8 <addr_rv64_c_addiw_0b>
diff --git a/gas/testsuite/gas/riscv/dis-addr-4b.d b/gas/testsuite/gas/riscv/dis-addr-4b.d
new file mode 100644
index 00000000000..2f78ff59411
--- /dev/null
+++ b/gas/testsuite/gas/riscv/dis-addr-4b.d
@@ -0,0 +1,18 @@
+#as: -march=rv64ic
+#source: dis-addr-4.s
+#objdump: -d --adjust-vma=0x7fffffe0
+
+.*:     file format elf64-(little|big)riscv
+
+
+Disassembly of section .text:
+
+0+7fffffe0 <_start>:
+[ 	]+7fffffe0:[ 	]+00000297[ 	]+auipc[ 	]+t0,0x0
+[ 	]+7fffffe4:[ 	]+0182831b[ 	]+addiw[ 	]+t1,t0,24 # 7ffffff8 <addr_rv64_addiw_1a>
+[ 	]+7fffffe8:[ 	]+00000397[ 	]+auipc[ 	]+t2,0x0
+[ 	]+7fffffec:[ 	]+01c38e1b[ 	]+addiw[ 	]+t3,t2,28 # ffffffff80000004 <addr_rv64_addiw_1b>
+[ 	]+7ffffff0:[ 	]+00000e97[ 	]+auipc[ 	]+t4,0x0
+[ 	]+7ffffff4:[ 	]+2eb1[ 	]+addiw[ 	]+t4,t4,12 # 7ffffffc <addr_rv64_c_addiw_1a>
+[ 	]+7ffffff6:[ 	]+00000f17[ 	]+auipc[ 	]+t5,0x0
+[ 	]+7ffffffa:[ 	]+2f49[ 	]+addiw[ 	]+t5,t5,18 # ffffffff80000008 <addr_rv64_c_addiw_1b>
-- 
2.34.1


^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v7 1/5] RISC-V: Print highest address on disassembler
  2022-08-24  1:26             ` [PATCH v7 1/5] RISC-V: Print highest address on disassembler Tsukasa OI
@ 2022-08-24 11:22               ` Nelson Chu
  2022-08-24 11:22                 ` Nelson Chu
  2022-08-24 12:06                 ` Tsukasa OI
  0 siblings, 2 replies; 48+ messages in thread
From: Nelson Chu @ 2022-08-24 11:22 UTC (permalink / raw)
  To: Tsukasa OI
  Cc: H . Peter Anvin, Palmer Dabbelt, Andrew Waterman, Jim Wilson,
	Nelson Chu, binutils

Hi Tsukasa,

I think there are three dis-assembler issues here,

1. PR29342
2. The target address of jump
3. Should we show the target address when it is -1

Therefore, three separate patches looks reasonable.  But I would suggest
that we should add test cases for each patch as possible as we can, rather
than add them together at last.  That is because it is really hard to make
sure the correctness of the separate patches.

This patch refers to issue 3.  So according to the source code, we won't
show the final target address when pd->print_addr is -1, which means
the address is exactly -1 or it is the default value.  I think it is really
rare to jump or refer to the symbol whose value is -1.  Besides that, not
showing the target address when it's value is -1 doesn't look wrong to me,
so personally I would like to keep the original behavior.  Unless there are
other users who really want to change the behavior, or llvm are doing
something different.  However, the change of gp makes sense, so it looks to
me.

Thanks
Nelson

On Wed, Aug 24, 2022 at 9:28 AM Tsukasa OI via Binutils <
binutils@sourceware.org> wrote:

> This patch makes possible to print the highest address (0xffffffff on RV32,
> 0xffffffff_ffffffff on RV64).  This is particularly useful if the highest
> address space is used for I/O registers and corresponding symbols
> are defined.
>
> opcodes/ChangeLog:
>
>         * riscv-dis.c (struct riscv_private_data): Add `to_print_addr' and
>         `has_gp' to enable printing the highest address.
>         (maybe_print_address): Utilize `to_print_addr' and `has_gp'.
>         (riscv_disassemble_insn): Likewise.
> ---
>  opcodes/riscv-dis.c | 22 ++++++++++++++++------
>  1 file changed, 16 insertions(+), 6 deletions(-)
>
> diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
> index 164fd209dbd..c6d80c3ba49 100644
> --- a/opcodes/riscv-dis.c
> +++ b/opcodes/riscv-dis.c
> @@ -52,6 +52,8 @@ struct riscv_private_data
>    bfd_vma gp;
>    bfd_vma print_addr;
>    bfd_vma hi_addr[OP_MASK_RD + 1];
> +  bool to_print_addr;
> +  bool has_gp;
>  };
>
>  /* Used for mapping symbols.  */
> @@ -177,10 +179,13 @@ maybe_print_address (struct riscv_private_data *pd,
> int base_reg, int offset,
>        pd->print_addr = (base_reg != 0 ? pd->hi_addr[base_reg] : 0) +
> offset;
>        pd->hi_addr[base_reg] = -1;
>      }
> -  else if (base_reg == X_GP && pd->gp != (bfd_vma)-1)
> +  else if (base_reg == X_GP && pd->has_gp)
>      pd->print_addr = pd->gp + offset;
>    else if (base_reg == X_TP || base_reg == 0)
>      pd->print_addr = offset;
> +  else
> +    return;
> +  pd->to_print_addr = true;
>
>    /* Sign-extend a 32-bit value to a 64-bit value.  */
>    if (wide)
> @@ -595,14 +600,19 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t
> word, disassemble_info *info)
>        int i;
>
>        pd = info->private_data = xcalloc (1, sizeof (struct
> riscv_private_data));
> -      pd->gp = -1;
> -      pd->print_addr = -1;
> +      pd->gp = 0;
> +      pd->print_addr = 0;
>        for (i = 0; i < (int)ARRAY_SIZE (pd->hi_addr); i++)
>         pd->hi_addr[i] = -1;
> +      pd->to_print_addr = false;
> +      pd->has_gp = false;
>
>        for (i = 0; i < info->symtab_size; i++)
>         if (strcmp (bfd_asymbol_name (info->symtab[i]), RISCV_GP_SYMBOL)
> == 0)
> -         pd->gp = bfd_asymbol_value (info->symtab[i]);
> +         {
> +           pd->gp = bfd_asymbol_value (info->symtab[i]);
> +           pd->has_gp = true;
> +         }
>      }
>    else
>      pd = info->private_data;
> @@ -662,13 +672,13 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t
> word, disassemble_info *info)
>           print_insn_args (op->args, word, memaddr, info);
>
>           /* Try to disassemble multi-instruction addressing sequences.  */
> -         if (pd->print_addr != (bfd_vma)-1)
> +         if (pd->to_print_addr)
>             {
>               info->target = pd->print_addr;
>               (*info->fprintf_styled_func)
>                 (info->stream, dis_style_comment_start, " # ");
>               (*info->print_address_func) (info->target, info);
> -             pd->print_addr = -1;
> +             pd->to_print_addr = false;
>             }
>
>           /* Finish filling out insn_info fields.  */
> --
> 2.34.1
>
>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v7 1/5] RISC-V: Print highest address on disassembler
  2022-08-24 11:22               ` Nelson Chu
@ 2022-08-24 11:22                 ` Nelson Chu
  2022-08-24 12:06                 ` Tsukasa OI
  1 sibling, 0 replies; 48+ messages in thread
From: Nelson Chu @ 2022-08-24 11:22 UTC (permalink / raw)
  To: Tsukasa OI
  Cc: H . Peter Anvin, Palmer Dabbelt, Andrew Waterman, Jim Wilson,
	Nelson Chu, binutils

[-- Attachment #1: Type: text/plain, Size: 4278 bytes --]

Hi Tsukasa,

I think there are three dis-assembler issues here,

1. PR29342
2. The target address of jump
3. Should we show the target address when it is -1

Therefore, three separate patches looks reasonable.  But I would suggest
that we should add test cases for each patch as possible as we can, rather
than add them together at last.  That is because it is really hard to make
sure the correctness of the separate patches.

This patch refers to issue 3.  So according to the source code, we won't
show the final target address when pd->print_addr is -1, which means
the address is exactly -1 or it is the default value.  I think it is really
rare to jump or refer to the symbol whose value is -1.  Besides that, not
showing the target address when it's value is -1 doesn't look wrong to me,
so personally I would like to keep the original behavior.  Unless there are
other users who really want to change the behavior, or llvm are doing
something different.  However, the change of gp makes sense, so it looks to
me.

Thanks
Nelson

On Wed, Aug 24, 2022 at 9:28 AM Tsukasa OI via Binutils <
binutils@sourceware.org> wrote:

> This patch makes possible to print the highest address (0xffffffff on RV32,
> 0xffffffff_ffffffff on RV64).  This is particularly useful if the highest
> address space is used for I/O registers and corresponding symbols
> are defined.
>
> opcodes/ChangeLog:
>
>         * riscv-dis.c (struct riscv_private_data): Add `to_print_addr' and
>         `has_gp' to enable printing the highest address.
>         (maybe_print_address): Utilize `to_print_addr' and `has_gp'.
>         (riscv_disassemble_insn): Likewise.
> ---
>  opcodes/riscv-dis.c | 22 ++++++++++++++++------
>  1 file changed, 16 insertions(+), 6 deletions(-)
>
> diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
> index 164fd209dbd..c6d80c3ba49 100644
> --- a/opcodes/riscv-dis.c
> +++ b/opcodes/riscv-dis.c
> @@ -52,6 +52,8 @@ struct riscv_private_data
>    bfd_vma gp;
>    bfd_vma print_addr;
>    bfd_vma hi_addr[OP_MASK_RD + 1];
> +  bool to_print_addr;
> +  bool has_gp;
>  };
>
>  /* Used for mapping symbols.  */
> @@ -177,10 +179,13 @@ maybe_print_address (struct riscv_private_data *pd,
> int base_reg, int offset,
>        pd->print_addr = (base_reg != 0 ? pd->hi_addr[base_reg] : 0) +
> offset;
>        pd->hi_addr[base_reg] = -1;
>      }
> -  else if (base_reg == X_GP && pd->gp != (bfd_vma)-1)
> +  else if (base_reg == X_GP && pd->has_gp)
>      pd->print_addr = pd->gp + offset;
>    else if (base_reg == X_TP || base_reg == 0)
>      pd->print_addr = offset;
> +  else
> +    return;
> +  pd->to_print_addr = true;
>
>    /* Sign-extend a 32-bit value to a 64-bit value.  */
>    if (wide)
> @@ -595,14 +600,19 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t
> word, disassemble_info *info)
>        int i;
>
>        pd = info->private_data = xcalloc (1, sizeof (struct
> riscv_private_data));
> -      pd->gp = -1;
> -      pd->print_addr = -1;
> +      pd->gp = 0;
> +      pd->print_addr = 0;
>        for (i = 0; i < (int)ARRAY_SIZE (pd->hi_addr); i++)
>         pd->hi_addr[i] = -1;
> +      pd->to_print_addr = false;
> +      pd->has_gp = false;
>
>        for (i = 0; i < info->symtab_size; i++)
>         if (strcmp (bfd_asymbol_name (info->symtab[i]), RISCV_GP_SYMBOL)
> == 0)
> -         pd->gp = bfd_asymbol_value (info->symtab[i]);
> +         {
> +           pd->gp = bfd_asymbol_value (info->symtab[i]);
> +           pd->has_gp = true;
> +         }
>      }
>    else
>      pd = info->private_data;
> @@ -662,13 +672,13 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t
> word, disassemble_info *info)
>           print_insn_args (op->args, word, memaddr, info);
>
>           /* Try to disassemble multi-instruction addressing sequences.  */
> -         if (pd->print_addr != (bfd_vma)-1)
> +         if (pd->to_print_addr)
>             {
>               info->target = pd->print_addr;
>               (*info->fprintf_styled_func)
>                 (info->stream, dis_style_comment_start, " # ");
>               (*info->print_address_func) (info->target, info);
> -             pd->print_addr = -1;
> +             pd->to_print_addr = false;
>             }
>
>           /* Finish filling out insn_info fields.  */
> --
> 2.34.1
>
>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v7 2/5] RISC-V: Fix RV32 disassembler address computation
  2022-08-24  1:26             ` [PATCH v7 2/5] RISC-V: Fix RV32 disassembler address computation Tsukasa OI
@ 2022-08-24 11:35               ` Nelson Chu
  0 siblings, 0 replies; 48+ messages in thread
From: Nelson Chu @ 2022-08-24 11:35 UTC (permalink / raw)
  To: Tsukasa OI
  Cc: H . Peter Anvin, Palmer Dabbelt, Andrew Waterman, Jim Wilson,
	Nelson Chu, binutils

On Wed, Aug 24, 2022 at 9:28 AM Tsukasa OI via Binutils
<binutils@sourceware.org> wrote:
>
> 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 bug (including PR29342) by fitting an address into a 32-bit value
> on RV32.
>
> gas/ChangeLog:
>
>         * testsuite/gas/riscv/lla32.d: Reflect RV32 address computation fix.
>
> opcodes/ChangeLog:
>
>         * riscv-dis.c (maybe_print_address): Clarify the role of the `wide'
>         argument and rename to `is_addiw'.  Fit the address into 32-bit on
>         RV32.  (print_insn_args): Reflect bool type of `is_addiw'.

Probably no need to change this.

> ---
>  gas/testsuite/gas/riscv/lla32.d |  2 +-
>  opcodes/riscv-dis.c             | 24 ++++++++++++++----------
>  2 files changed, 15 insertions(+), 11 deletions(-)
>
> 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 c6d80c3ba49..419c4746db9 100644
> --- a/opcodes/riscv-dis.c
> +++ b/opcodes/riscv-dis.c
> @@ -172,7 +172,7 @@ arg_print (struct disassemble_info *info, unsigned long val,
>
>  static void
>  maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
> -                    int wide)
> +                    bool is_addiw)
>  {
>    if (pd->hi_addr[base_reg] != (bfd_vma)-1)
>      {
> @@ -187,9 +187,13 @@ maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
>      return;
>    pd->to_print_addr = true;
>
> -  /* Sign-extend a 32-bit value to a 64-bit value.  */
> -  if (wide)
> +  /* On ADDIW, Sign-extend a 32-bit value to a 64-bit value.  */
> +  if (is_addiw)
>      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;

These three lines should resolve PR29342, so it looks good to me.

>  }
>
>  /* Print insn arguments for 32/64-bit code.  */
> @@ -239,10 +243,10 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
>             case 'o':
>             case 'j':
>               if (((l & MASK_C_ADDI) == MATCH_C_ADDI) && rd != 0)
> -               maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), 0);
> +               maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), false);
>               if (info->mach == bfd_mach_riscv64
>                   && ((l & MASK_C_ADDIW) == MATCH_C_ADDIW) && rd != 0)
> -               maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), 1);
> +               maybe_print_address (pd, rd, EXTRACT_CITYPE_IMM (l), true);
>               print (info->stream, dis_style_immediate, "%d",
>                      (int)EXTRACT_CITYPE_IMM (l));
>               break;
> @@ -402,7 +406,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, 0, false);
>           print (info->stream, dis_style_register, "%s", riscv_gpr_names[rs1]);
>           break;
>
> @@ -432,21 +436,21 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
>           break;
>
>         case 'o':
> -         maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0);
> +         maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), false);
>           /* Fall through.  */
>         case 'j':
>           if (((l & MASK_ADDI) == MATCH_ADDI && rs1 != 0)
>               || (l & MASK_JALR) == MATCH_JALR)
> -           maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0);
> +           maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), false);
>           if (info->mach == bfd_mach_riscv64
>               && ((l & MASK_ADDIW) == MATCH_ADDIW) && rs1 != 0)
> -           maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 1);
> +           maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), true);
>           print (info->stream, dis_style_immediate, "%d",
>                  (int)EXTRACT_ITYPE_IMM (l));
>           break;
>
>         case 'q':
> -         maybe_print_address (pd, rs1, EXTRACT_STYPE_IMM (l), 0);
> +         maybe_print_address (pd, rs1, EXTRACT_STYPE_IMM (l), false);
>           print (info->stream, dis_style_address_offset, "%d",
>                  (int)EXTRACT_STYPE_IMM (l));
>           break;
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v7 3/5] RISC-V: Fix JALR target address computation
  2022-08-24  1:26             ` [PATCH v7 3/5] RISC-V: Fix JALR target " Tsukasa OI
@ 2022-08-24 11:36               ` Nelson Chu
  0 siblings, 0 replies; 48+ messages in thread
From: Nelson Chu @ 2022-08-24 11:36 UTC (permalink / raw)
  To: Tsukasa OI
  Cc: H . Peter Anvin, Palmer Dabbelt, Andrew Waterman, Jim Wilson,
	Nelson Chu, binutils

On Wed, Aug 24, 2022 at 9:28 AM Tsukasa OI via Binutils
<binutils@sourceware.org> wrote:
>
> H. Peter Anvin discovered that we have wrong address computation for JALR
> instruction (the initial bug is back in 2018).  This commit will fix that
> based on the idea of Palmer Dabbelt.
>
> opcodes/ChangeLog:
>
>         * riscv-dis.c (print_insn_args): Fix JALR address computation.
> ---
>  opcodes/riscv-dis.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
> index 419c4746db9..162a2971320 100644
> --- a/opcodes/riscv-dis.c
> +++ b/opcodes/riscv-dis.c
> @@ -406,7 +406,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, false);
> +           maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), false);

OK, should move the related test cases in this patch.

>           print (info->stream, dis_style_register, "%s", riscv_gpr_names[rs1]);
>           break;
>
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v7 4/5] RISC-V: Add address printer tests on disassembler
  2022-08-24  1:26             ` [PATCH v7 4/5] RISC-V: Add address printer tests on disassembler Tsukasa OI
@ 2022-08-24 11:42               ` Nelson Chu
  0 siblings, 0 replies; 48+ messages in thread
From: Nelson Chu @ 2022-08-24 11:42 UTC (permalink / raw)
  To: Tsukasa OI
  Cc: H . Peter Anvin, Palmer Dabbelt, Andrew Waterman, Jim Wilson,
	Nelson Chu, binutils

On Wed, Aug 24, 2022 at 9:29 AM Tsukasa OI via Binutils
<binutils@sourceware.org> wrote:
>
> This commit adds address printer tests on the disassembler focusing on
> various path to/on maybe_print_address.  It also tests whether the address
> adjustment on RV32 (fix to PR29342) works as expected, whether the highest
> address is printed with a symbol and JALR address computation is fixed.
>
> gas/ChangeLog:
>
>         * testsuite/gas/riscv/dis-addr-1.s: Rename from auipc-x0.s.
>         * testsuite/gas/riscv/dis-addr-1.d: Rename from auipc-x0.d.

I think the test case is for another purpose, it is not only for the
PR29342, so just keep it as before.

>         * testsuite/gas/riscv/dis-addr-2.s: New address printer tests
>         on the disassembler.
>         * testsuite/gas/riscv/dis-addr-2-32.d: Likewise.
>         * testsuite/gas/riscv/dis-addr-2-64.d: Likewise.
>         * testsuite/gas/riscv/dis-addr-3.s: New address printer tests
>         on the disassembler if `gp' is the highest address.
>         * testsuite/gas/riscv/dis-addr-3-32.d: Likewise.
>         * testsuite/gas/riscv/dis-addr-3-64.d: Likewise.

OK, looks good.  Just moving them to the corresponding patches should be enough.

> ---
>  .../gas/riscv/{auipc-x0.d => dis-addr-1.d}    |  0
>  .../gas/riscv/{auipc-x0.s => dis-addr-1.s}    |  0
>  gas/testsuite/gas/riscv/dis-addr-2-32.d       | 31 ++++++++
>  gas/testsuite/gas/riscv/dis-addr-2-64.d       | 35 +++++++++
>  gas/testsuite/gas/riscv/dis-addr-2.s          | 74 +++++++++++++++++++
>  gas/testsuite/gas/riscv/dis-addr-3-32.d       | 12 +++
>  gas/testsuite/gas/riscv/dis-addr-3-64.d       | 12 +++
>  gas/testsuite/gas/riscv/dis-addr-3.s          | 15 ++++
>  8 files changed, 179 insertions(+)
>  rename gas/testsuite/gas/riscv/{auipc-x0.d => dis-addr-1.d} (100%)
>  rename gas/testsuite/gas/riscv/{auipc-x0.s => dis-addr-1.s} (100%)
>  create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-32.d
>  create mode 100644 gas/testsuite/gas/riscv/dis-addr-2-64.d
>  create mode 100644 gas/testsuite/gas/riscv/dis-addr-2.s
>  create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-32.d
>  create mode 100644 gas/testsuite/gas/riscv/dis-addr-3-64.d
>  create mode 100644 gas/testsuite/gas/riscv/dis-addr-3.s
>
> diff --git a/gas/testsuite/gas/riscv/auipc-x0.d b/gas/testsuite/gas/riscv/dis-addr-1.d
> similarity index 100%
> rename from gas/testsuite/gas/riscv/auipc-x0.d
> rename to gas/testsuite/gas/riscv/dis-addr-1.d
> diff --git a/gas/testsuite/gas/riscv/auipc-x0.s b/gas/testsuite/gas/riscv/dis-addr-1.s
> similarity index 100%
> rename from gas/testsuite/gas/riscv/auipc-x0.s
> rename to gas/testsuite/gas/riscv/dis-addr-1.s
> diff --git a/gas/testsuite/gas/riscv/dis-addr-2-32.d b/gas/testsuite/gas/riscv/dis-addr-2-32.d
> new file mode 100644
> index 00000000000..5117c3d8a0c
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/dis-addr-2-32.d
> @@ -0,0 +1,31 @@
> +#as: -march=rv32ic
> +#source: dis-addr-2.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>
> +[      ]+[0-9a-f]+:[   ]+fff00f83[     ]+lb[           ]+t6,-1\(zero\) # ffffffff <addr_top>
> diff --git a/gas/testsuite/gas/riscv/dis-addr-2-64.d b/gas/testsuite/gas/riscv/dis-addr-2-64.d
> new file mode 100644
> index 00000000000..d806bad25b4
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/dis-addr-2-64.d
> @@ -0,0 +1,35 @@
> +#as: -march=rv64ic -defsym rv64=1
> +#source: dis-addr-2.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>
> +[      ]+[0-9a-f]+:[   ]+fff00f83[     ]+lb[           ]+t6,-1\(zero\) # ffffffffffffffff <addr_top>
> diff --git a/gas/testsuite/gas/riscv/dis-addr-2.s b/gas/testsuite/gas/riscv/dis-addr-2.s
> new file mode 100644
> index 00000000000..cb7f0cd9dc2
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/dis-addr-2.s
> @@ -0,0 +1,74 @@
> +.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  # 0x104
> +.set addr_jalr_rel_zero_neg, topbase + 0xfffff804  # -0x7fc
> +.set addr_top,               topbase + 0xffffffff  # -1
> +
> +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)
> +
> +       # Access to the highest address
> +       lb      t6, -1(zero)
> diff --git a/gas/testsuite/gas/riscv/dis-addr-3-32.d b/gas/testsuite/gas/riscv/dis-addr-3-32.d
> new file mode 100644
> index 00000000000..42ca89850ac
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/dis-addr-3-32.d
> @@ -0,0 +1,12 @@
> +#as: -march=rv32i
> +#source: dis-addr-3.s
> +#objdump: -d
> +
> +.*:     file format elf32-(little|big)riscv
> +
> +
> +Disassembly of section .text:
> +
> +0+000 <target>:
> +[      ]+[0-9a-f]+:[   ]+0051a283[     ]+lw[           ]+t0,5\(gp\) # 4 <addr_rel_gp_pos>
> +[      ]+[0-9a-f]+:[   ]+ffd1a303[     ]+lw[           ]+t1,-3\(gp\) # fffffffc <addr_rel_gp_neg>
> diff --git a/gas/testsuite/gas/riscv/dis-addr-3-64.d b/gas/testsuite/gas/riscv/dis-addr-3-64.d
> new file mode 100644
> index 00000000000..394c58fac96
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/dis-addr-3-64.d
> @@ -0,0 +1,12 @@
> +#as: -march=rv64i -defsym rv64=1
> +#source: dis-addr-3.s
> +#objdump: -d
> +
> +.*:     file format elf64-(little|big)riscv
> +
> +
> +Disassembly of section .text:
> +
> +0+000 <target>:
> +[      ]+[0-9a-f]+:[   ]+0051a283[     ]+lw[           ]+t0,5\(gp\) # 4 <addr_rel_gp_pos>
> +[      ]+[0-9a-f]+:[   ]+ffd1a303[     ]+lw[           ]+t1,-3\(gp\) # fffffffffffffffc <addr_rel_gp_neg>
> diff --git a/gas/testsuite/gas/riscv/dis-addr-3.s b/gas/testsuite/gas/riscv/dis-addr-3.s
> new file mode 100644
> index 00000000000..6ba9fc7a39d
> --- /dev/null
> +++ b/gas/testsuite/gas/riscv/dis-addr-3.s
> @@ -0,0 +1,15 @@
> +.ifdef rv64
> +topbase = 0xffffffff00000000
> +.else
> +topbase = 0
> +.endif
> +
> +.set __global_pointer$, topbase + 0xffffffff  # -1
> +.set addr_rel_gp_pos,             0x00000004  # +4
> +.set addr_rel_gp_neg,   topbase + 0xfffffffc  # -4
> +
> +target:
> +       # Use addresses relative to gp
> +       # (gp is the highest address)
> +       lw      t0, +5(gp)
> +       lw      t1, -3(gp)
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v7 1/5] RISC-V: Print highest address on disassembler
  2022-08-24 11:22               ` Nelson Chu
  2022-08-24 11:22                 ` Nelson Chu
@ 2022-08-24 12:06                 ` Tsukasa OI
  2022-08-25  5:07                   ` Nelson Chu
  1 sibling, 1 reply; 48+ messages in thread
From: Tsukasa OI @ 2022-08-24 12:06 UTC (permalink / raw)
  To: Nelson Chu; +Cc: binutils

Hi Nelson, good to hear you again.
I see why you were so busy.

On 2022/08/24 20:22, Nelson Chu wrote:
> Hi Tsukasa,
> 
> I think there are three dis-assembler issues here,
> 
> 1. PR29342
> 2. The target address of jump
> 3. Should we show the target address when it is -1
> 
> Therefore, three separate patches looks reasonable.  But I would suggest
> that we should add test cases for each patch as possible as we can,
> rather than add them together at last.  That is because it is really
> hard to make sure the correctness of the separate patches.

I apologize about that.  I am making a series of patches to make the
disassembler faster and more reliable and... I have following branch
graph.  And... that's the only a part of it (that requires
riscv-dis-fix-addr).  Aside from the following branches, I have...
eleven... branches that can be directly applied to master.

1. riscv-dis-fix-addr (This patchset)
  2. riscv-dis-opts-batch-1
     (Roughly 25% performance improvements [more general])
    3. riscv-dis-rv32e (disassembler support for RV32E)
    4. riscv-dis-data-large (highly debatable: .long dumping on RV64)
    5. riscv-dis-generics (fix disassembling some zext.h/pack/packw)
    6. riscv-dis-arch-priv-spec
       (sometimes "real" arch and priv doesn't match with ELF attrs
        [e.g. OpenSBI] and JTAG-based debugging may require ability to
        override some disassembler parameters on the fly)
  7. riscv-dis-opts-batch-2
     (Not general as batch 1 but very effective on libraries; I observed
      nearly 10x improvements on disassembling libcrypto.so)
    8. riscv-dis-reduce-fp-on-addresses
       (reduce false positives on address printing)

Yes, clearly I was impatient.  Not splitting up the problem and
effectively forcing all or nothing to you is a rude behavior and I
sincerely apologize about that.

So, let me split this patchset based on your comments.

> 
> This patch refers to issue 3.  So according to the source code, we won't
> show the final target address when pd->print_addr is -1, which means
> the address is exactly -1 or it is the default value.  I think it is
> really rare to jump or refer to the symbol whose value is -1.  Besides
> that, not showing the target address when it's value is -1 doesn't look
> wrong to me, so personally I would like to keep the original behavior. 

Still I think... if we have a chance to "fix" this (without any
significant performance penalty), why not?  So I stick to my original
opinion (except I will split this change into a separate patchset for
separate review).

Thanks,
Tsukasa

> Unless there are other users who really want to change the behavior, or
> llvm are doing something different.  However, the change of gp makes
> sense, so it looks to me.
> 
> Thanks
> Nelson
> 
> On Wed, Aug 24, 2022 at 9:28 AM Tsukasa OI via Binutils
> <binutils@sourceware.org <mailto:binutils@sourceware.org>> wrote:
> 
>     This patch makes possible to print the highest address (0xffffffff
>     on RV32,
>     0xffffffff_ffffffff on RV64).  This is particularly useful if the
>     highest
>     address space is used for I/O registers and corresponding symbols
>     are defined.
> 
>     opcodes/ChangeLog:
> 
>             * riscv-dis.c (struct riscv_private_data): Add
>     `to_print_addr' and
>             `has_gp' to enable printing the highest address.
>             (maybe_print_address): Utilize `to_print_addr' and `has_gp'.
>             (riscv_disassemble_insn): Likewise.
>     ---
>      opcodes/riscv-dis.c | 22 ++++++++++++++++------
>      1 file changed, 16 insertions(+), 6 deletions(-)
> 
>     diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
>     index 164fd209dbd..c6d80c3ba49 100644
>     --- a/opcodes/riscv-dis.c
>     +++ b/opcodes/riscv-dis.c
>     @@ -52,6 +52,8 @@ struct riscv_private_data
>        bfd_vma gp;
>        bfd_vma print_addr;
>        bfd_vma hi_addr[OP_MASK_RD + 1];
>     +  bool to_print_addr;
>     +  bool has_gp;
>      };
> 
>      /* Used for mapping symbols.  */
>     @@ -177,10 +179,13 @@ maybe_print_address (struct riscv_private_data
>     *pd, int base_reg, int offset,
>            pd->print_addr = (base_reg != 0 ? pd->hi_addr[base_reg] : 0)
>     + offset;
>            pd->hi_addr[base_reg] = -1;
>          }
>     -  else if (base_reg == X_GP && pd->gp != (bfd_vma)-1)
>     +  else if (base_reg == X_GP && pd->has_gp)
>          pd->print_addr = pd->gp + offset;
>        else if (base_reg == X_TP || base_reg == 0)
>          pd->print_addr = offset;
>     +  else
>     +    return;
>     +  pd->to_print_addr = true;
> 
>        /* Sign-extend a 32-bit value to a 64-bit value.  */
>        if (wide)
>     @@ -595,14 +600,19 @@ riscv_disassemble_insn (bfd_vma memaddr,
>     insn_t word, disassemble_info *info)
>            int i;
> 
>            pd = info->private_data = xcalloc (1, sizeof (struct
>     riscv_private_data));
>     -      pd->gp = -1;
>     -      pd->print_addr = -1;
>     +      pd->gp = 0;
>     +      pd->print_addr = 0;
>            for (i = 0; i < (int)ARRAY_SIZE (pd->hi_addr); i++)
>             pd->hi_addr[i] = -1;
>     +      pd->to_print_addr = false;
>     +      pd->has_gp = false;
> 
>            for (i = 0; i < info->symtab_size; i++)
>             if (strcmp (bfd_asymbol_name (info->symtab[i]),
>     RISCV_GP_SYMBOL) == 0)
>     -         pd->gp = bfd_asymbol_value (info->symtab[i]);
>     +         {
>     +           pd->gp = bfd_asymbol_value (info->symtab[i]);
>     +           pd->has_gp = true;
>     +         }
>          }
>        else
>          pd = info->private_data;
>     @@ -662,13 +672,13 @@ riscv_disassemble_insn (bfd_vma memaddr,
>     insn_t word, disassemble_info *info)
>               print_insn_args (op->args, word, memaddr, info);
> 
>               /* Try to disassemble multi-instruction addressing
>     sequences.  */
>     -         if (pd->print_addr != (bfd_vma)-1)
>     +         if (pd->to_print_addr)
>                 {
>                   info->target = pd->print_addr;
>                   (*info->fprintf_styled_func)
>                     (info->stream, dis_style_comment_start, " # ");
>                   (*info->print_address_func) (info->target, info);
>     -             pd->print_addr = -1;
>     +             pd->to_print_addr = false;
>                 }
> 
>               /* Finish filling out insn_info fields.  */
>     -- 
>     2.34.1
> 

^ permalink raw reply	[flat|nested] 48+ messages in thread

* Re: [PATCH v7 1/5] RISC-V: Print highest address on disassembler
  2022-08-24 12:06                 ` Tsukasa OI
@ 2022-08-25  5:07                   ` Nelson Chu
  0 siblings, 0 replies; 48+ messages in thread
From: Nelson Chu @ 2022-08-25  5:07 UTC (permalink / raw)
  To: Tsukasa OI; +Cc: binutils

On Wed, Aug 24, 2022 at 8:06 PM Tsukasa OI <research_trasio@irq.a4lg.com> wrote:
>
> Hi Nelson, good to hear you again.
> I see why you were so busy.
>
> On 2022/08/24 20:22, Nelson Chu wrote:
> > Hi Tsukasa,
> >
> > I think there are three dis-assembler issues here,
> >
> > 1. PR29342
> > 2. The target address of jump
> > 3. Should we show the target address when it is -1
> >
> > Therefore, three separate patches looks reasonable.  But I would suggest
> > that we should add test cases for each patch as possible as we can,
> > rather than add them together at last.  That is because it is really
> > hard to make sure the correctness of the separate patches.
>
> I apologize about that.  I am making a series of patches to make the
> disassembler faster and more reliable and... I have following branch
> graph.  And... that's the only a part of it (that requires
> riscv-dis-fix-addr).  Aside from the following branches, I have...
> eleven... branches that can be directly applied to master.
>
> 1. riscv-dis-fix-addr (This patchset)
>   2. riscv-dis-opts-batch-1
>      (Roughly 25% performance improvements [more general])
>     3. riscv-dis-rv32e (disassembler support for RV32E)
>     4. riscv-dis-data-large (highly debatable: .long dumping on RV64)
>     5. riscv-dis-generics (fix disassembling some zext.h/pack/packw)
>     6. riscv-dis-arch-priv-spec
>        (sometimes "real" arch and priv doesn't match with ELF attrs
>         [e.g. OpenSBI] and JTAG-based debugging may require ability to
>         override some disassembler parameters on the fly)
>   7. riscv-dis-opts-batch-2
>      (Not general as batch 1 but very effective on libraries; I observed
>       nearly 10x improvements on disassembling libcrypto.so)
>     8. riscv-dis-reduce-fp-on-addresses
>        (reduce false positives on address printing)
>
> Yes, clearly I was impatient.  Not splitting up the problem and
> effectively forcing all or nothing to you is a rude behavior and I
> sincerely apologize about that.
>
> So, let me split this patchset based on your comments.

Thanks for doing this, it will make the review easier and also make
sure the correctness of each patch.

> >
> > This patch refers to issue 3.  So according to the source code, we won't
> > show the final target address when pd->print_addr is -1, which means
> > the address is exactly -1 or it is the default value.  I think it is
> > really rare to jump or refer to the symbol whose value is -1.  Besides
> > that, not showing the target address when it's value is -1 doesn't look
> > wrong to me, so personally I would like to keep the original behavior.
>
> Still I think... if we have a chance to "fix" this (without any
> significant performance penalty), why not?  So I stick to my original
> opinion (except I will split this change into a separate patchset for
> separate review).

OK, I just prefer not to change the behavior if it isn't really a
serious bug, in case other project's test cases or some analysis tools
may broken, since we are changing the dis-assembler results.  But
yeah, -1 may still be used as address, even if it is corner used.
Anyway, I'm okay for this change for now, if there are no objections
in a while. I think we just add these changes to the NEWS, then people
will know it's time to update their test cases or tools.

Thanks
Nelson

> Thanks,
> Tsukasa
>
> > Unless there are other users who really want to change the behavior, or
> > llvm are doing something different.  However, the change of gp makes
> > sense, so it looks to me.
> >
> > Thanks
> > Nelson
> >
> > On Wed, Aug 24, 2022 at 9:28 AM Tsukasa OI via Binutils
> > <binutils@sourceware.org <mailto:binutils@sourceware.org>> wrote:
> >
> >     This patch makes possible to print the highest address (0xffffffff
> >     on RV32,
> >     0xffffffff_ffffffff on RV64).  This is particularly useful if the
> >     highest
> >     address space is used for I/O registers and corresponding symbols
> >     are defined.
> >
> >     opcodes/ChangeLog:
> >
> >             * riscv-dis.c (struct riscv_private_data): Add
> >     `to_print_addr' and
> >             `has_gp' to enable printing the highest address.
> >             (maybe_print_address): Utilize `to_print_addr' and `has_gp'.
> >             (riscv_disassemble_insn): Likewise.
> >     ---
> >      opcodes/riscv-dis.c | 22 ++++++++++++++++------
> >      1 file changed, 16 insertions(+), 6 deletions(-)
> >
> >     diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c
> >     index 164fd209dbd..c6d80c3ba49 100644
> >     --- a/opcodes/riscv-dis.c
> >     +++ b/opcodes/riscv-dis.c
> >     @@ -52,6 +52,8 @@ struct riscv_private_data
> >        bfd_vma gp;
> >        bfd_vma print_addr;
> >        bfd_vma hi_addr[OP_MASK_RD + 1];
> >     +  bool to_print_addr;
> >     +  bool has_gp;
> >      };
> >
> >      /* Used for mapping symbols.  */
> >     @@ -177,10 +179,13 @@ maybe_print_address (struct riscv_private_data
> >     *pd, int base_reg, int offset,
> >            pd->print_addr = (base_reg != 0 ? pd->hi_addr[base_reg] : 0)
> >     + offset;
> >            pd->hi_addr[base_reg] = -1;
> >          }
> >     -  else if (base_reg == X_GP && pd->gp != (bfd_vma)-1)
> >     +  else if (base_reg == X_GP && pd->has_gp)
> >          pd->print_addr = pd->gp + offset;
> >        else if (base_reg == X_TP || base_reg == 0)
> >          pd->print_addr = offset;
> >     +  else
> >     +    return;
> >     +  pd->to_print_addr = true;
> >
> >        /* Sign-extend a 32-bit value to a 64-bit value.  */
> >        if (wide)
> >     @@ -595,14 +600,19 @@ riscv_disassemble_insn (bfd_vma memaddr,
> >     insn_t word, disassemble_info *info)
> >            int i;
> >
> >            pd = info->private_data = xcalloc (1, sizeof (struct
> >     riscv_private_data));
> >     -      pd->gp = -1;
> >     -      pd->print_addr = -1;
> >     +      pd->gp = 0;
> >     +      pd->print_addr = 0;
> >            for (i = 0; i < (int)ARRAY_SIZE (pd->hi_addr); i++)
> >             pd->hi_addr[i] = -1;
> >     +      pd->to_print_addr = false;
> >     +      pd->has_gp = false;
> >
> >            for (i = 0; i < info->symtab_size; i++)
> >             if (strcmp (bfd_asymbol_name (info->symtab[i]),
> >     RISCV_GP_SYMBOL) == 0)
> >     -         pd->gp = bfd_asymbol_value (info->symtab[i]);
> >     +         {
> >     +           pd->gp = bfd_asymbol_value (info->symtab[i]);
> >     +           pd->has_gp = true;
> >     +         }
> >          }
> >        else
> >          pd = info->private_data;
> >     @@ -662,13 +672,13 @@ riscv_disassemble_insn (bfd_vma memaddr,
> >     insn_t word, disassemble_info *info)
> >               print_insn_args (op->args, word, memaddr, info);
> >
> >               /* Try to disassemble multi-instruction addressing
> >     sequences.  */
> >     -         if (pd->print_addr != (bfd_vma)-1)
> >     +         if (pd->to_print_addr)
> >                 {
> >                   info->target = pd->print_addr;
> >                   (*info->fprintf_styled_func)
> >                     (info->stream, dis_style_comment_start, " # ");
> >                   (*info->print_address_func) (info->target, info);
> >     -             pd->print_addr = -1;
> >     +             pd->to_print_addr = false;
> >                 }
> >
> >               /* Finish filling out insn_info fields.  */
> >     --
> >     2.34.1
> >

^ permalink raw reply	[flat|nested] 48+ messages in thread

end of thread, other threads:[~2022-08-25  5:07 UTC | newest]

Thread overview: 48+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-29 13:10 [PATCH 0/3] RISC-V: Fix address printer on the disassembler Tsukasa OI
2022-07-29 13:10 ` [PATCH 1/3] RISC-V: Print highest address on disassembler Tsukasa OI
2022-07-29 13:10 ` [PATCH 2/3] RISC-V: Fix RV32 disassembler address computation Tsukasa OI
2022-07-29 13:10 ` [PATCH 3/3] RISC-V: Add address printer tests on disassembler Tsukasa OI
2022-08-02  5:54 ` [PATCH v2 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
2022-08-02  5:54   ` [PATCH v2 1/4] RISC-V: Print highest address on disassembler Tsukasa OI
2022-08-02  5:54   ` [PATCH v2 2/4] RISC-V: Fix RV32 disassembler address computation Tsukasa OI
2022-08-02  5:54   ` [PATCH v2 3/4] RISC-V: Break early if RISCV_GP_SYMBOL is found Tsukasa OI
2022-08-02  5:54   ` [PATCH v2 4/4] RISC-V: Add address printer tests on disassembler Tsukasa OI
2022-08-04  4:35   ` [PATCH v3 0/3] RISC-V: Fix address printer on the disassembler Tsukasa OI
2022-08-04  4:35     ` [PATCH v3 1/3] RISC-V: Print highest address on disassembler Tsukasa OI
2022-08-04  4:35     ` [PATCH v3 2/3] RISC-V: Fix RV32 disassembler address computation Tsukasa OI
2022-08-04  4:35     ` [PATCH v3 3/3] RISC-V: Add address printer tests on disassembler Tsukasa OI
2022-08-08 18:31     ` [PATCH v3 0/3] RISC-V: Fix address printer on the disassembler H. Peter Anvin
2022-08-08 19:46       ` Palmer Dabbelt
2022-08-09  3:39     ` [PATCH v3 0/4] " Tsukasa OI
2022-08-09  3:39       ` [PATCH v3 1/4] RISC-V: Print highest address on disassembler Tsukasa OI
2022-08-09  3:39       ` [PATCH v3 2/4] RISC-V: Fix RV32 disassembler address computation Tsukasa OI
2022-08-09  3:39       ` [PATCH v3 3/4] RISC-V: Fix JALR target " Tsukasa OI
2022-08-09  3:39       ` [PATCH v3 4/4] RISC-V: Add address printer tests on disassembler Tsukasa OI
2022-08-09  3:44     ` [PATCH v4 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
2022-08-09  3:44       ` [PATCH v4 1/4] RISC-V: Print highest address on disassembler Tsukasa OI
2022-08-09  3:44       ` [PATCH v4 2/4] RISC-V: Fix RV32 disassembler address computation Tsukasa OI
2022-08-09  3:44       ` [PATCH v4 3/4] RISC-V: Fix JALR target " Tsukasa OI
2022-08-09  3:44       ` [PATCH v4 4/4] RISC-V: Add address printer tests on disassembler Tsukasa OI
2022-08-09  4:41       ` [PATCH v5 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
2022-08-09  4:41         ` [PATCH v5 1/4] RISC-V: Print highest address on disassembler Tsukasa OI
2022-08-09  4:41         ` [PATCH v5 2/4] RISC-V: Fix RV32 disassembler address computation Tsukasa OI
2022-08-09  4:41         ` [PATCH v5 3/4] RISC-V: Fix JALR target " Tsukasa OI
2022-08-09  4:41         ` [PATCH v5 4/4] RISC-V: Add address printer tests on disassembler Tsukasa OI
2022-08-13 10:10         ` [PATCH v6 0/4] RISC-V: Fix address printer on the disassembler Tsukasa OI
2022-08-13 10:10           ` [PATCH v6 1/4] RISC-V: Print highest address on disassembler Tsukasa OI
2022-08-13 10:10           ` [PATCH v6 2/4] RISC-V: Fix RV32 disassembler address computation Tsukasa OI
2022-08-13 10:10           ` [PATCH v6 3/4] RISC-V: Fix JALR target " Tsukasa OI
2022-08-13 10:10           ` [PATCH v6 4/4] RISC-V: Add address printer tests on disassembler Tsukasa OI
2022-08-24  1:26           ` [PATCH v7 0/5] RISC-V: Fix address printer on the disassembler Tsukasa OI
2022-08-24  1:26             ` [PATCH v7 1/5] RISC-V: Print highest address on disassembler Tsukasa OI
2022-08-24 11:22               ` Nelson Chu
2022-08-24 11:22                 ` Nelson Chu
2022-08-24 12:06                 ` Tsukasa OI
2022-08-25  5:07                   ` Nelson Chu
2022-08-24  1:26             ` [PATCH v7 2/5] RISC-V: Fix RV32 disassembler address computation Tsukasa OI
2022-08-24 11:35               ` Nelson Chu
2022-08-24  1:26             ` [PATCH v7 3/5] RISC-V: Fix JALR target " Tsukasa OI
2022-08-24 11:36               ` Nelson Chu
2022-08-24  1:26             ` [PATCH v7 4/5] RISC-V: Add address printer tests on disassembler Tsukasa OI
2022-08-24 11:42               ` Nelson Chu
2022-08-24  1:26             ` [PATCH v7 5/5] RISC-V: Add address printer tests with ADDIW Tsukasa OI

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).