aboutsummaryrefslogtreecommitdiff
path: root/gdb/riscv-tdep.c
diff options
context:
space:
mode:
authorAndrew Burgess <andrew.burgess@embecosm.com>2021-02-04 18:34:13 +0000
committerAndrew Burgess <andrew.burgess@embecosm.com>2021-02-24 16:06:54 +0000
commit895b7b4e4bed9eee9d4a3d55bee876055736bfd3 (patch)
tree99f835d6b88ce3dd716e62b17f26f0ea58d25812 /gdb/riscv-tdep.c
parentbc3c0632a2ebec04ad8c3c320dc8e9852bd2aabe (diff)
downloadgdb-895b7b4e4bed9eee9d4a3d55bee876055736bfd3.zip
gdb-895b7b4e4bed9eee9d4a3d55bee876055736bfd3.tar.gz
gdb-895b7b4e4bed9eee9d4a3d55bee876055736bfd3.tar.bz2
gdb/riscv: select rv32 target by default when requested
GDB for RISC-V always uses target descriptions. When the target doesn't provide a target description then a default is selected. Usually this default is selected based on the properties of the executable being debugged. However, when there is no executable being debugged we currently fallback to the riscv:rv64 target description as the default. This leads to strange behaviour like this: $ gdb (gdb) set architecture riscv:rv32 (gdb) p sizeof ($pc) $1 = 8 Despite the users specifically setting the architecture to riscv:rv32 GDB still thinks that the target has riscv:rv64 register sizes. The above is a bit of a contrived situation. I actually ran into this situation while trying to connect to a running riscv:rv32 target without supplying an executable (the target didn't provide a target description). When I tried to set a register on the target I ran into errors because GDB was passing 8 bytes to the target rather than the expected 4. Even when I manually specified the architecture (as above) I couldn't convince GDB to only send 4 bytes. This patch fixes this issue. Now, when we selected a default target description we will make use of the user selected architecture to guide our choice. In the above example we now get: $ gdb (gdb) set architecture riscv:rv32 (gdb) p sizeof ($pc) $1 = 4 And my real world example of connecting to a remote without an executable works fine. I've used the fact that we can ask GDB about $pc even when no executable is loaded as the basis for a test to cover this situation. gdb/ChangeLog: * riscv-tdep.c (riscv_features_from_gdbarch_info): Rename to... (riscv_features_from_bfd): ...this. Change parameter type to 'bfd*', and update as required. (riscv_find_default_target_description): Update call to riscv_features_from_bfd. Select a default xlen based on info.bfd_arch_info. (riscv_gdbarch_init): Update call to riscv_features_from_bfd. gdb/testsuite/ChangeLog: * gdb.arch/riscv-default-tdesc.exp: New file.
Diffstat (limited to 'gdb/riscv-tdep.c')
-rw-r--r--gdb/riscv-tdep.c28
1 files changed, 13 insertions, 15 deletions
diff --git a/gdb/riscv-tdep.c b/gdb/riscv-tdep.c
index 7463b0c..da86ed1 100644
--- a/gdb/riscv-tdep.c
+++ b/gdb/riscv-tdep.c
@@ -3215,13 +3215,11 @@ static const struct frame_unwind riscv_frame_unwind =
/*.prev_arch =*/ NULL,
};
-/* Extract a set of required target features out of INFO, specifically the
- bfd being executed is examined to see what target features it requires.
- IF there is no current bfd, or the bfd doesn't indicate any useful
- features then a RISCV_GDBARCH_FEATURES is returned in its default state. */
+/* Extract a set of required target features out of ABFD. If ABFD is
+ nullptr then a RISCV_GDBARCH_FEATURES is returned in its default state. */
static struct riscv_gdbarch_features
-riscv_features_from_gdbarch_info (const struct gdbarch_info info)
+riscv_features_from_bfd (const bfd *abfd)
{
struct riscv_gdbarch_features features;
@@ -3231,11 +3229,10 @@ riscv_features_from_gdbarch_info (const struct gdbarch_info info)
only used at all if the target hasn't given us a description, so this
is really a last ditched effort to do something sane before giving
up. */
- if (info.abfd != NULL
- && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
+ if (abfd != nullptr && bfd_get_flavour (abfd) == bfd_target_elf_flavour)
{
- unsigned char eclass = elf_elfheader (info.abfd)->e_ident[EI_CLASS];
- int e_flags = elf_elfheader (info.abfd)->e_flags;
+ unsigned char eclass = elf_elfheader (abfd)->e_ident[EI_CLASS];
+ int e_flags = elf_elfheader (abfd)->e_flags;
if (eclass == ELFCLASS32)
features.xlen = 4;
@@ -3273,13 +3270,14 @@ riscv_find_default_target_description (const struct gdbarch_info info)
{
/* Extract desired feature set from INFO. */
struct riscv_gdbarch_features features
- = riscv_features_from_gdbarch_info (info);
+ = riscv_features_from_bfd (info.abfd);
- /* If the XLEN field is still 0 then we got nothing useful from INFO. In
- this case we fall back to a minimal useful target, 8-byte x-registers,
- with no floating point. */
+ /* If the XLEN field is still 0 then we got nothing useful from INFO.BFD,
+ maybe there was no bfd object. In this case we fall back to a minimal
+ useful target with no floating point, the x-register size is selected
+ based on the architecture from INFO. */
if (features.xlen == 0)
- features.xlen = 8;
+ features.xlen = info.bfd_arch_info->bits_per_word == 32 ? 4 : 8;
/* Now build a target description based on the feature set. */
return riscv_lookup_target_description (features);
@@ -3497,7 +3495,7 @@ riscv_gdbarch_init (struct gdbarch_info info,
target, then check that this matches with what the target is
providing. */
struct riscv_gdbarch_features abi_features
- = riscv_features_from_gdbarch_info (info);
+ = riscv_features_from_bfd (info.abfd);
/* If the ABI_FEATURES xlen is 0 then this indicates we got no useful abi
features from the INFO object. In this case we just treat the