-
Notifications
You must be signed in to change notification settings - Fork 274
Description
Version and Platform (required):
- Binary Ninja Version: 5.2.8722 Personal (c75356aa)
- OS: macOS
- CPU Architecture: ARM64
Bug Description:
When disassembling a RISC-V relocatable (.o) file, references to data can end up pointing to the wrong location. Initial triage by bdash on Slack suggests that this may be due to multiple symbols with the same name.
Steps To Reproduce:
- Acquire a RISC-V binutils toolchain from somewhere.
- Run
objdump -xdsS wch_nfca_pcd.oand observe the following disassembly, including a reference togs_nfca_pcd_controller. This is within thenfca_pcd_lib_initfunction, which should be the first function in the file.
0000000c <.L4>:
c: 4918 lw a4,16(a0)
e: 00000797 auipc a5,0x0
e: R_RISCV_PCREL_HI20 gs_nfca_pcd_controller
e: R_RISCV_RELAX *ABS*
12: 00078793 mv a5,a5
12: R_RISCV_PCREL_LO12_I .L0
12: R_RISCV_RELAX *ABS*
16: 414c lw a1,4(a0)
18: cb98 sw a4,16(a5)
1a: 4958 lw a4,20(a0)
1c: 4510 lw a2,8(a0)
1e: 4554 lw a3,12(a0)
20: 00052803 lw a6,0(a0)
24: cbd8 sw a4,20(a5)
26: 4d18 lw a4,24(a0)
28: 0107a023 sw a6,0(a5) # e <.L4+0x2>
2c: c3cc sw a1,4(a5)
2e: c790 sw a2,8(a5)
30: c7d4 sw a3,12(a5)
32: cf98 sw a4,24(a5)
34: 4501 li a0,0
36: 8082 ret
- Run
readelf -r wch_nfca_pcd.oand observe the following output. TheR_RISCV_PCREL_LO12_Irelocation points to symbol 0x3b (decimal 59), and readelf resolves the address to 0xe (where theR_RISCV_PCREL_HI20relocation pointing to the actual target can be found).
0000000e 00000717 R_RISCV_PCREL_HI2 00000000 gs_nfca_pcd_controller + 0
0000000e 00000033 R_RISCV_RELAX 0
00000012 00003b18 R_RISCV_PCREL_LO1 0000000e .L0 + 0
00000012 00000033 R_RISCV_RELAX 0
- Run
readelf -s wch_nfca_pcd.oand observe the following output. Symbol 59 indeed contains the value 0xe. Note that symbol 58, with the same name, contains the value 0x0.
58: 00000000 0 NOTYPE LOCAL DEFAULT 4 .L0
59: 0000000e 0 NOTYPE LOCAL DEFAULT 4 .L0
60: 00000038 0 NOTYPE LOCAL DEFAULT 4 .L2
61: 0000000c 0 NOTYPE LOCAL DEFAULT 4 .L4
- Open the object file in Binary Ninja, switch to disassembly view, and observe the following output:
.L4:
0001000c 1849 lw a4, 0x10(a0)
0001000e 97070000 auipc a5, 0x0
00010012 93870775 addi a5, a5, 0x750 {0x1075e}
00010016 4c41 lw a1, 0x4(a0)
00010018 98cb sw a4, 0x10(a5) {0x1076e}
0001001a 5849 lw a4, 0x14(a0)
0001001c 1045 lw a2, 0x8(a0)
0001001e 5445 lw a3, 0xc(a0)
00010020 03280500 lw a6, 0x0(a0)
00010024 d8cb sw a4, 0x14(a5) {data_10772}
00010026 184d lw a4, 0x18(a0)
00010028 23a00701 sw a6, 0x0(a5) {0x1075e}
0001002c ccc3 sw a1, 0x4(a5) {0x10762}
0001002e 90c7 sw a2, 0x8(a5) {0x10766}
00010030 d4c7 sw a3, 0xc(a5) {0x1076a}
00010032 98cf sw a4, 0x18(a5) {data_10776}
00010034 0145 li a0, 0x0
00010036 8280 ret
- Enter the following in the Binary Ninja Python console:
>>> bv.relocations_at(0x10012)
[<Relocation: ".L0 " @ 0x10000>]- Scroll to the bottom of the disassembly view and observe that the correct address for the
gs_nfca_pcd_controllersymbol should be 0x10770:
.bss.gs_nfca_pcd_controller (NOBITS) section started {0x10770-0x107a4}
00010770 gs_nfca_pcd_controller:
00010770 00 00 ..
00010772 int32_t data_10772 = 0x0
00010776 int32_t data_10776 = 0x0
0001077a 00 00 00 00 00 00 ......
00010780 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00010790 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000107a0 00 00 00 00 ....
.bss.gs_nfca_pcd_controller (NOBITS) section ended {0x10770-0x107a4}
Expected Behavior:
Binary Ninja has incorrectly resolved gs_nfca_pcd_controller to 0x1075e, which does not lie within any section. The reference to the object should be resolved correctly, just as binutils is able to.
Screenshots/Video Recording:
N/A
Binary:
Additional Information:
This binary contains currently-unsupported RISC-V bitmanip instructions as well as vendor-proprietary instructions that replace existing opcodes. As such, it will not fully disassemble (bitmanip instructions will be unknown, and the vendor instructions will incorrectly disassemble as double-precision floating-point load/stores). This does not affect relocation processing.
The R_RISCV_RELAX relocation causes [RISCV] Unknown relocation type 51 at XXXXX warnings in the logs. This can be ignored.