aboutsummaryrefslogtreecommitdiff
path: root/gdb/elf-none-tdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/elf-none-tdep.c')
-rw-r--r--gdb/elf-none-tdep.c126
1 files changed, 126 insertions, 0 deletions
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);
+}