-
Notifications
You must be signed in to change notification settings - Fork 2
riscv_dis_fix_addr
- Status: Merged for Binutils 2.40 (non-tidying part)
- Branch:
riscv-dis-fix-addr - Tracking PR: #30 (view Pull Request and Diff)
- Mailing List:
- PATCH v1 (2022-07-29)
- PATCH v2 (2022-08-02)
- PATCH v3 (2022-08-04)
- PATCH v4 (with incorrect subject line) (2022-08-09)
- PATCH v4 (2022-08-09)
- PATCH v5 (2022-08-09)
- PATCH v6 (2022-08-13)
- PATCH v7 (2022-08-24)
- PATCH v8 (2022-08-27)
- PATCH v9 (with incorrect subject line) (2022-08-27)
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 (temporary variable is not -1))
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). - fixes address computation of the
JALRinstruction
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).
On disassembling programs using objdump, this patchset imposes a small performance penalty. This is usually around 1%.
Interestingly, Disassembler: Core improvements and optimizations (batch 1) shadows this degration.
This is relative to the latest master at the time of the benchmack (commit b82817674f4).
| Program | Improvements | Notes |
|---|---|---|
Busybox 1.35.1 (RV64GC) |
0.4-0.4% | |
OpenSBI 1.1 (generic fw_*.elf) |
0.3-0.5% | |
Linux kernel 5.18 (vmlinux) |
0.5-0.7% | |
Linux kernel 5.18 (vmlinux.o) |
0.2-1.2% | Not finally linked |
glibc (libc.so.6) |
0.0-0.4% |
| Program | Improvements |
|---|---|
glibc (libc.a) |
1.3-1.6% |
newlib (libc.a) |
2.0-2.5% |
| Program | Improvements |
|---|---|
Linux kernel 5.18 (vmlinux) |
0.0-6.3% |
Random files (/dev/urandom) |
(-1.1)-1.1% |
| 1M (1048576) CSR instructions | (-0.3)% |
| Program | Improvements |
|---|---|
Linux kernel 5.18 (vmlinux) with debug info |
0.5% |
Linux kernel 5.18 (vmlinux) without debug info |
1.2% |
OpenSBI 1.1 (generic fw_*.elf) |
0.2-0.3% |
| 1M (1048576) CSR instructions (ELF) | 1.1% |
| System | Path | N | Improvements |
|---|---|---|---|
| Ubuntu 22.04 LTS (image for HiFive Unmatched) | /usr/bin |
563 | 0.4% |
| Debian unstable (as of 2022-07-20) | /usr/bin |
269 | 0.5% |
| Ubuntu 22.04 LTS (image for HiFive Unmatched) | /usr/lib |
6797 | 1.2% |
| Debian unstable (as of 2022-07-20) | /usr/lib |
548 | 0.8% |
| System | N | Improvements |
|---|---|---|
| Ubuntu 22.04 LTS (image for HiFive Unmatched) | 7666 | 0.2% |
| Debian unstable (as of 2022-07-20) | 946 | 0.3% |
| System | Path | N | Improvements |
|---|---|---|---|
| Ubuntu 22.04 LTS (image for HiFive Unmatched) | /usr/bin |
563 | 0.7% |
| Debian unstable (as of 2022-07-20) | /usr/bin |
269 | 0.3% |
| System | N | Improvements |
|---|---|---|
| Ubuntu 22.04 LTS (image for HiFive Unmatched) | 7666 | 0.4% |
| Debian unstable (as of 2022-07-20) | 946 | 0.6% |