Closed lbmeng closed 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?
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?
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.
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?
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.
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.
Thanks Jim. Agree let's close this issue.
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:
While the actually disassembly codes by objdump are: