Add multi-arch capable 'fbsd_make_corefile_notes' variant
This creates a new version of the FreeBSD core file note generation logic in the new target-dependent file "fbsd-tdep.c". The new version is mostly copied from "fbsd-nat.c", but uses the iterator instead of regset_from_core_section and defines fbsd_make_corefile_notes as a gdbarch method instead of a target method. Consecutive architecture-dependent changes exploit the new version, migrating away from the target method. When all FreeBSD targets are changed, the target method can go away. gdb/ChangeLog: * fbsd-tdep.c: New file. * fbsd-tdep.h: New file. * Makefile.in (ALL_TARGET_OBS): Add fbsd-tdep.o. (HFILES_NO_SRCDIR): Add fbsd-tdep.h. (ALLDEPFILES): Add fbsd-tdep.c.
This commit is contained in:
parent
8f0435f75e
commit
a904c024b0
4 changed files with 173 additions and 1 deletions
137
gdb/fbsd-tdep.c
Normal file
137
gdb/fbsd-tdep.c
Normal file
|
@ -0,0 +1,137 @@
|
|||
/* Target-dependent code for FreeBSD, architecture-independent.
|
||||
|
||||
Copyright (C) 2002-2014 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 "gdbcore.h"
|
||||
#include "inferior.h"
|
||||
#include "regcache.h"
|
||||
#include "regset.h"
|
||||
#include "gdbthread.h"
|
||||
|
||||
#include "gdb_assert.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "elf-bfd.h"
|
||||
#include "fbsd-tdep.h"
|
||||
|
||||
|
||||
static int
|
||||
find_signalled_thread (struct thread_info *info, void *data)
|
||||
{
|
||||
if (info->suspend.stop_signal != GDB_SIGNAL_0
|
||||
&& ptid_get_pid (info->ptid) == ptid_get_pid (inferior_ptid))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum gdb_signal
|
||||
find_stop_signal (void)
|
||||
{
|
||||
struct thread_info *info =
|
||||
iterate_over_threads (find_signalled_thread, NULL);
|
||||
|
||||
if (info)
|
||||
return info->suspend.stop_signal;
|
||||
else
|
||||
return GDB_SIGNAL_0;
|
||||
}
|
||||
|
||||
struct fbsd_collect_regset_section_cb_data
|
||||
{
|
||||
const struct regcache *regcache;
|
||||
bfd *obfd;
|
||||
char *note_data;
|
||||
int *note_size;
|
||||
};
|
||||
|
||||
static void
|
||||
fbsd_collect_regset_section_cb (const char *sect_name, int size,
|
||||
const struct regset *regset,
|
||||
const char *human_name, void *cb_data)
|
||||
{
|
||||
char *buf;
|
||||
struct fbsd_collect_regset_section_cb_data *data = cb_data;
|
||||
|
||||
gdb_assert (regset->collect_regset);
|
||||
|
||||
buf = xmalloc (size);
|
||||
regset->collect_regset (regset, data->regcache, -1, buf, size);
|
||||
|
||||
/* PRSTATUS still needs to be treated specially. */
|
||||
if (strcmp (sect_name, ".reg") == 0)
|
||||
data->note_data = (char *) elfcore_write_prstatus
|
||||
(data->obfd, data->note_data, data->note_size,
|
||||
ptid_get_pid (inferior_ptid), find_stop_signal (), buf);
|
||||
else
|
||||
data->note_data = (char *) elfcore_write_register_note
|
||||
(data->obfd, data->note_data, data->note_size,
|
||||
sect_name, buf, size);
|
||||
xfree (buf);
|
||||
}
|
||||
|
||||
/* Create appropriate note sections for a corefile, returning them in
|
||||
allocated memory. */
|
||||
|
||||
static char *
|
||||
fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
|
||||
{
|
||||
const struct regcache *regcache = get_current_regcache ();
|
||||
char *note_data;
|
||||
Elf_Internal_Ehdr *i_ehdrp;
|
||||
struct fbsd_collect_regset_section_cb_data data;
|
||||
|
||||
/* Put a "FreeBSD" label in the ELF header. */
|
||||
i_ehdrp = elf_elfheader (obfd);
|
||||
i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
|
||||
|
||||
gdb_assert (gdbarch_iterate_over_regset_sections_p (gdbarch));
|
||||
|
||||
data.regcache = regcache;
|
||||
data.obfd = obfd;
|
||||
data.note_data = NULL;
|
||||
data.note_size = note_size;
|
||||
gdbarch_iterate_over_regset_sections (gdbarch,
|
||||
fbsd_collect_regset_section_cb,
|
||||
&data, regcache);
|
||||
note_data = data.note_data;
|
||||
|
||||
if (get_exec_file (0))
|
||||
{
|
||||
const char *fname = lbasename (get_exec_file (0));
|
||||
char *psargs = xstrdup (fname);
|
||||
|
||||
if (get_inferior_args ())
|
||||
psargs = reconcat (psargs, psargs, " ", get_inferior_args (),
|
||||
(char *) NULL);
|
||||
|
||||
note_data = elfcore_write_prpsinfo (obfd, note_data, note_size,
|
||||
fname, psargs);
|
||||
}
|
||||
|
||||
return note_data;
|
||||
}
|
||||
|
||||
/* To be called from GDB_OSABI_FREEBSD_ELF handlers. */
|
||||
|
||||
void
|
||||
fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
|
||||
{
|
||||
set_gdbarch_make_corefile_notes (gdbarch, fbsd_make_corefile_notes);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue