* server.c (get_features_xml): Check if target implemented
[deliverable/binutils-gdb.git] / gdb / gdbserver / linux-x86-64-low.c
index 4ee1ae48190af621c32058ab90bb3047258dc3e0..5951104d421d6118c132262533ba94a92ebe196b 100644 (file)
@@ -1,7 +1,6 @@
 /* GNU/Linux/x86-64 specific low level interface, for the remote server
    for GDB.
-   Copyright 2002
-   Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
    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.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include "server.h"
 #include "linux-low.h"
 #include "i387-fp.h"
 
+#include "gdb_proc_service.h"
+
 #include <sys/reg.h>
 #include <sys/procfs.h>
 #include <sys/ptrace.h>
 
+/* This definition comes from prctl.h, but some kernels may not have it.  */
+#ifndef PTRACE_ARCH_PRCTL
+#define PTRACE_ARCH_PRCTL      30
+#endif
+
+/* The following definitions come from prctl.h, but may be absent
+   for certain configurations.  */
+#ifndef ARCH_GET_FS
+#define ARCH_SET_GS 0x1001
+#define ARCH_SET_FS 0x1002
+#define ARCH_GET_FS 0x1003
+#define ARCH_GET_GS 0x1004
+#endif
+
 static int x86_64_regmap[] = {
   RAX * 8, RBX * 8, RCX * 8, RDX * 8,
   RSI * 8, RDI * 8, RBP * 8, RSP * 8,
   R8 * 8, R9 * 8, R10 * 8, R11 * 8,
   R12 * 8, R13 * 8, R14 * 8, R15 * 8,
   RIP * 8, EFLAGS * 8, CS * 8, SS * 8, 
-  DS * 8, ES * 8, FS * 8, GS * 8
+  DS * 8, ES * 8, FS * 8, GS * 8,
+  -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  ORIG_RAX * 8
 };
 
 #define X86_64_NUM_GREGS (sizeof(x86_64_regmap)/sizeof(int))
 
+/* Called by libthread_db.  */
+
+ps_err_e
+ps_get_thread_area (const struct ps_prochandle *ph,
+                    lwpid_t lwpid, int idx, void **base)
+{
+  switch (idx)
+    {
+    case FS:
+      if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_FS) == 0)
+       return PS_OK;
+      break;
+    case GS:
+      if (ptrace (PTRACE_ARCH_PRCTL, lwpid, base, ARCH_GET_GS) == 0)
+       return PS_OK;
+      break;
+    default:
+      return PS_BADADDR;
+    }
+  return PS_ERR;
+}
+
 static void
 x86_64_fill_gregset (void *buf)
 {
   int i;
 
   for (i = 0; i < X86_64_NUM_GREGS; i++)
-    collect_register (i, ((char *) buf) + x86_64_regmap[i]);
+    if (x86_64_regmap[i] != -1)
+      collect_register (i, ((char *) buf) + x86_64_regmap[i]);
 }
 
 static void
@@ -54,7 +97,8 @@ x86_64_store_gregset (const void *buf)
   int i;
 
   for (i = 0; i < X86_64_NUM_GREGS; i++)
-    supply_register (i, ((char *) buf) + x86_64_regmap[i]);
+    if (x86_64_regmap[i] != -1)
+      supply_register (i, ((char *) buf) + x86_64_regmap[i]);
 }
 
 static void
@@ -79,9 +123,59 @@ struct regset_info target_regsets[] = {
   { 0, 0, -1, -1, NULL, NULL }
 };
 
+static const unsigned char x86_64_breakpoint[] = { 0xCC };
+#define x86_64_breakpoint_len 1
+                
+extern int debug_threads;
+
+static CORE_ADDR
+x86_64_get_pc ()
+{
+  unsigned long pc;
+
+  collect_register_by_name ("rip", &pc);
+
+  if (debug_threads)
+    fprintf (stderr, "stop pc (before any decrement) is %08lx\n", pc);
+  return pc;
+}
+
+static void
+x86_64_set_pc (CORE_ADDR newpc)
+{
+  if (debug_threads)
+    fprintf (stderr, "set pc to %08lx\n", (long) newpc);
+  supply_register_by_name ("rip", &newpc);
+}
+
+static int
+x86_64_breakpoint_at (CORE_ADDR pc)
+{
+  unsigned char c;
+
+  read_inferior_memory (pc, &c, 1);
+  if (c == 0xCC)
+    return 1;
+
+  return 0;
+}
+
 struct linux_target_ops the_low_target = {
   -1,
   NULL,
   NULL,
   NULL,
+  x86_64_get_pc,
+  x86_64_set_pc,
+  x86_64_breakpoint,  
+  x86_64_breakpoint_len,
+  NULL,                                 
+  1,
+  x86_64_breakpoint_at,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  0,
+  "i386:x86-64",
 };
This page took 0.02525 seconds and 4 git commands to generate.