RISC-V: PR29342, Fix RV32 disassembler address computation

If either the base register is `zero', `tp' or `gp' and XLEN is 32, an
incorrectly sign-extended address is produced when printing.  This commit
fixes this by fitting an address into a 32-bit value on RV32.

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

gas/
	pr29342
	* testsuite/gas/riscv/lla32.d: Reflect RV32 address computation fix.
	* testsuite/gas/riscv/dis-addr-overflow.s: New testcase.
	* testsuite/gas/riscv/dis-addr-overflow-32.d: Likewise.
	* testsuite/gas/riscv/dis-addr-overflow-64.d: Likewise.
opcodes/
	pr29342
	* riscv-dis.c (maybe_print_address): Fit address into 32-bit on RV32.
	(print_insn_args): Fix JALR address by adding EXTRACT_ITYPE_IMM.
This commit is contained in:
Tsukasa OI 2022-08-27 00:11:00 +00:00 committed by Nelson Chu
parent e9f7ba21f0
commit 48525554d5
5 changed files with 142 additions and 2 deletions

View File

@ -0,0 +1,30 @@
#as: -march=rv32ic
#source: dis-addr-overflow.s
#objdump: -d
.*: file format elf32-(little|big)riscv
Disassembly of section .text:
0+000 <target>:
[ ]+[0-9a-f]+:[ ]+fffff2b7[ ]+lui[ ]+t0,0xfffff
[ ]+[0-9a-f]+:[ ]+ffc2a903[ ]+lw[ ]+s2,-4\(t0\) # ffffeffc <addr_load>
[ ]+[0-9a-f]+:[ ]+ffffe337[ ]+lui[ ]+t1,0xffffe
[ ]+[0-9a-f]+:[ ]+ff332c23[ ]+sw[ ]+s3,-8\(t1\) # ffffdff8 <addr_store>
[ ]+[0-9a-f]+:[ ]+ffffd3b7[ ]+lui[ ]+t2,0xffffd
[ ]+[0-9a-f]+:[ ]+000380e7[ ]+jalr[ ]+t2 # ffffd000 <addr_jalr_1>
[ ]+[0-9a-f]+:[ ]+ffffce37[ ]+lui[ ]+t3,0xffffc
[ ]+[0-9a-f]+:[ ]+ff4e00e7[ ]+jalr[ ]+-12\(t3\) # ffffbff4 <addr_jalr_2>
[ ]+[0-9a-f]+:[ ]+ffffbeb7[ ]+lui[ ]+t4,0xffffb
[ ]+[0-9a-f]+:[ ]+000e8a67[ ]+jalr[ ]+s4,t4 # ffffb000 <addr_jalr_3>
[ ]+[0-9a-f]+:[ ]+ffffaf37[ ]+lui[ ]+t5,0xffffa
[ ]+[0-9a-f]+:[ ]+ff0f0a93[ ]+addi[ ]+s5,t5,-16 # ffff9ff0 <addr_loadaddr>
[ ]+[0-9a-f]+:[ ]+ffff9fb7[ ]+lui[ ]+t6,0xffff9
[ ]+[0-9a-f]+:[ ]+1fb1[ ]+addi[ ]+t6,t6,-20 # ffff8fec <addr_loadaddr_c>
[ ]+[0-9a-f]+:[ ]+4001a283[ ]+lw[ ]+t0,1024\(gp\) # 600 <addr_rel_gp_pos>
[ ]+[0-9a-f]+:[ ]+c001a303[ ]+lw[ ]+t1,-1024\(gp\) # fffffe00 <addr_rel_gp_neg>
[ ]+[0-9a-f]+:[ ]+10002383[ ]+lw[ ]+t2,256\(zero\) # 100 <addr_rel_zero_pos>
[ ]+[0-9a-f]+:[ ]+80002e03[ ]+lw[ ]+t3,-2048\(zero\) # fffff800 <addr_rel_zero_neg>
[ ]+[0-9a-f]+:[ ]+10400ee7[ ]+jalr[ ]+t4,260\(zero\) # 104 <addr_jalr_rel_zero_pos>
[ ]+[0-9a-f]+:[ ]+80400f67[ ]+jalr[ ]+t5,-2044\(zero\) # fffff804 <addr_jalr_rel_zero_neg>

