aboutsummaryrefslogtreecommitdiff
path: root/gdb/fbsd-tdep.c
diff options
context:
space:
mode:
authorAndreas Arnez <arnez@linux.vnet.ibm.com>2013-12-03 11:35:35 +0000
committerAndreas Krebbel <krebbel@linux.vnet.ibm.com>2014-09-30 09:14:33 +0200
commita904c024b0760911288e865c62d91578fd887e3b (patch)
tree382b519df903251ba5dc81113b0b3532c9bbb02f /gdb/fbsd-tdep.c
parent8f0435f75e3c9676d2e177ce055fed3155fd9476 (diff)
downloadgdb-a904c024b0760911288e865c62d91578fd887e3b.zip
gdb-a904c024b0760911288e865c62d91578fd887e3b.tar.gz
gdb-a904c024b0760911288e865c62d91578fd887e3b.tar.bz2
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.
Diffstat (limited to 'gdb/fbsd-tdep.c')
-rw-r--r--gdb/fbsd-tdep.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/gdb/fbsd-tdep.c b/gdb/fbsd-tdep.c
new file mode 100644
index 0000000..a60fbc2
--- /dev/null
+++ b/gdb/fbsd-tdep.c
@@ -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);
+}