* amd64-nat.h: New file.
authorMark Kettenis <kettenis@gnu.org>
Fri, 29 Aug 2003 13:58:26 +0000 (13:58 +0000)
committerMark Kettenis <kettenis@gnu.org>
Fri, 29 Aug 2003 13:58:26 +0000 (13:58 +0000)
* amd64-nat.c: New file.
* amd64fbsd-nat.c: Include "amd64-nat.h".
(REG_ADDR, GETREGS_SUPPLIES): Remove macros.
(amd64fbsd32_r_reg_offset): New variable.
(supply_gregset): Simply call amd64_supply_native_gregset.
(fill_gregset): Rename `regno' to `regnum'.  Simply call
amd64_collect_native_gregset.
(fill_fpregset): Rename `regno' to `regnum'.
(fetch_inferior_registers): Rename `regno' to `regnum'.  Replace
usage of GETREGS_SUPPLIES with amd64_native_gregset_supplies_p.
Use `struct reg' and `struct fpreg' instead of `gregset_t' and
`fpregset_t'.  Call amd64_supply_native_gregset instead of
supply_gregset.  Call x86_64_supply_fxsave instead of
supply_fpregset.
(store_inferior_registers): Rename `regno' to `regnum'.  Replace
usage of GETREGS_SUPPLIES with amd64_native_gregset_supplies_p.
Use `struct reg' and `struct fpreg' instead of `gregset_t' and
`fpregset_t'.  Call amd64_collect_native_gregset instead of
fill_gregset.  Call x86_64_collect_fxsave instead of
fill_fpregset.
(_initialize_am64fbsd_nat): Initialize
amd64_native_gregset32_reg_offset and
amd64_native_gregset64_reg_offset.
* config/i386/fbsd64.mh (NATDEPFILES): Add amd64-nat.o.

gdb/ChangeLog
gdb/amd64-nat.c [new file with mode: 0644]
gdb/amd64-nat.h [new file with mode: 0644]
gdb/amd64fbsd-nat.c
gdb/config/i386/fbsd64.mh

index e7d670d7bf63218f75d3f2abdf5e36d08b9153b6..4bd50aa8aac129533ba10330b29d17adf8979920 100644 (file)
@@ -1,5 +1,31 @@
 2003-08-29  Mark Kettenis  <kettenis@gnu.org>
 
+       * amd64-nat.h: New file.
+       * amd64-nat.c: New file.
+       * amd64fbsd-nat.c: Include "amd64-nat.h".
+       (REG_ADDR, GETREGS_SUPPLIES): Remove macros.
+       (amd64fbsd32_r_reg_offset): New variable.
+       (supply_gregset): Simply call amd64_supply_native_gregset.
+       (fill_gregset): Rename `regno' to `regnum'.  Simply call
+       amd64_collect_native_gregset.
+       (fill_fpregset): Rename `regno' to `regnum'.
+       (fetch_inferior_registers): Rename `regno' to `regnum'.  Replace
+       usage of GETREGS_SUPPLIES with amd64_native_gregset_supplies_p.
+       Use `struct reg' and `struct fpreg' instead of `gregset_t' and
+       `fpregset_t'.  Call amd64_supply_native_gregset instead of
+       supply_gregset.  Call x86_64_supply_fxsave instead of
+       supply_fpregset.
+       (store_inferior_registers): Rename `regno' to `regnum'.  Replace
+       usage of GETREGS_SUPPLIES with amd64_native_gregset_supplies_p.
+       Use `struct reg' and `struct fpreg' instead of `gregset_t' and
+       `fpregset_t'.  Call amd64_collect_native_gregset instead of
+       fill_gregset.  Call x86_64_collect_fxsave instead of
+       fill_fpregset.
+       (_initialize_am64fbsd_nat): Initialize
+       amd64_native_gregset32_reg_offset and
+       amd64_native_gregset64_reg_offset.
+       * config/i386/fbsd64.mh (NATDEPFILES): Add amd64-nat.o.
+
        * regcache.c (regcache_raw_supply): Don't assert that BUF isn't a
        null pointer.  Fix typo in comment.
 
diff --git a/gdb/amd64-nat.c b/gdb/amd64-nat.c
new file mode 100644 (file)
index 0000000..fb0efcf
--- /dev/null
@@ -0,0 +1,144 @@
+/* Native-dependent code for AMD64.
+
+   Copyright 2003 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include "defs.h"
+#include "gdbarch.h"
+#include "regcache.h"
+
+#include "gdb_assert.h"
+
+#include "i386-tdep.h"
+#include "x86-64-tdep.h"
+
+/* The following bits of code help with implementing debugging 32-bit
+   code natively on AMD64.  The idea is to define two mappings between
+   the register number as used by GDB and the register set used by the
+   host to represent the general-purpose registers; one for 32-bit
+   code and one for 64-bit code.  The mappings are specified by the
+   follwing variables and consist of an array of offsets within the
+   register set indexed by register number, and the number of
+   registers supported by the mapping.  We don't need mappings for the
+   floating-point and SSE registers, since the difference between
+   64-bit and 32-bit variants are negligable.  The difference in the
+   number of SSE registers is already handled by the target code.  */
+
+/* General-purpose register mapping for native 32-bit code.  */
+int *amd64_native_gregset32_reg_offset;
+int amd64_native_gregset32_num_regs = I386_NUM_GREGS;
+
+/* General-purpose register mapping for native 64-bit code.  */
+int *amd64_native_gregset64_reg_offset;
+int amd64_native_gregset64_num_regs = X86_64_NUM_GREGS;
+
+/* Return the offset of REGNUM within the appropriate native
+   general-purpose register set.  */
+
+static int
+amd64_native_gregset_reg_offset (int regnum)
+{
+  int *reg_offset = amd64_native_gregset64_reg_offset;
+  int num_regs = amd64_native_gregset64_num_regs;
+
+  gdb_assert (regnum >= 0);
+
+  if (gdbarch_ptr_bit (current_gdbarch) == 32)
+    {
+      reg_offset = amd64_native_gregset32_reg_offset;
+      num_regs = amd64_native_gregset32_num_regs;
+    }
+
+  if (num_regs > NUM_REGS)
+    num_regs = NUM_REGS;
+
+  if (regnum < num_regs && regnum < NUM_REGS)
+    return reg_offset[regnum];
+
+  return -1;
+}
+
+/* Return whether the native general-purpose register set supplies
+   register REGNUM.  */
+
+int
+amd64_native_gregset_supplies_p (int regnum)
+{
+  return (amd64_native_gregset_reg_offset (regnum) != -1);
+}
+
+
+/* Supply register REGNUM, whose contents are store in BUF, to
+   REGCACHE.  If REGNUM is -1, supply all appropriate registers.  */
+
+void
+amd64_supply_native_gregset (struct regcache *regcache,
+                            const void *gregs, int regnum)
+{
+  const char *regs = gregs;
+  int num_regs = amd64_native_gregset64_num_regs;
+  int i;
+
+  if (gdbarch_ptr_bit (current_gdbarch) == 32)
+    num_regs = amd64_native_gregset32_num_regs;
+
+  if (num_regs > NUM_REGS)
+    num_regs = NUM_REGS;
+
+  for (i = 0; i < num_regs; i++)
+    {
+      if (regnum == -1 || regnum == i)
+       {
+         int offset = amd64_native_gregset_reg_offset (i);
+
+         if (offset != -1)
+           regcache_raw_supply (current_regcache, i, regs + offset);
+       }
+    }
+}
+
+/* Collect register REGNUM from REGCACHE and store its contents in
+   GREGS.  If REGNUM is -1, collect and store all appropriate
+   registers.  */
+
+void
+amd64_collect_native_gregset (const struct regcache *regcache,
+                             void *gregs, int regnum)
+{
+  char *regs = gregs;
+  int num_regs = amd64_native_gregset64_num_regs;
+  int i;
+
+  if (gdbarch_ptr_bit (current_gdbarch) == 32)
+    num_regs = amd64_native_gregset32_num_regs;
+
+  if (num_regs > NUM_REGS)
+    num_regs = NUM_REGS;
+
+  for (i = 0; i < num_regs; i++)
+    {
+      if (regnum == -1 || regnum == i)
+       {
+         int offset = amd64_native_gregset_reg_offset (i);
+
+         if (offset != -1)
+           regcache_raw_collect (current_regcache, i, regs + offset);
+       }
+    }
+}
diff --git a/gdb/amd64-nat.h b/gdb/amd64-nat.h
new file mode 100644 (file)
index 0000000..e2c9379
--- /dev/null
@@ -0,0 +1,51 @@
+/* Native-dependent code for AMD64.
+
+   Copyright 2003 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 2 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, write to the Free Software
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef AMD64_NAT_H
+#define AMD64_NAT_H 1
+
+/* General-purpose register set description for native 32-bit code.  */
+extern int *amd64_native_gregset32_reg_offset;
+extern int amd64_native_gregset32_num_regs;
+
+/* General-purpose register set description for native 64-bit code.  */
+extern int *amd64_native_gregset64_reg_offset;
+extern int amd64_native_gregset64_num_regs;
+
+/* Return whether the native general-purpose register set supplies
+   register REGNUM.  */
+
+extern int amd64_native_gregset_supplies_p (int regnum);
+
+/* Supply register REGNUM, whose contents are store in BUF, to
+   REGCACHE.  If REGNUM is -1, supply all appropriate registers.  */
+
+extern void amd64_supply_native_gregset (struct regcache *regcache,
+                                        const void *gregs, int regnum);
+
+/* Collect register REGNUM from REGCACHE and store its contents in
+   GREGS.  If REGNUM is -1, collect and store all appropriate
+   registers.  */
+
+extern void amd64_collect_native_gregset (const struct regcache *regcache,
+                                         void *gregs, int regnum);
+
+#endif /* amd64-nat.h */
index e90d8fac061fae470ba58b8a67f83e7bc56ddac0..dee2c8dea1ae8ec41a25abd87987f0656c9d4ed9 100644 (file)
@@ -1,4 +1,5 @@
 /* Native-dependent code for FreeBSD/amd64.
+
    Copyright 2003 Free Software Foundation, Inc.
 
    This file is part of GDB.
@@ -44,13 +45,14 @@ typedef struct fpreg fpregset_t;
 
 #include "gregset.h"
 #include "x86-64-tdep.h"
+#include "amd64-nat.h"
 \f
 
 /* Offset to the gregset_t location where REG is stored.  */
 #define REG_OFFSET(reg) offsetof (gregset_t, reg)
 
-/* At reg_offset[REGNO] you'll find the offset to the gregset_t
-   location where the GDB register REGNO is stored.  Unsupported
+/* At reg_offset[REGNUM] you'll find the offset to the gregset_t
+   location where the GDB register REGNUM is stored.  Unsupported
    registers are marked with `-1'.  */
 static int reg_offset[] =
 {
@@ -77,12 +79,27 @@ static int reg_offset[] =
   -1,
   -1
 };