View File

@ -0,0 +1,34 @@
#as: -march=rv64ic -defsym rv64=1
#source: dis-addr-overflow.s
#objdump: -d
.*: file format elf64-(little|big)riscv
Disassembly of section .text:
0+000 <target>:
[ ]+[0-9a-f]+:[ ]+fffff2b7[ ]+lui[ ]+t0,0xfffff
[ ]+[0-9a-f]+:[ ]+ffc2a903[ ]+lw[ ]+s2,-4\(t0\) # ffffffffffffeffc <addr_load>
[ ]+[0-9a-f]+:[ ]+ffffe337[ ]+lui[ ]+t1,0xffffe
[ ]+[0-9a-f]+:[ ]+ff332c23[ ]+sw[ ]+s3,-8\(t1\) # ffffffffffffdff8 <addr_store>
[ ]+[0-9a-f]+:[ ]+ffffd3b7[ ]+lui[ ]+t2,0xffffd
[ ]+[0-9a-f]+:[ ]+000380e7[ ]+jalr[ ]+t2 # ffffffffffffd000 <addr_jalr_1>
[ ]+[0-9a-f]+:[ ]+ffffce37[ ]+lui[ ]+t3,0xffffc
[ ]+[0-9a-f]+:[ ]+ff4e00e7[ ]+jalr[ ]+-12\(t3\) # ffffffffffffbff4 <addr_jalr_2>
[ ]+[0-9a-f]+:[ ]+ffffbeb7[ ]+lui[ ]+t4,0xffffb
[ ]+[0-9a-f]+:[ ]+000e8a67[ ]+jalr[ ]+s4,t4 # ffffffffffffb000 <addr_jalr_3>
[ ]+[0-9a-f]+:[ ]+ffffaf37[ ]+lui[ ]+t5,0xffffa
[ ]+[0-9a-f]+:[ ]+ff0f0a93[ ]+addi[ ]+s5,t5,-16 # ffffffffffff9ff0 <addr_loadaddr>
[ ]+[0-9a-f]+:[ ]+ffff9fb7[ ]+lui[ ]+t6,0xffff9
[ ]+[0-9a-f]+:[ ]+1fb1[ ]+addi[ ]+t6,t6,-20 # ffffffffffff8fec <addr_loadaddr_c>
[ ]+[0-9a-f]+:[ ]+ffff8b37[ ]+lui[ ]+s6,0xffff8
[ ]+[0-9a-f]+:[ ]+fe8b0b9b[ ]+addiw[ ]+s7,s6,-24 # ffffffffffff7fe8 <addr_loadaddr_w>
[ ]+[0-9a-f]+:[ ]+ffff7c37[ ]+lui[ ]+s8,0xffff7
[ ]+[0-9a-f]+:[ ]+3c11[ ]+addiw[ ]+s8,s8,-28 # ffffffffffff6fe4 <addr_loadaddr_w_c>
[ ]+[0-9a-f]+:[ ]+4001a283[ ]+lw[ ]+t0,1024\(gp\) # 600 <addr_rel_gp_pos>
[ ]+[0-9a-f]+:[ ]+c001a303[ ]+lw[ ]+t1,-1024\(gp\) # fffffffffffffe00 <addr_rel_gp_neg>
[ ]+[0-9a-f]+:[ ]+10002383[ ]+lw[ ]+t2,256\(zero\) # 100 <addr_rel_zero_pos>
[ ]+[0-9a-f]+:[ ]+80002e03[ ]+lw[ ]+t3,-2048\(zero\) # fffffffffffff800 <addr_rel_zero_neg>
[ ]+[0-9a-f]+:[ ]+10400ee7[ ]+jalr[ ]+t4,260\(zero\) # 104 <addr_jalr_rel_zero_pos>
[ ]+[0-9a-f]+:[ ]+80400f67[ ]+jalr[ ]+t5,-2044\(zero\) # fffffffffffff804 <addr_jalr_rel_zero_neg>

