riscvarchive / riscv-qemu

QEMU with RISC-V (RV64G, RV32G) Emulation Support
384 stars 154 forks source link

Some instructions' disassembly codes are not displayed correctly #179

Closed lbmeng closed 5 years ago

lbmeng commented 5 years ago

Built a QEMU from riscv/riscv-qemu, and call it with '-s'. Use a riscv gdb (built from riscv/riscv-gnu-toolchain) to do remote debugging (target connect :1234)

Debugging Linux kernel's handle_exception, gdb told me:

0xffffffe0000311c8 ? csrr    tp,sscratch
0xffffffe0000311cc ? 0x223c23
0xffffffe0000311d0 ? 0x2223023
0xffffffe0000311d4 ? 0x1823103
0xffffffe0000311d8 ? addi    sp,sp,-288
0xffffffe0000311da ? 0xe406
0xffffffe0000311dc ? 0xec0e
0xffffffe0000311de ? 0xf416

While the actually disassembly codes by objdump are:

ffffffe0000311c0 <handle_exception>:
ffffffe0000311c0:       14021273                csrrw   tp,sscratch,tp
ffffffe0000311c4:       00021663                bnez    tp,ffffffe0000311d0 <handle_exception+0x10>
ffffffe0000311c8:       14002273                csrr    tp,sscratch
ffffffe0000311cc:       00223c23                sd      sp,24(tp) # 18 <__vdso_rt_sigreturn-0x7e8>
ffffffe0000311d0:       02223023                sd      sp,32(tp) # 20 <__vdso_rt_sigreturn-0x7e0>
ffffffe0000311d4:       01823103                ld      sp,24(tp) # 18 <__vdso_rt_sigreturn-0x7e8>
ffffffe0000311d8:       712d                    addi    sp,sp,-288
ffffffe0000311da:       e406                    sd      ra,8(sp)
ffffffe0000311dc:       ec0e                    sd      gp,24(sp)
ffffffe0000311de:       f416                    sd      t0,40(sp)
jim-wilson commented 5 years ago

The instructions that don't disassemble are RV64 instructions, that are only valid instructions in rv64 mode. Maybe gdb is confused about the target architecture somehow? It should get that from the executable, unless maybe you don't have one, or have something funny like a 32-bit bbl loading a 64-bit kernel. What does "show architecture" say? Does "set architecture riscv:rv64" help?

lbmeng commented 5 years ago

Thanks Jim. Indeed the "show architecture" said "The target architecture is set automatically (currently riscv)" which was the cause of issue reported. When I explicitly set to "riscv:rv64" the problem was gone.

I was under the impression that gdb should guess the target architecture from the file being debugged, but it's not always the case. It looks the following sequence works:

$ gdb <file_to_be_debugged>
(gdb) show architecture
The target architecture is set automatically (currently riscv:rv64)

or

$ gdb
(gdb) file <file_to_be_debugged>
(gdb) show architecture
The target architecture is set automatically (currently riscv:rv64)

But the following sequence does NOT work:

$ gdb
(gdb) add-symbol-file <file_to_be_debugged> <load_address>
(gdb) show architecture
The target architecture is set automatically (currently riscv)

Is this expected behavior that add-symbol-file does not change the architecture?

jim-wilson commented 5 years ago

I see the same behavior with the FSF gdb RISC-V port. And I see the same behavior on x86. Gdb starts in i386 mode, if I add-symbol-file an x86_64 binary, it remains in i386 mode. Looking at the gdb code, I see that the architecture is set to a default at gdb start, it is set if you use exec-file to load a binary, it is set if you use core to load a core file. It is not set if you load a symbol file. The file command by the way does both exec-file and symbol-file commands, where exec-file sets the architecture, and symbol-file does not. So yes, this looks like expected behavior to me.

lbmeng commented 5 years ago

Jim, thanks for the confirmation!

One more thing, what is the default architecture riscv for? Is that for RV32?

Besides, even if it is set to RV32 which riscv stands for, if you check the case I provided, I don't think bnez and csrr are 64-bit only instructions. Is this an issue?

michaeljclark commented 5 years ago

GDB defaults to RV32 if otherwise unknown?

I don't believe there is a default riscv architecture, however, making RV64 the default for Linux makes a little bit of sense because RV64 is the only widespread architecture with Linux support so far.

However, that is a change, so folk might complain if there is a change to the default. That's the problems with changes. You lose either way ;-) Someone out there has a script that depends on the default behaviour :-(

Worth thinking about though.

There is actually a disassembler in QEMU however it only shows up when tracing. The disassembly you are reporting is from binutils and gdb. QEMU is perhaps responsible if it were expected to signal the architecture to the GDB client. In any case it does seem like a GDB shortcoming. One would expect that GDB switches its disassembly personality when you give it an ELF file.

I'll leave this issue open until we figure out whether to raise an issue on the binutils issue tracker.

jim-wilson commented 5 years ago

The 32-bit architecture is riscv:rv32. The 64-bit architecture is riscv:rv64. If you have just "riscv", then we know the target is riscv related but we don't know which architecture. Not much is going to work when the arch is "riscv" as we won't know register sizes for instance. But we can handle disassembly of instructions that are common to the 32-bit and 64-bit architectures, which is why the RV32 instructions will still disassemble, but the RV64 instructions won't.

In your original example, the gdb output starts with a csrr instruction, but the objdump output starts with a csrrw instruction. The csrr instruction is actually the third instruction in the objdump output. So I don't believe there is any problem with disassembling the bnez and csrr instructions. You just need to properly align the gdb output with the objdump output.

I think this issue can be closed, as there is no qemu or gdb bug here.

lbmeng commented 5 years ago

Thanks Jim. Agree let's close this issue.