gef icon indicating copy to clipboard operation
gef copied to clipboard

RISC-V Remote Target Support?

Open kallisti5 opened this issue 3 years ago • 12 comments

Is your feature request related to a problem? Please describe. Looking for RISC-V support :-)

set architecture riscv
riscv       riscv:rv32  riscv:rv64 
gef➤  gef-remote -q localhost:1234
[!] Command 'gef-remote' failed to execute properly, reason: Unknown architecture: The target architecture is set to "riscv".
gef➤  gef-remote -q localhost:1234
[!] Command 'gef-remote' failed to execute properly, reason: Unknown architecture: The target architecture is set to "riscv:rv64".

kallisti5 avatar Jan 12 '21 21:01 kallisti5

Risc 5 is supported, it's just not detecting it properly. Try setting it manually: pi set_arch("riscv")

You're not giving us a lot to go on. Take a look and try to see why it's not detecting it.

Grazfather avatar Jan 13 '21 00:01 Grazfather

If you are using gdb >= 10.1 then this incorrect detection is probably due to #594, which should be fixed soon.

Grazfather avatar Jan 18 '21 15:01 Grazfather

Ah yup. gdb 10.1

I should note that running the non-gef specific remote target 127.0.0.1:1234 works as expected. I'll close this one as a duplicate of #594

kallisti5 avatar Jan 19 '21 01:01 kallisti5

Thank you.

Would you be able to check out that commit to verify that it fixes the issue for you?

Thanks

Grazfather avatar Jan 19 '21 01:01 Grazfather

@Grazfather hm.. maybe I closed this one too soon :-)

Using the latest gef from dev....

[kallisti5@eris generated.riscv64]$ riscv64-elf-gdb
Exception caught while booting Guile.
Error in function "make_objcode_from_file":
bad header on object file: "\x7fELF\x02\x01\x01ÿ\x00\x00\x00\x00\x00\x00\x00\x00"
riscv64-elf-gdb: warning: Could not complete Guile gdb module initialization from:
/usr/share/gdb/guile/gdb/boot.scm.
Limited Guile support is available.
Suggest passing --data-directory=/path/to/gdb/data-directory.
GNU gdb (GDB) 10.1
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "--host=x86_64-pc-linux-gnu --target=riscv64-elf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word".
GEF for linux ready, type `gef' to start, `gef config' to configure
92 commands loaded for GDB 10.1 using Python engine 3.9
gef➤  gef-remote -q localhost:1234
[!] Command 'gef-remote' failed to execute properly, reason: unsupported architecture: auto" (currently "riscv
gef➤  

kallisti5 avatar Apr 14 '21 01:04 kallisti5

To be honest.. things have gotten a bit worse:

gef➤  pi set_arch("riscv")
<__main__.RISCV object at 0x7f71502a8e80>
gef➤  add-symbol-file /home/kallisti5/Code/haiku/generated.riscv64/objects/haiku/riscv64/debug_1/system/boot/efi/boot_loader_efi 0xfe6bc000
add symbol table from file "/home/kallisti5/Code/haiku/generated.riscv64/objects/haiku/riscv64/debug_1/system/boot/efi/boot_loader_efi" at
	.text_addr = 0xfe6bc000
Reading symbols from /home/kallisti5/Code/haiku/generated.riscv64/objects/haiku/riscv64/debug_1/system/boot/efi/boot_loader_efi...
Python Exception <class 'OSError'> CPU type is currently not supported: riscv: 
gef➤  

Not calling pi set_arch("riscv")

For help, type "help".
Type "apropos word" to search for commands related to "word".
GEF for linux ready, type `gef' to start, `gef config' to configure
92 commands loaded for GDB 10.1 using Python engine 3.9
gef➤  add-symbol-file /home/kallisti5/Code/haiku/generated.riscv64/objects/haiku/riscv64/debug_1/system/boot/efi/boot_loader_efi 0xfe6bc000
add symbol table from file "/home/kallisti5/Code/haiku/generated.riscv64/objects/haiku/riscv64/debug_1/system/boot/efi/boot_loader_efi" at
	.text_addr = 0xfe6bc000
Reading symbols from /home/kallisti5/Code/haiku/generated.riscv64/objects/haiku/riscv64/debug_1/system/boot/efi/boot_loader_efi...
Python Exception <class 'gdb.error'> Not supported on this target.: 

Here are the valid riscv architectures:

gef➤  set architecture
Requires an argument. Valid arguments are riscv, riscv:rv64, riscv:rv32, auto.

kallisti5 avatar Apr 14 '21 01:04 kallisti5

Here's the raw GDB stub output from qemu-system-riscv64. I hate it :laughing:

$qXfer:features:read:target.xml:0,4096#1E

