[gdbserver] Disable conditional breakpoints on no-hardware-single-step targets
[deliverable/binutils-gdb.git] / gdb / gdbserver / spu-low.c
index d9ac815d20ff726c3adb29b33a5682a99e2ea353..a56a8893c4a3179b22a73025121e4f17653e451f 100644 (file)
@@ -1,5 +1,5 @@
 /* Low level interface to SPUs, for the remote server for GDB.
-   Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 2006-2015 Free Software Foundation, Inc.
 
    Contributed by Ulrich Weigand <uweigand@de.ibm.com>.
 
 
 #include "server.h"
 
-#include <sys/wait.h>
-#include <stdio.h>
+#include "gdb_wait.h"
 #include <sys/ptrace.h>
 #include <fcntl.h>
-#include <string.h>
-#include <stdlib.h>
 #include <unistd.h>
-#include <errno.h>
 #include <sys/syscall.h>
+#include "filestuff.h"
+#include "hostio.h"
 
 /* Some older glibc versions do not define this.  */
 #ifndef __WNOTHREAD
 #define INSTR_SC       0x44000002
 #define NR_spu_run     0x0116
 
-/* Get current thread ID (Linux task ID).  */
-#define current_ptid ((struct inferior_list_entry *)current_inferior)->id
-
 /* These are used in remote-utils.c.  */
 int using_threads = 0;
 
 /* Defined in auto-generated file reg-spu.c.  */
 void init_registers_spu (void);
-
+extern const struct target_desc *tdesc_spu;
 
 /* Fetch PPU register REGNO.  */
 static CORE_ADDR