View File

@ -0,0 +1,70 @@
.set __global_pointer$, 0x00000200
.ifdef rv64
topbase = 0xffffffff00000000
.else
topbase = 0
.endif
.set addr_load, topbase + 0xffffeffc # -0x1000 -4
.set addr_store, topbase + 0xffffdff8 # -0x2000 -8
.set addr_jalr_1, topbase + 0xffffd000 # -0x3000
.set addr_jalr_2, topbase + 0xffffbff4 # -0x4000 -12
.set addr_jalr_3, topbase + 0xffffb000 # -0x5000
.set addr_loadaddr, topbase + 0xffff9ff0 # -0x6000 -16
.set addr_loadaddr_c, topbase + 0xffff8fec # -0x7000 -20
.set addr_loadaddr_w, topbase + 0xffff7fe8 # -0x8000 -24
.set addr_loadaddr_w_c, topbase + 0xffff6fe4 # -0x9000 -28
.set addr_rel_gp_pos, 0x00000600 # __global_pointer$ + 0x400
.set addr_rel_gp_neg, topbase + 0xfffffe00 # __global_pointer$ - 0x400
.set addr_rel_zero_pos, 0x00000100
.set addr_rel_zero_neg, topbase + 0xfffff800 # -0x800
.set addr_jalr_rel_zero_pos, 0x00000104
.set addr_jalr_rel_zero_neg, topbase + 0xfffff804 # -0x7fc
target:
.option push
.option arch, -c
## Use hi_addr
# Load
lui t0, 0xfffff
lw s2, -4(t0)
# Store
lui t1, 0xffffe
sw s3, -8(t1)
# JALR (implicit destination, no offset)
lui t2, 0xffffd
jalr t2
# JALR (implicit destination, with offset)
lui t3, 0xffffc
jalr -12(t3)
# JALR (explicit destination, no offset)
lui t4, 0xffffb
jalr s4, t4
# ADDI (not compressed)
lui t5, 0xffffa
addi s5, t5, -16
# C.ADDI
lui t6, 0xffff9
.option pop
c.addi t6, -20
.ifdef rv64
.option push
.option arch, -c
# ADDIW (not compressed)
lui s6, 0xffff8
addiw s7, s6, -24
# C.ADDIW
lui s8, 0xffff7
.option pop
c.addiw s8, -28
.endif
# Use addresses relative to gp
lw t0, 0x400(gp)
lw t1, -0x400(gp)
# Use addresses relative to zero
lw t2, 0x100(zero)
lw t3, -0x800(zero)
jalr t4, 0x104(zero)
jalr t5, -0x7fc(zero)

View File

@ -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

View File

@ -181,10 +181,16 @@ maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset,
pd->print_addr = pd->gp + offset;
else if (base_reg == X_TP || base_reg == 0)
pd->print_addr = offset;
else
return; /* Don't print the address. */
/* Sign-extend a 32-bit value to a 64-bit value. */
if (wide)
pd->print_addr = (bfd_vma)(int32_t) pd->print_addr;
/* Fit into a 32-bit value on RV32. */
if (xlen == 32)
pd->print_addr = (bfd_vma)(uint32_t)pd->print_addr;
}
/* Print insn arguments for 32/64-bit code. */
@ -397,7 +403,7 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info
case 'b':
case 's':
if ((l & MASK_JALR) == MATCH_JALR)
maybe_print_address (pd, rs1, 0, 0);
maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0);
print (info->stream, dis_style_register, "%s", riscv_gpr_names[rs1]);
break;