* dw2gencfi.c, dw2gencfi.h: New files.
[binutils-gdb.git] / gdb / x86-64-linux-nat.c
index fd9246c2ea7d1fd4c9a2c871f5da31b3b8e802f0..044236ce320003ca3891a2ecbe981b71f571d7f8 100644 (file)
@@ -1,6 +1,6 @@
 /* Native-dependent code for GNU/Linux x86-64.
 
-   Copyright 2001, 2002 Free Software Foundation, Inc.
+   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
 
    Contributed by Jiri Smid, SuSE Labs.
 
@@ -25,8 +25,8 @@
 #include "inferior.h"
 #include "gdbcore.h"
 #include "regcache.h"
-#include "i387-nat.h"
 #include "gdb_assert.h"
+#include "gdb_string.h"
 #include "x86-64-tdep.h"
 
 #include <sys/ptrace.h>
@@ -43,7 +43,7 @@ static int x86_64_regmap[] = {
   RSI, RDI, RBP, RSP,
   R8, R9, R10, R11,
   R12, R13, R14, R15,
-  RIP, EFLAGS,
+  RIP, EFLAGS, CS, SS, 
   DS, ES, FS, GS
 };
 
@@ -158,7 +158,7 @@ fill_gregset (elf_gregset_t * gregsetp, int regno)
 
   for (i = 0; i < x86_64_num_gregs; i++)
     if ((regno == -1 || regno == i))
-      read_register_gen (i, (char *) (regp + x86_64_regmap[i]));
+      regcache_collect (i, (char *) (regp + x86_64_regmap[i]));
 }
 
 /* Fetch all general-purpose registers from process/thread TID and
@@ -195,23 +195,73 @@ store_regs (int tid, int regno)
 
 /* Transfering floating-point registers between GDB, inferiors and cores.  */
 
-/* Fill GDB's register array with the floating-point register values in
-   *FPREGSETP.  */
+static void *
+x86_64_fxsave_offset (elf_fpregset_t * fxsave, int regnum)
+{
+  const char *reg_name;
+  int reg_index;
+
+  gdb_assert (x86_64_num_gregs - 1 < regnum && regnum < x86_64_num_regs);
+
+  reg_name = x86_64_register_name (regnum);
+
+  if (reg_name[0] == 's' && reg_name[1] == 't')
+    {
+      reg_index = reg_name[2] - '0';
+      return &fxsave->st_space[reg_index * 2];
+    }
+
+  if (reg_name[0] == 'x' && reg_name[1] == 'm' && reg_name[2] == 'm')
+    {
+      reg_index = reg_name[3] - '0';
+      return &fxsave->xmm_space[reg_index * 4];
+    }
+
+  if (strcmp (reg_name, "mxcsr") == 0)
+    return &fxsave->mxcsr;
+
+  return NULL;
+}
+
+/* Fill GDB's register array with the floating-point and SSE register
+   values in *FXSAVE.  This function masks off any of the reserved
+   bits in *FXSAVE.  */
 
 void
-supply_fpregset (elf_fpregset_t * fpregsetp)
+supply_fpregset (elf_fpregset_t * fxsave)
 {
-  i387_supply_fxsave ((char *) fpregsetp);
+  int i, reg_st0, reg_mxcsr;
+
+  reg_st0 = x86_64_register_number ("st0");
+  reg_mxcsr = x86_64_register_number ("mxcsr");
+
+  gdb_assert (reg_st0 > 0 && reg_mxcsr > reg_st0);
+
+  for (i = reg_st0; i <= reg_mxcsr; i++)
+    supply_register (i, x86_64_fxsave_offset (fxsave, i));
 }
 
-/* Fill register REGNO (if it is a floating-point register) in
-   *FPREGSETP with the value in GDB's register array.  If REGNO is -1,
-   do this for all registers.  */
+/* Fill register REGNUM (if it is a floating-point or SSE register) in
+   *FXSAVE with the value in GDB's register array.  If REGNUM is -1, do
+   this for all registers.  This function doesn't touch any of the
+   reserved bits in *FXSAVE.  */
 
 void
-fill_fpregset (elf_fpregset_t * fpregsetp, int regno)
+fill_fpregset (elf_fpregset_t * fxsave, int regnum)
 {
-  i387_fill_fxsave ((char *) fpregsetp, regno);
+  int i, last_regnum = MXCSR_REGNUM;
+  void *ptr;
+
+  if (gdbarch_tdep (current_gdbarch)->num_xmm_regs == 0)
+    last_regnum = FOP_REGNUM;
+
+  for (i = FP0_REGNUM; i <= last_regnum; i++)
+    if (regnum == -1 || regnum == i)
+      {
+       ptr = x86_64_fxsave_offset (fxsave, i);
+       if (ptr)
+         regcache_collect (i, ptr);
+      }
 }
 
 /* Fetch all floating-point registers from process/thread TID and store
@@ -406,12 +456,6 @@ static struct core_fns linux_elf_core_fns = {
 #define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
 #endif
 
-/* Record the value of the debug control register.  */
-static long debug_control_mirror;
-
-/* Record which address associates with which register.  */
-static CORE_ADDR address_lookup[DR_LASTADDR - DR_FIRSTADDR + 1];
-
 /* Return the address of register REGNUM.  BLOCKEND is the value of
    u.u_ar0, which should point to the registers.  */
 CORE_ADDR