aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog13
-rw-r--r--gdb/Makefile.in4
-rwxr-xr-xgdb/configure3
-rw-r--r--gdb/configure.ac3
-rw-r--r--gdb/configure.tgt2
-rw-r--r--gdb/elf-none-tdep.c126
-rw-r--r--gdb/elf-none-tdep.h30
-rw-r--r--gdb/riscv-none-tdep.c113
8 files changed, 291 insertions, 3 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index dbcc524..1a1076a 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,16 @@
+2021-03-05 Andrew Burgess <andrew.burgess@embecosm.com>
+ Craig Blackmore <craig.blackmore@embecosm.com>
+
+ * Makefile.in (ALL_TARGET_OBS): Add riscv-none-tdep.o.
+ (ALLDEPFILES): Add riscv-none-tdep.c.
+ * configure: Regenerate.
+ * configure.ac (CONFIG_OBS): Add elf-none-tdep.o when BFD has ELF
+ support.
+ * configure.tgt (riscv*-*-*): Include riscv-none-tdep.c.
+ * elf-none-tdep.c: New file.
+ * elf-none-tdep.h: New file.
+ * riscv-none-tdep.c: New file.
+
2021-03-05 Craig Blackmore <craig.blackmore@embecosm.com>
Andrew Burgess <andrew.burgess@embecosm.com>
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index cf5017e..a6ca5a5 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -808,6 +808,7 @@ ALL_TARGET_OBS = \
ravenscar-thread.o \
riscv-fbsd-tdep.o \
riscv-linux-tdep.o \
+ riscv-none-tdep.o \
riscv-ravenscar-thread.o \
riscv-tdep.o \
rl78-tdep.o \
@@ -1189,6 +1190,7 @@ SFILES = \
cp-name-parser.y \
d-exp.y \
dtrace-probe.c \
+ elf-none-tdep.c \
elfread.c \
f-exp.y \
gcore-elf.c \
@@ -1363,6 +1365,7 @@ HFILES_NO_SRCDIR = \
netbsd-tdep.h \
nds32-tdep.h \
nios2-tdep.h \
+ elf-none-tdep.h \
nto-tdep.h \
objc-lang.h \
objfiles.h \
@@ -2274,6 +2277,7 @@ ALLDEPFILES = \
riscv-fbsd-tdep.c \
riscv-linux-nat.c \
riscv-linux-tdep.c \
+ riscv-none-tdep.c \
riscv-ravenscar-thread.c \
riscv-tdep.c \
rl78-tdep.c \
diff --git a/gdb/configure b/gdb/configure
index 4707fd0..4c80350 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -17264,7 +17264,8 @@ $as_echo "$gdb_cv_var_elf" >&6; }
LDFLAGS=$OLD_LDFLAGS
LIBS=$OLD_LIBS
if test "$gdb_cv_var_elf" = yes; then
- CONFIG_OBS="$CONFIG_OBS elfread.o stap-probe.o dtrace-probe.o gcore-elf.o"
+ CONFIG_OBS="$CONFIG_OBS elfread.o stap-probe.o dtrace-probe.o \
+ gcore-elf.o elf-none-tdep.o"
$as_echo "#define HAVE_ELF 1" >>confdefs.h
diff --git a/gdb/configure.ac b/gdb/configure.ac
index db765af..7035014 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -1882,7 +1882,8 @@ WIN32LIBS="$WIN32LIBS $WIN32APILIBS"
GDB_AC_CHECK_BFD([for ELF support in BFD], gdb_cv_var_elf,
[bfd_get_elf_phdr_upper_bound (NULL)], elf-bfd.h)
if test "$gdb_cv_var_elf" = yes; then
- CONFIG_OBS="$CONFIG_OBS elfread.o stap-probe.o dtrace-probe.o gcore-elf.o"
+ CONFIG_OBS="$CONFIG_OBS elfread.o stap-probe.o dtrace-probe.o \
+ gcore-elf.o elf-none-tdep.o"
AC_DEFINE(HAVE_ELF, 1,
[Define if ELF support should be included.])
# -ldl is provided by bfd/Makfile.am (LIBDL) <PLUGINS>.
diff --git a/gdb/configure.tgt b/gdb/configure.tgt
index 842e683..9102067 100644
--- a/gdb/configure.tgt
+++ b/gdb/configure.tgt
@@ -85,7 +85,7 @@ ia64*-*-*)
;;
riscv*-*-*)
- cpu_obs="riscv-tdep.o arch/riscv.o \
+ cpu_obs="riscv-tdep.o riscv-none-tdep.o arch/riscv.o \
ravenscar-thread.o riscv-ravenscar-thread.o";;
x86_64-*-*)
diff --git a/gdb/elf-none-tdep.c b/gdb/elf-none-tdep.c
new file mode 100644
index 0000000..4cbb664
--- /dev/null
+++ b/gdb/elf-none-tdep.c
@@ -0,0 +1,126 @@
+/* Common code for targets with the none ABI (bare-metal), but where the
+ BFD library is build with ELF support.
+
+ Copyright (C) 2020-2021 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "defs.h"
+#include "elf-none-tdep.h"
+#include "regset.h"
+#include "elf-bfd.h" /* for elfcore_write_* */
+#include "inferior.h"
+#include "regcache.h"
+#include "gdbarch.h"
+#include "gcore.h"
+#include "gcore-elf.h"
+
+/* Build the note section for a corefile, and return it in a malloc
+ buffer. Currently this just dumps all available registers for each
+ thread. */
+
+static gdb::unique_xmalloc_ptr<char>
+elf_none_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd,
+ int *note_size)
+{
+ gdb::unique_xmalloc_ptr<char> note_data;
+
+ /* Add note information about the executable and its arguments. */
+ std::string fname;
+ std::string psargs;
+ static const size_t fname_len = 16;
+ static const size_t psargs_len = 80;
+ if (get_exec_file (0))
+ {
+ const char *exe = get_exec_file (0);
+ fname = lbasename (exe);
+ psargs = std::string (exe);
+
+ const char *infargs = get_inferior_args ();
+ if (infargs != nullptr)
+ psargs += " " + std::string (infargs);
+
+ /* All existing targets that handle writing out prpsinfo expect the
+ fname and psargs strings to be at least 16 and 80 characters long
+ respectively, including a null terminator at the end. Resize to
+ the expected length minus one to ensure there is a null within the
+ required length. */
+ fname.resize (fname_len - 1);
+ psargs.resize (psargs_len - 1);
+ }
+
+ /* Resize the buffers up to their required lengths. This will fill any
+ remaining space with the null character. */
+ fname.resize (fname_len);
+ psargs.resize (psargs_len);
+
+ /* Now write out the prpsinfo structure. */
+ note_data.reset (elfcore_write_prpsinfo (obfd, note_data.release (),
+ note_size, fname.c_str (),
+ psargs.c_str ()));
+ if (note_data == nullptr)
+ return nullptr;
+
+ /* Thread register information. */
+ try
+ {
+ update_thread_list ();
+ }
+ catch (const gdb_exception_error &e)
+ {
+ exception_print (gdb_stderr, e);
+ }
+
+ /* Like the Linux kernel, prefer dumping the signalled thread first.
+ "First thread" is what tools use to infer the signalled thread. */
+ thread_info *signalled_thr = gcore_find_signalled_thread ();
+
+ /* All threads are reported as having been stopped by the same signal
+ that stopped SIGNALLED_THR. */
+ gdb_signal stop_signal;
+ if (signalled_thr != nullptr)
+ stop_signal = signalled_thr->suspend.stop_signal;
+ else
+ stop_signal = GDB_SIGNAL_0;
+
+ if (signalled_thr != nullptr)
+ gcore_elf_build_thread_register_notes (gdbarch, signalled_thr,
+ stop_signal, obfd, &note_data,
+ note_size);
+ for (thread_info *thr : current_inferior ()->non_exited_threads ())
+ {
+ if (thr == signalled_thr)
+ continue;
+
+ gcore_elf_build_thread_register_notes (gdbarch, thr, stop_signal, obfd,
+ &note_data, note_size);
+ }
+
+
+ /* Target description. */
+ gcore_elf_make_tdesc_note (obfd, &note_data, note_size);
+
+ return note_data;
+}
+
+/* See none-tdep.h. */
+
+void
+elf_none_init_abi (struct gdbarch *gdbarch)
+{
+ /* Default core file support. */
+ set_gdbarch_make_corefile_notes (gdbarch, elf_none_make_corefile_notes);
+}
diff --git a/gdb/elf-none-tdep.h b/gdb/elf-none-tdep.h
new file mode 100644
index 0000000..9ce9a20
--- /dev/null
+++ b/gdb/elf-none-tdep.h
@@ -0,0 +1,30 @@
+/* Architecture independent code for ABI 'none' (bare-metal).
+
+ Copyright (C) 2021 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef NONE_TDEP_H
+#define NONE_TDEP_H
+
+struct gdbarch;
+
+/* Initialize support for cross-architecture features applicable for the
+ GDB_OSABI_NONE ABI, that is bare-metal targets. */
+
+void elf_none_init_abi (struct gdbarch *gdbarch);
+
+#endif /* NONE_TDEP_H */
diff --git a/gdb/riscv-none-tdep.c b/gdb/riscv-none-tdep.c
new file mode 100644
index 0000000..f1ac592
--- /dev/null
+++ b/gdb/riscv-none-tdep.c
@@ -0,0 +1,113 @@
+/* Copyright (C) 2020-2021 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* This file contain code that is specific for bare-metal RISC-V targets. */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "regcache.h"
+#include "riscv-tdep.h"
+#include "elf-bfd.h"
+#include "regset.h"
+
+#ifdef HAVE_ELF
+#include "elf-none-tdep.h"
+#endif
+
+/* Define the general register mapping. This follows the same format as
+ the RISC-V linux corefile. The linux kernel puts the PC at offset 0,
+ gdb puts it at offset 32. Register x0 is always 0 and can be ignored.
+ Registers x1 to x31 are in the same place. */
+
+static const struct regcache_map_entry riscv_gregmap[] =
+{
+ { 1, RISCV_PC_REGNUM, 0 },
+ { 31, RISCV_RA_REGNUM, 0 }, /* x1 to x31 */
+ { 0 }
+};
+
+/* Define the FP register mapping. This follows the same format as the
+ RISC-V linux corefile. The kernel puts the 32 FP regs first, and then
+ FCSR. */
+
+static const struct regcache_map_entry riscv_fregmap[] =
+{
+ { 32, RISCV_FIRST_FP_REGNUM, 0 },
+ { 1, RISCV_CSR_FCSR_REGNUM, 4 }, /* Always stored as 4-bytes. */
+ { 0 }
+};
+
+/* Define the general register regset. */
+
+static const struct regset riscv_gregset =
+{
+ riscv_gregmap, riscv_supply_regset, regcache_collect_regset
+};
+
+/* Define the FP register regset. */
+
+static const struct regset riscv_fregset =
+{
+ riscv_fregmap, riscv_supply_regset, regcache_collect_regset
+};
+
+/* Implement the "iterate_over_regset_sections" gdbarch method. */
+
+static void
+riscv_iterate_over_regset_sections (struct gdbarch *gdbarch,
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
+{
+ /* Write out the GPRs. */
+ int sz = 32 * riscv_isa_xlen (gdbarch);
+ cb (".reg", sz, sz, &riscv_gregset, NULL, cb_data);
+
+ /* Write out the FPRs, but only if present. */
+ if (riscv_isa_flen (gdbarch) > 0)
+ {
+ sz = (32 * riscv_isa_flen (gdbarch)
+ + register_size (gdbarch, RISCV_CSR_FCSR_REGNUM));
+ cb (".reg2", sz, sz, &riscv_fregset, NULL, cb_data);
+ }
+}
+
+/* Initialize RISC-V bare-metal ABI info. */
+
+static void
+riscv_none_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+#ifdef HAVE_ELF
+ elf_none_init_abi (gdbarch);
+#endif
+
+ /* Iterate over registers for reading and writing bare metal RISC-V core
+ files. */
+ set_gdbarch_iterate_over_regset_sections
+ (gdbarch, riscv_iterate_over_regset_sections);
+
+}
+
+/* Initialize RISC-V bare-metal target support. */
+
+void _initialize_riscv_none_tdep ();
+void
+_initialize_riscv_none_tdep ()
+{
+ gdbarch_register_osabi (bfd_arch_riscv, 0, GDB_OSABI_NONE,
+ riscv_none_init_abi);
+}