aboutsummaryrefslogtreecommitdiff
path: root/gdb/amd64obsd-tdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/amd64obsd-tdep.c')
-rw-r--r--gdb/amd64obsd-tdep.c65
1 files changed, 57 insertions, 8 deletions
diff --git a/gdb/amd64obsd-tdep.c b/gdb/amd64obsd-tdep.c
index 6ccf39f..be263d8 100644
--- a/gdb/amd64obsd-tdep.c
+++ b/gdb/amd64obsd-tdep.c
@@ -23,12 +23,54 @@
#include "frame.h"
#include "gdbcore.h"
#include "osabi.h"
+#include "regset.h"
#include "target.h"
#include "gdb_assert.h"
#include "gdb_string.h"
#include "x86-64-tdep.h"
+#include "i387-tdep.h"
+
+/* Support for core dumps. */
+
+static void
+amd64obsd_supply_regset (const struct regset *regset,
+ struct regcache *regcache, int regnum,
+ const void *regs, size_t len)
+{
+ const struct gdbarch_tdep *tdep = regset->descr;
+
+ gdb_assert (len >= tdep->sizeof_gregset + I387_SIZEOF_FXSAVE);
+
+ i386_supply_gregset (regset, regcache, regnum, regs, tdep->sizeof_gregset);
+ x86_64_supply_fxsave (regcache, regnum, (char *)regs + tdep->sizeof_gregset);
+}
+
+static const struct regset *
+amd64obsd_regset_from_core_section (struct gdbarch *gdbarch,
+ const char *sect_name, size_t sect_size)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ /* OpenBSD core dumps don't use seperate register sets for the
+ general-purpose and floating-point registers. */
+
+ if (strcmp (sect_name, ".reg") == 0
+ && sect_size >= tdep->sizeof_gregset + I387_SIZEOF_FXSAVE)
+ {
+ if (tdep->gregset == NULL)
+ {
+ tdep->gregset = XMALLOC (struct regset);
+ tdep->gregset->descr = tdep;
+ tdep->gregset->supply_regset = amd64obsd_supply_regset;
+ }
+ return tdep->gregset;
+ }
+
+ return NULL;
+}
+
/* Support for signal handlers. */
@@ -77,7 +119,7 @@ amd64obsd_sigcontext_addr (struct frame_info *next_frame)
/* Mapping between the general-purpose registers in `struct reg'
format and GDB's register cache layout. */
-/* From <machine/reg.h>. Used for ptrace(2), but not for core dumps. */
+/* From <machine/reg.h>. */
int amd64obsd_r_reg_offset[] =
{
14 * 8, /* %rax */
@@ -106,7 +148,7 @@ int amd64obsd_r_reg_offset[] =
23 * 8 /* %gs */
};
-/* From <machine/signal.h>. Also used for core dumps. */
+/* From <machine/signal.h>. */
static int amd64obsd_sc_reg_offset[] =
{
14 * 8, /* %rax */
@@ -140,13 +182,16 @@ amd64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- /* Initialize general-purpose register set details first. */
- tdep->gregset_reg_offset = amd64obsd_sc_reg_offset;
- tdep->gregset_num_regs = ARRAY_SIZE (amd64obsd_sc_reg_offset);
- tdep->sizeof_gregset = 26 * 8;
-
x86_64_init_abi (info, gdbarch);
+ /* Initialize general-purpose register set details. */
+ tdep->gregset_reg_offset = amd64obsd_r_reg_offset;
+ tdep->gregset_num_regs = ARRAY_SIZE (amd64obsd_r_reg_offset);
+ tdep->sizeof_gregset = 24 * 8;
+
+ set_gdbarch_regset_from_core_section (gdbarch,
+ amd64obsd_regset_from_core_section);
+
tdep->jb_pc_offset = 7 * 8;
set_gdbarch_pc_in_sigtramp (gdbarch, amd64obsd_pc_in_sigtramp);
@@ -160,11 +205,15 @@ amd64obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
void _initialize_amd64obsd_tdep (void);
void
-_initialize_amd64obsd_ndep (void)
+_initialize_amd64obsd_tdep (void)
{
/* The OpenBSD/amd64 native dependent code makes this assumption. */
gdb_assert (ARRAY_SIZE (amd64obsd_r_reg_offset) == X86_64_NUM_GREGS);
gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
GDB_OSABI_OPENBSD_ELF, amd64obsd_init_abi);
+
+ /* OpenBSD uses traditional (a.out) NetBSD-style core dumps. */
+ gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64,
+ GDB_OSABI_NETBSD_AOUT, amd64obsd_init_abi);
}