+$l<?xml version="1.0"?><!DOCTYPE target SYSTEM "gdb-target.dtd"><target><xi:include href="riscv-64bit-cpu.xml"/><xi:include href="riscv-64bit-fpu.xml"/><xi:include href="riscv-64bit-csr.xml"/><xi:include href="riscv-64bit-virtual.xml"/></target>#68

There's no "<architecture>" defined there from the qemu code. Looking at qemu's gdbstub...

   if (strncmp(p, "target.xml", len) == 0) {
        char *buf = process->target_xml;
        const size_t buf_sz = sizeof(process->target_xml);

        /* Generate the XML description for this CPU.  */
        if (!buf[0]) {
            GDBRegisterState *r;

            pstrcat(buf, buf_sz,
                    "<?xml version=\"1.0\"?>"
                    "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
                    "<target>");
            if (cc->gdb_arch_name) {
                gchar *arch = cc->gdb_arch_name(cpu);
                pstrcat(buf, buf_sz, "<architecture>");
                pstrcat(buf, buf_sz, arch);
                pstrcat(buf, buf_sz, "</architecture>");
                g_free(arch);
            }

So it looks like qemu isn't setting gdb_arch_name for riscv. Looking through the qemu source code...

https://github.com/qemu/qemu/commit/edf647864bdab84ed4b1a4f47ea05be6bb075c69

Oops... a really recent addition :-)

So.. it looks like gdb is calling no architecture defined in the target.xml as "auto"

gef might want to handle "auto" with some special warning case :-)

kallisti5 avatar Apr 14 '21 02:04 kallisti5

I compiled qemu 6.0, and it indeed reports architecture now...

$qXfer:features:read:target.xml:0,4096#1E
+$l<?xml version="1.0"?><!DOCTYPE target SYSTEM "gdb-target.dtd"><target><architecture>riscv:rv64</architecture><xi:include href="riscv-64bit-cpu.xml"/><xi:include href="riscv-64bit-fpu.xml"/><xi:include href="riscv-64bit-virtual.xml"/><xi:include href="riscv-csr.xml"/></target>#6e

Now gef shows:

gef➤  gef-remote -q 127.0.0.1:1234
[!] Command 'gef-remote' failed to execute properly, reason: unsupported architecture: riscv:rv64

A quick patch to gef:

[kallisti5@eris generated.riscv64]$ diff -Naur ~/.gdbinit-gef-stock.py ~/.gdbinit-gef.py
--- /home/kallisti5/.gdbinit-gef-stock.py	2021-04-14 08:43:21.201598648 -0500
+++ /home/kallisti5/.gdbinit-gef.py	2021-04-14 08:44:00.975034941 -0500
@@ -6320,6 +6320,9 @@
         elif arch.startswith("sparc"):
             current_elf.e_machine = Elf.SPARC
             current_arch = SPARC()
+        elif arch.startswith("riscv"):
+            current_elf.e_machine = Elf.RISCV
+            current_arch = RISCV()
         else:
             raise RuntimeError("unsupported architecture: {}".format(arch))
 

Back to the original error :angry: under qemu 6.0

gef➤  gef-remote -q 127.0.0.1:1234
[!] Command 'gef-remote' failed to execute properly, reason: unsupported architecture: auto" (currently "riscv

kallisti5 avatar Apr 14 '21 13:04 kallisti5

You'll have to break this into separate issue. Can you debug risc5 locally?

What are you using as your riscv target? Do you have some easy qemu setup I could use to reproduce.

Grazfather avatar Apr 14 '21 21:04 Grazfather

to reproduce, qemu-system-riscv64 -s -S is enough to give gdb / gef something to connect to. qemu-system-riscv64 ships in os packages for Fedora / ArchLinux that I know of.

However for the fix I mentioned above, you might have to compile qemu-system-riscv64 6.x from upstream qemu.

I've attached my qemu 6.x qemu-system-riscv64, but it likely won't help much if you don't have matching system libraries to run it qemu-riscv64.zip

kallisti5 avatar Apr 14 '21 21:04 kallisti5

Yes, I have that, I'll have to take some time to get a linux system running in it, it's just not a priority for me right now.

Grazfather avatar Apr 17 '21 12:04 Grazfather

JFYI, AFAICT running an OS within qemu is not required to investigate the problem. The parameters he mentioned halt the CPU at reset and one can use gdb to run a bare-metal binary. This is a common setup for embedded systems/microcontrollers (where you also debug via GDB's remote function and a gdb server stub running in a hardware debugger dongle. This will be less useful with riscv64 but for riscv32 microcontrollers. (I am working on hw security mechanisms on these thus my interest in this issue ;)

stefanct avatar Aug 23 '21 09:08 stefanct

I do not have this same issue (years later 😅).

I am using this dockerfile to install both qemu and gdb with riscv64 support.

It still isn't perfect, because it doesn't know how to map the stack, but I think that's another issue.

If any of you are still using riscv, I would be curious to understand how it's behaving for you now.

Grazfather avatar Sep 02 '23 14:09 Grazfather