-
Notifications
You must be signed in to change notification settings - Fork 2
riscv_dis_fix_addr
- Branch:
riscv-dis-fix-addr - Tracking PR: #30 (view Pull Request and Diff)
- Mailing List:
- PATCH v1 (2022-07-29)
- Upcoming (Pending): Disassembler: Core improvements and optimizations (batch 1)
It also touches the core disassembler.-
Rebased
riscv-dis-opts-batch-1branch is available
-
Rebased
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:
- fits an address into a 32-bit value on RV32 (resolves PR29342)
- makes the highest address printable (
0xffffffff(RV32) and0xffffffff_ffffffff(RV64) can be printed as a real symbol) - clarifies the meaning of the
wideargument (is_addiwfits 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).