riscvarchive / riscv-binutils-gdb

RISC-V backports for binutils-gdb. Development is done upstream at the FSF.
GNU General Public License v2.0
147 stars 233 forks source link

RISC-V: Inform the disassembler that x0 is always 0 #133

Closed palmer-dabbelt closed 6 years ago

palmer-dabbelt commented 6 years ago

The RISC-V ISA defines a hardware-enforced zero register, denotated as either x0 or zero. Normal programs don't write to this register, but when playing around with how our assembler interprets awkward addresses I noticed that our disassembler doesn't know that x0 always has the value 0. For example, before this patch we produce the following output:

0000000000010078 <__bss_start-0x1008>:
   10078:   00000017            auipc   zero,0x0
   1007c:   00003003            ld  zero,0(zero) # 10078 <__bss_start-0x1008>

While I'm arithmatically challaged, I'm pretty sure that 0+0 isn't 0x10078. This isn't really a problem: it's just an incorrect disassembler hint and nobody should we writing to x0 anyway, but it's technically wrong.

opcodes/ChangeLog

2018-01-08 Palmer Dabbelt palmer@dabbelt.com

    * riscv-dis.c (maybe_print_address): x0 is always 0.

gas/ChangeLog

2018-01-08 Palmer Dabbelt palmer@dabbelt.com

    * testsuite/gas/riscv/auipc-x0.d: New testcase.
    * testsuite/gas/riscv/auipc-x0.s: Likewise.
palmer-dabbelt commented 6 years ago

@jim-wilson I haven't even compiled this. Do you mind taking it over?

jim-wilson commented 6 years ago

Patch added upstream. The testcase had to be modified slightly to demonstrate the problem. I added a .skip 64 so that the auipc did not have a 0 address in the object file. Also, in the riscv-dis.c file, I don't think it is safe to unconditionally set register 0 to 0 as a -1 value has a special meaning, so I moved the code inside the if statement that compares a register value against -1.