I’ve made some progress here.
gdb does keep track of the description for the current target, and it can
be retrieved by calling target_current_description(). My problems stemmed
from the fact that sometimes riscv_gdbarch_init() was called with an info
structure that did not have the current target description filled out. I
tracked this down to gdbarch_from_bfd(), which doesn’t set
info.target_desc. set_gdbarch_from_file() does do so (since 2008), and the
following patch makes everything work for me:
diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c
index 2ae3413087..6c84f100af 100644
--- a/gdb/arch-utils.c
+++ b/gdb/arch-utils.c
@@ -600,6 +600,7 @@ gdbarch_from_bfd (bfd *abfd)
gdbarch_info_init (&info);
info.abfd = abfd;
+ info.target_desc = target_current_description ();
return gdbarch_find_by_info (info);
}
Does this seem like the right solution? A better one might be to put this
assignment in gdbarch_info_init(). Or I could just call
target_current_description() in riscv_arch_init() when no target
description is passed in. The latter goes against the comment accompanying
target_current_description(), but it would only be a target-dependent
change.
Tim
​
On Wed, Dec 6, 2017 at 12:20 PM, Tim Newsome <tim@sifive.com> wrote:
> Still working on RISC-V support…
>
> I’ve taught OpenOCD to provide a target description, so now when
> connecting to a target that doesn’t have an FPU, the FPU registers don’t
> show up. Obviously I want this reflected in gdb, and I’ve managed to make
> that work in some cases. However, it doesn’t always work. Sometimes my
> target appears to revert to the case where it just uses the built-in list
> of registers, despite being connected to an OpenOCD that I know provides
> the target description.
>
> My confusion comes from when riscv_gdbarch_init() is called, and how. With
> a bit of instrumenting, I get this output:
>
> + /opt/riscv/bin/riscv64-unknown-elf-gdb
> >>> riscv_gdbarch_init()
> >>> bits_per_word=64
> >>> tdesc_has_register() -> 0
> >>> info.abfd=(nil)
> >>> abi=1073741824
> GNU gdb (GDB) 8.0.50.20170724-git
> ...
> (gdb) target extended-remote localhost:38295
>
> target extended-remote localhost:38295
> Remote debugging using localhost:38295
> >>> riscv_gdbarch_init()
> >>> bits_per_word=64
> >>> tdesc_has_register() -> 1
> >>> info.abfd=(nil)
> >>> abi=1073741824
> warning: No executable has been specified and target does not support
> determining executable automatically. Try using the "file" command.
> 0x00000000800009f0 in ?? ()
> (gdb) file HiFive1_debug-32
> >>> riscv_gdbarch_init()
>
> >>> bits_per_word=32
> >>> tdesc_has_register() -> 1
> >>> info.abfd=0x55a8a1f4e7f0
> >>> flavour=5
> >>> abi=0
> >>> riscv_gdbarch_init()
> >>> bits_per_word=32
> >>> tdesc_has_register() -> 0
> >>> info.abfd=0x55a8a1f4e7f0
> >>> flavour=5
> >>> abi=0
> Reading symbols from HiFive1_debug-32...done.
> (gdb) set arch riscv:rv32
> >>> riscv_gdbarch_init()
> >>> bits_per_word=32
> >>> tdesc_has_register() -> 1
> >>> info.abfd=0x55a8a1f4e7f0
> >>> flavour=5
> >>> abi=0
> The target architecture is assumed to be riscv:rv32
>
> It almost feels like I’m on completely the wrong track by initializing
> registers in riscv_gdbarch_init(), but that’s what the ARM and MIPS targets
> do. A lot of code in their gdbarch_init() is dedicated to figuring out the
> ABI in use. How are ABIs and registers related? In my world view the
> hardware has certain registers, and how the software chooses to use those
> registers is the ABI. But changing the ABI doesn’t change what registers
> exist.
>
> Are there callbacks I can use that are called when we connect
> to/disconnect from a remote server like OpenOCD?
>
> Thank you,
> Tim
> ​
>