-
Notifications
You must be signed in to change notification settings - Fork 1
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
wide
argument (is_addiw
fits the context). - fixes address computation of the
JALR
instruction
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% |