+\f
+
+/* Mapping between the general-purpose registers in FreeBSD/amd64
+   `struct reg' format and GDB's register cache layout for
+   FreeBSD/i386.
 
-#define REG_ADDR(regset, regno) ((char *) (regset) + reg_offset[regno])
+   Note that most FreeBSD/amd64 registers are 64-bit, while the
+   FreeBSD/i386 registers are all 32-bit, but since we're
+   little-endian we get away with that.  */
 
-/* Macro to determine if a register is fetched with PT_GETREGS.  */
-#define GETREGS_SUPPLIES(regno) \
-  ((0 <= (regno) && (regno) < X86_64_NUM_GREGS))
+/* From <machine/reg.h>.  */
+static int amd64fbsd32_r_reg_offset[I386_NUM_GREGS] =
+{
+  14 * 8, 13 * 8,              /* %eax, %ecx */
+  12 * 8, 11 * 8,              /* %edx, %ebx */
+  20 * 8, 10 * 8,              /* %esp, %ebp */
+  9 * 8, 8 * 8,                        /* %esi, %edi */
+  17 * 8, 19 * 8,              /* %eip, %eflags */
+  18 * 8, 21 * 8,              /* %cs, %ss */
+  -1, -1, -1, -1               /* %ds, %es, %fs, %gs */
+};
 \f
 
 /* Transfering the registers between GDB, inferiors and core files.  */
