126 lines
3.9 KiB
C
126 lines
3.9 KiB
C
/* Common code for targets with the none ABI (bare-metal), but where the
|
|
BFD library is build with ELF support.
|
|
|
|
Copyright (C) 2020-2022 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 std::string &infargs = current_inferior ()->args ();
|
|
if (!infargs.empty ())
|
|
psargs += ' ' + 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->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);
|
|
}
|