diff options
-rw-r--r-- | gdb/ChangeLog | 13 | ||||
-rw-r--r-- | gdb/Makefile.in | 4 | ||||
-rwxr-xr-x | gdb/configure | 3 | ||||
-rw-r--r-- | gdb/configure.ac | 3 | ||||
-rw-r--r-- | gdb/configure.tgt | 2 | ||||
-rw-r--r-- | gdb/elf-none-tdep.c | 126 | ||||
-rw-r--r-- | gdb/elf-none-tdep.h | 30 | ||||
-rw-r--r-- | gdb/riscv-none-tdep.c | 113 |
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, ¬e_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, + ¬e_data, note_size); + } + + + /* Target description. */ + gcore_elf_make_tdesc_note (obfd, ¬e_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); +} |