@@ -93,29 +110,17 @@ static int reg_offset[] =
 void
 supply_gregset (gregset_t *gregsetp)
 {
-  int i;
-
-  for (i = 0; i < X86_64_NUM_GREGS; i++)
-    {
-      if (reg_offset[i] == -1)
-       supply_register (i, NULL);
-      else
-       supply_register (i, REG_ADDR (gregsetp, i));
-    }
+  amd64_supply_native_gregset (current_regcache, gregsetp, -1);
 }
 
-/* Fill register REGNO (if it is a general-purpose register) in
-   *GREGSETPS with the value in GDB's register array.  If REGNO is -1,
+/* Fill register REGNUM (if it is a general-purpose register) in
+   *GREGSETPS with the value in GDB's register array.  If REGNUM is -1,
    do this for all registers.  */
 
 void
-fill_gregset (gregset_t *gregsetp, int regno)
+fill_gregset (gregset_t *gregsetp, int regnum)
 {
-  int i;
-
-  for (i = 0; i < X86_64_NUM_GREGS; i++)
-    if ((regno == -1 || regno == i) && reg_offset[i] != -1)
-      regcache_collect (i, REG_ADDR (gregsetp, i));
+  amd64_collect_native_gregset (current_regcache, gregsetp, regnum);
 }
 
 /* Fill GDB's register array with the floating-point register values
@@ -127,80 +132,80 @@ supply_fpregset (fpregset_t *fpregsetp)
   x86_64_supply_fxsave ((const char *) fpregsetp, -1);
 }
 
-/* Fill register REGNO (if it is a floating-point register) in
-   *FPREGSETP with the value in GDB's register array.  If REGNO is -1,
+/* Fill register REGNUM (if it is a floating-point register) in
+   *FPREGSETP with the value in GDB's register array.  If REGNUM is -1,
    do this for all registers.  */
 
 void
