[03/26] Add multi-arch capable 'fbsd_make_corefile_notes' variant

Message ID 1410536396-25524-4-git-send-email-arnez@linux.vnet.ibm.com
State New, archived
Headers

Commit Message

Andreas Arnez Sept. 12, 2014, 3:39 p.m. UTC
  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.
---
 gdb/Makefile.in |   4 +-
 gdb/fbsd-tdep.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 gdb/fbsd-tdep.h |  25 +++++++++++
 3 files changed, 165 insertions(+), 1 deletion(-)
 create mode 100644 gdb/fbsd-tdep.c
 create mode 100644 gdb/fbsd-tdep.h
  

Patch

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index f6b9176..409f5fa 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -625,6 +625,7 @@  ALL_TARGET_OBS = \
 	bfin-linux-tdep.o bfin-tdep.o \
 	cris-linux-tdep.o cris-tdep.o \
 	dicos-tdep.o \
+	fbsd-tdep.o \
 	frv-linux-tdep.o frv-tdep.o \
 	h8300-tdep.o \
 	hppabsd-tdep.o hppanbsd-tdep.o hppaobsd-tdep.o \
@@ -938,7 +939,7 @@  target/wait.h target/waitstatus.h nat/linux-nat.h nat/linux-waitpid.h \
 common/print-utils.h common/rsp-low.h nat/x86-dregs.h x86-linux-nat.h \
 i386-linux-nat.h common/common-defs.h common/errors.h common/common-types.h \
 common/common-debug.h common/cleanups.h common/gdb_setjmp.h \
-common/common-exceptions.h target/target.h common/symbol.h
+common/common-exceptions.h target/target.h common/symbol.h fbsd-tdep.h
 
 # Header files that already have srcdir in them, or which are in objdir.
 
@@ -1621,6 +1622,7 @@  ALLDEPFILES = \
 	dcache.c dicos-tdep.c darwin-nat.c \
 	exec.c \
 	fbsd-nat.c \
+	fbsd-tdep.c \
 	fork-child.c \
 	glibc-tdep.c \
 	go32-nat.c h8300-tdep.c \
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);
+}
diff --git a/gdb/fbsd-tdep.h b/gdb/fbsd-tdep.h
new file mode 100644
index 0000000..0a592ae
--- /dev/null
+++ b/gdb/fbsd-tdep.h
@@ -0,0 +1,25 @@ 
+/* Target-dependent code for FreeBSD, architecture independent.
+
+   Copyright (C) 2009-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/>.  */
+
+#ifndef FBSD_TDEP_H
+#define FBSD_TDEP_H
+
+extern void fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch);
+
+#endif /* fbsd-tdep.h */