diff options
author | Tsukasa OI <research_trasio@irq.a4lg.com> | 2022-08-27 00:11:00 +0000 |
---|---|---|
committer | Nelson Chu <nelson@rivosinc.com> | 2022-09-02 12:06:27 +0800 |
commit | 48525554d5222d98953202b9252ff65fdead58a4 (patch) | |
tree | 87d8509f91fa6f04acc478418a129838f0c20722 /opcodes | |
parent | e9f7ba21f08a264f813140eb6221e9d9670dc12f (diff) | |
download | binutils-48525554d5222d98953202b9252ff65fdead58a4.zip binutils-48525554d5222d98953202b9252ff65fdead58a4.tar.gz binutils-48525554d5222d98953202b9252ff65fdead58a4.tar.bz2 |
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.
Diffstat (limited to 'opcodes')
-rw-r--r-- | opcodes/riscv-dis.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c index 164fd20..b3ca680 100644 --- a/opcodes/riscv-dis.c +++ b/opcodes/riscv-dis.c @@ -181,10 +181,16 @@ maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset, pd->print_addr = pd->gp + offset; else if (base_reg == X_TP || base_reg == 0) pd->print_addr = offset; + else + return; /* Don't print the address. */ /* Sign-extend a 32-bit value to a 64-bit value. */ if (wide) pd->print_addr = (bfd_vma)(int32_t) pd->print_addr; + + /* Fit into a 32-bit value on RV32. */ + if (xlen == 32) + pd->print_addr = (bfd_vma)(uint32_t)pd->print_addr; } /* Print insn arguments for 32/64-bit code. */ @@ -397,7 +403,7 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info case 'b': case 's': if ((l & MASK_JALR) == MATCH_JALR) - maybe_print_address (pd, rs1, 0, 0); + maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l), 0); print (info->stream, dis_style_register, "%s", riscv_gpr_names[rs1]); break; |