-fill_fpregset (fpregset_t *fpregsetp, int regno)
+fill_fpregset (fpregset_t *fpregsetp, int regnum)
 {
-  x86_64_fill_fxsave ((char *) fpregsetp, regno);
+  x86_64_fill_fxsave ((char *) fpregsetp, regnum);
 }
 
-/* Fetch register REGNO from the inferior.  If REGNO is -1, do this
+/* Fetch register REGNUM from the inferior.  If REGNUM is -1, do this
    for all registers (including the floating point registers).  */
 
 void
-fetch_inferior_registers (int regno)
+fetch_inferior_registers (int regnum)
 {
-  if (regno == -1 || GETREGS_SUPPLIES (regno))
+  if (regnum == -1 || amd64_native_gregset_supplies_p (regnum))
     {
-      gregset_t gregs;
+      struct reg regs;
 
       if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
-                 (PTRACE_ARG3_TYPE) &gregs, 0) == -1)
+                 (PTRACE_ARG3_TYPE) &regs, 0) == -1)
        perror_with_name ("Couldn't get registers");
 
-      supply_gregset (&gregs);
-      if (regno != -1)
+      amd64_supply_native_gregset (current_regcache, &regs, -1);
+      if (regnum != -1)
        return;
     }
 
-  if (regno == -1 || regno >= FP0_REGNUM)
+  if (regnum == -1 || regnum >= FP0_REGNUM)
     {
-      fpregset_t fpregs;
+      struct fpreg fpregs;
 
       if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
                  (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
        perror_with_name ("Couldn't get floating point status");
 
-      supply_fpregset (&fpregs);
+      x86_64_supply_fxsave ((const char *) &fpregs, -1);
     }
 }
 
-/* Store register REGNO back into the inferior.  If REGNO is -1, do
+/* Store register REGNUM back into the inferior.  If REGNUM is -1, do
    this for all registers (including the floating point registers).  */
 
 void
-store_inferior_registers (int regno)
+store_inferior_registers (int regnum)
 {
-  if (regno == -1 || GETREGS_SUPPLIES (regno))
+  if (regnum == -1 || amd64_native_gregset_supplies_p (regnum))
     {
-      gregset_t gregs;
+      struct reg regs;
 
       if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
-                  (PTRACE_ARG3_TYPE) &gregs, 0) == -1)
+                  (PTRACE_ARG3_TYPE) &regs, 0) == -1)
         perror_with_name ("Couldn't get registers");
 
-      fill_gregset (&gregs, regno);
+      amd64_collect_native_gregset (current_regcache, &regs, regnum);
 
       if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
-                 (PTRACE_ARG3_TYPE) &gregs, 0) == -1)
+                 (PTRACE_ARG3_TYPE) &regs, 0) == -1)
         perror_with_name ("Couldn't write registers");
 
-      if (regno != -1)
+      if (regnum != -1)
        return;
     }
 
-  if (regno == -1 || regno >= FP0_REGNUM)
+  if (regnum == -1 || regnum >= FP0_REGNUM)
     {
-      fpregset_t fpregs;
+      struct fpreg fpregs;
 
       if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
                  (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
        perror_with_name ("Couldn't get floating point status");
 
-      fill_fpregset (&fpregs, regno);
+      x86_64_fill_fxsave ((char *) &fpregs, regnum);
 
       if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
                  (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
@@ -217,6 +222,9 @@ _initialize_am64fbsd_nat (void)
 {
   int offset;
 
+  amd64_native_gregset32_reg_offset = amd64fbsd32_r_reg_offset;
+  amd64_native_gregset64_reg_offset = reg_offset;
+
   /* To support the recognition of signal handlers, i386bsd-tdep.c
      hardcodes some constants.  Inclusion of this file means that we
      are compiling a native debugger, which means that we can use the
index a1a79a33499bfa5501209f687284fbb7da29dae0..7e42aaa2cd62eb78f7eb60df4a384af3f58e4e1f 100644 (file)
@@ -4,4 +4,4 @@ XM_FILE= xm-i386.h
 
 NAT_FILE= nm-fbsd64.h
 # NOTE: Do not spread NATDEPFILES over several lines - it hurts BSD make.
-NATDEPFILES= fork-child.o infptrace.o inftarg.o solib.o solib-svr4.o solib-legacy.o corelow.o core-regset.o amd64fbsd-nat.o gcore.o fbsd-proc.o
+NATDEPFILES= fork-child.o infptrace.o inftarg.o solib.o solib-svr4.o solib-legacy.o corelow.o core-regset.o amd64-nat.o amd64fbsd-nat.o gcore.o fbsd-proc.o