mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:51:15 +08:00
0a70e1a8a9
Calls of `get_exec_file (0)` are equivalent to just getting the exec filename from the current program space. I'm looking to remove `get_exec_file`, so replace these uses with `current_program_space->exec_filename ()`. Remove the `err` parameter of `get_exec_wrapper` since all the calls that remain pass 1, meaning to error out if no executable is specified. Change-Id: I7729ea4c7f03dbb046211cc5aa3858ab3a551965 Approved-By: Tom Tromey <tom@tromey.com>
131 lines
4.2 KiB
C
131 lines
4.2 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-2024 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 "elf-none-tdep.h"
|
|
#include "exceptions.h"
|
|
#include "regset.h"
|
|
#include "elf-bfd.h"
|
|
#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 (current_program_space->exec_filename () != nullptr)
|
|
{
|
|
const char *exe = current_program_space->exec_filename ();
|
|
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);
|
|
}
|
|
|
|
|
|
/* Include the target description when possible. Some architectures
|
|
allow for per-thread gdbarch so we should really be emitting a tdesc
|
|
per-thread, however, we don't currently support reading in a
|
|
per-thread tdesc, so just emit the tdesc for the signalled thread. */
|
|
gdbarch = target_thread_architecture (signalled_thr->ptid);
|
|
gcore_elf_make_tdesc_note (gdbarch, 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);
|
|
}
|