Add multi-arch capable 'fbsd_make_corefile_notes' variant
authorAndreas Arnez <arnez@linux.vnet.ibm.com>
Tue, 3 Dec 2013 11:35:35 +0000 (11:35 +0000)
committerAndreas Krebbel <krebbel@linux.vnet.ibm.com>
Tue, 30 Sep 2014 07:14:33 +0000 (09:14 +0200)
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/ChangeLog
gdb/Makefile.in
gdb/fbsd-tdep.c [new file with mode: 0644]
gdb/fbsd-tdep.h [new file with mode: 0644]

index 522849ada3c2f41c372a5c5bf46e1903a109ac92..274bf51306804fde6fe27e18b7bf2d00dc3e3097 100644 (file)
@@ -1,3 +1,11 @@
+2014-09-30  Andreas Arnez  <arnez@linux.vnet.ibm.com>
+
+       * 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.
+
 2014-09-30  Andreas Arnez  <arnez@linux.vnet.ibm.com>
 
        * gdbarch.sh (iterate_over_regset_sections_cb): Add regset
index cbec0d204f157bed3fc02414a26f4805e73b1a3b..1ffa62a8705afac1ecab42995612a906dfcadcef 100644 (file)
@@ -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 \
@@ -939,7 +940,7 @@ 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-regcache.h
+common/common-regcache.h fbsd-tdep.h
 
 # Header files that already have srcdir in them, or which are in objdir.
 
@@ -1622,6 +1623,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 (file)
index 0000000..a60fbc2
--- /dev/null
@@ -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 (file)
index 0000000..0a592ae
--- /dev/null
@@ -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 */