Skip to content

riscv_dis_fix_addr

Tsukasa OI edited this page Sep 3, 2022 · 21 revisions

Disassembler: Fix address printer

Issue Solved

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:

  1. fits an address into a 32-bit value on RV32 (resolves PR29342)
  2. makes the highest address printable (0xffffffff (RV32) and 0xffffffff_ffffffff (RV64) can be printed as a real symbol)
  3. clarifies the meaning of the wide argument (is_addiw fits the context).
  4. 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).

Benchmarks

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).

objdump -d (ELF)

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%

objdump -d (ELF-based archive)

Program Improvements
glibc (libc.a) 1.3-1.6%
newlib (libc.a) 2.0-2.5%

objdump -D (binary)

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)%

gdb: disas of near all code region

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%

Batch: objdump -d on Linux distribution

Serial Run: All ELF Files Under the Directory

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%

Parallel Run: All (including data-only ELFs)

System N Improvements
Ubuntu 22.04 LTS (image for HiFive Unmatched) 7666 0.2%
Debian unstable (as of 2022-07-20) 946 0.3%

Batch: objdump -D (as binary) on Linux distribution

Serial Run: All ELF Files Under the Directory

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%

Parallel Run: All (including data-only ELFs)

System N Improvements
Ubuntu 22.04 LTS (image for HiFive Unmatched) 7666 0.4%
Debian unstable (as of 2022-07-20) 946 0.6%
Clone this wiki locally