@@ -206,14 +201,14 @@ store_ppc_memory (CORE_ADDR memaddr, char *myaddr, int len)
 static int
 parse_spufs_run (int *fd, CORE_ADDR *addr)
 {
-  char buf[4];
+  unsigned int insn;
   CORE_ADDR pc = fetch_ppc_register (32);  /* nip */
 
   /* Fetch instruction preceding current NIP.  */
-  if (fetch_ppc_memory (pc-4, buf, 4) != 0)
+  if (fetch_ppc_memory (pc-4, (char *) &insn, 4) != 0)
     return 0;
   /* It should be a "sc" instruction.  */
-  if (*(unsigned int *)buf != INSTR_SC)
+  if (insn != INSTR_SC)
     return 0;
   /* System call number should be NR_spu_run.  */
   if (fetch_ppc_register (0) != NR_spu_run)
@@ -269,6 +264,7 @@ spu_create_inferior (char *program, char **allargs)
 {
   int pid;
   ptid_t ptid;
+  struct process_info *proc;
 
   pid = fork ();
   if (pid < 0)
@@ -276,6 +272,7 @@ spu_create_inferior (char *program, char **allargs)
 
   if (pid == 0)
     {
+      close_most_fds ();
       ptrace (PTRACE_TRACEME, 0, 0, 0);
 
       setpgid (0, 0);
@@ -290,7 +287,8 @@ spu_create_inferior (char *program, char **allargs)
       _exit (0177);
     }
 
-  add_process (pid, 0);
+  proc = add_process (pid, 0);
+  proc->tdesc = tdesc_spu;
 
   ptid = ptid_build (pid, pid, 0);
   add_thread (ptid, NULL);
@@ -302,6 +300,7 @@ int
 spu_attach (unsigned long  pid)
 {
   ptid_t ptid;
+  struct process_info *proc;
 
   if (ptrace (PTRACE_ATTACH, pid, 0, 0) != 0)
     {
@@ -311,7 +310,8 @@ spu_attach (unsigned long  pid)
       _exit (0177);
     }
 
-  add_process (pid, 1);
+  proc = add_process (pid, 1);
+  proc->tdesc = tdesc_spu;
   ptid = ptid_build (pid, pid, 0);
   add_thread (ptid, NULL);
   return 0;
@@ -364,11 +364,6 @@ static void
 spu_join (int pid)
 {
   int status, ret;
-  struct process_info *process;
-
-  process = find_process_pid (pid);
-  if (process == NULL)
-    return;
 
   do {
     ret = waitpid (pid, &status, 0);
@@ -460,7 +455,7 @@ spu_wait (ptid_t ptid, struct target_waitstatus *ourstatus, int options)
     {
       fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
       ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
-      ourstatus->value.sig = target_signal_from_host (WTERMSIG (w));
+      ourstatus->value.sig = gdb_signal_from_host (WTERMSIG (w));
       clear_inferiors ();
       return pid_to_ptid (ret);
     }
@@ -470,12 +465,12 @@ spu_wait (ptid_t ptid, struct target_waitstatus *ourstatus, int options)
   if (!server_waiting)
     {
       ourstatus->kind = TARGET_WAITKIND_STOPPED;
-      ourstatus->value.sig = TARGET_SIGNAL_0;
+      ourstatus->value.sig = GDB_SIGNAL_0;
       return ptid_build (ret, ret, 0);
     }
 
   ourstatus->kind = TARGET_WAITKIND_STOPPED;
-  ourstatus->value.sig = target_signal_from_host (WSTOPSIG (w));
+  ourstatus->value.sig = gdb_signal_from_host (WSTOPSIG (w));
   return ptid_build (ret, ret, 0);
 }
 
@@ -561,7 +556,8 @@ spu_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
 {
   int fd, ret;
   CORE_ADDR addr;
-  char annex[32];
+  char annex[32], lslr_annex[32], buf[32];
+  CORE_ADDR lslr;
 
   /* We must be stopped on a spu_run system call.  */
   if (!parse_spufs_run (&fd, &addr))
@@ -570,6 +566,22 @@ spu_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
   /* Use the "mem" spufs file to access SPU local store.  */
   sprintf (annex, "%d/mem", fd);
   ret = spu_proc_xfer_spu (annex, myaddr, NULL, memaddr, len);
+  if (ret > 0)
+    return ret == len ? 0 : EIO;
+
+  /* SPU local store access wraps the address around at the
+     local store limit.  We emulate this here.  To avoid needing
+     an extra access to retrieve the LSLR, we only do that after
+     trying the original address first, and getting end-of-file.  */
+  sprintf (lslr_annex, "%d/lslr", fd);
+  memset (buf, 0, sizeof buf);
+  if (spu_proc_xfer_spu (lslr_annex, (unsigned char *)buf, NULL,
+                        0, sizeof buf) <= 0)
+    return ret;
+
+  lslr = strtoul (buf, NULL, 16);
+  ret = spu_proc_xfer_spu (annex, myaddr, NULL, memaddr & lslr, len);
+
   return ret == len ? 0 : EIO;
 }
 
@@ -582,7 +594,8 @@ spu_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
 {
   int fd, ret;
   CORE_ADDR addr;
-  char annex[32];
+  char annex[32], lslr_annex[32], buf[32];
+  CORE_ADDR lslr;
 
   /* We must be stopped on a spu_run system call.  */
   if (!parse_spufs_run (&fd, &addr))
@@ -591,6 +604,22 @@ spu_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
   /* Use the "mem" spufs file to access SPU local store.  */
   sprintf (annex, "%d/mem", fd);
   ret = spu_proc_xfer_spu (annex, NULL, myaddr, memaddr, len);
+  if (ret > 0)
+    return ret == len ? 0 : EIO;
+
+  /* SPU local store access wraps the address around at the
+     local store limit.  We emulate this here.  To avoid needing
+     an extra access to retrieve the LSLR, we only do that after
+     trying the original address first, and getting end-of-file.  */
+  sprintf (lslr_annex, "%d/lslr", fd);
+  memset (buf, 0, sizeof buf);
+  if (spu_proc_xfer_spu (lslr_annex, (unsigned char *)buf, NULL,
+                        0, sizeof buf) <= 0)
+    return ret;
+
+  lslr = strtoul (buf, NULL, 16);
+  ret = spu_proc_xfer_spu (annex, NULL, myaddr, memaddr & lslr, len);
+
   return ret == len ? 0 : EIO;
 }
 
@@ -619,13 +648,21 @@ static struct target_ops spu_target_ops = {
   spu_wait,
   spu_fetch_registers,
   spu_store_registers,
+  NULL, /* prepare_to_access_memory */
+  NULL, /* done_accessing_memory */
   spu_read_memory,
   spu_write_memory,
   spu_look_up_symbols,
   spu_request_interrupt,
   NULL,
+  NULL,  /* supports_z_point_type */
   NULL,
   NULL,
+  NULL, /* stopped_by_sw_breakpoint */
+  NULL, /* supports_stopped_by_sw_breakpoint */
+  NULL, /* stopped_by_hw_breakpoint */
+  NULL, /* supports_stopped_by_hw_breakpoint */
+  NULL, /* supports_conditional_breakpoints */
   NULL,
   NULL,
   NULL,
This page took 0.032136 seconds and 4 git commands to generate.