Replace breakpoint_reinsert_addr by get_next_pcs operation in GDBServer
[deliverable/binutils-gdb.git] / gdb / gdbserver / linux-nios2-low.c
index 7bd3c9795d37a80e3743e2f92a8dae02efd56d8d..1accc03412014b4265de27319ff37f2f018ea144 100644 (file)
@@ -22,7 +22,7 @@
 #include "server.h"
 #include "linux-low.h"
 #include "elf/common.h"
-#include <sys/ptrace.h>
+#include "nat/gdb_ptrace.h"
 #include <endian.h>
 #include "gdb_proc_service.h"
 #include <asm/ptrace.h>
@@ -117,21 +117,31 @@ nios2_set_pc (struct regcache *regcache, CORE_ADDR pc)
   supply_register_by_name (regcache, "pc", newpc.buf);
 }
 
-/* Breakpoint support.  */
+/* Breakpoint support.  Also see comments on nios2_breakpoint_from_pc
+   in nios2-tdep.c.  */
 
-static const unsigned int nios2_breakpoint = 0x003b6ffa;
+#if defined(__nios2_arch__) && __nios2_arch__ == 2
+#define NIOS2_BREAKPOINT 0xb7fd0020
+#define CDX_BREAKPOINT 0xd7c9
+#else
+#define NIOS2_BREAKPOINT 0x003b6ffa
+#endif
+
+/* We only register the 4-byte breakpoint, even on R2 targets which also
+   support 2-byte breakpoints.  Since there is no supports_z_point_type
+   function provided, gdbserver never inserts software breakpoints itself
+   and instead relies on GDB to insert the breakpoint of the correct length
+   via a memory write.  */
+static const unsigned int nios2_breakpoint = NIOS2_BREAKPOINT;
 #define nios2_breakpoint_len 4
 
-/* Implement the breakpoint_reinsert_addr linux_target_ops method.  */
+/* Implementation of linux_target_ops method "sw_breakpoint_from_kind".  */
 
-static CORE_ADDR
-nios2_reinsert_addr (void)
+static const gdb_byte *
+nios2_sw_breakpoint_from_kind (int kind, int *size)
 {
-  union nios2_register ra;
-  struct regcache *regcache = get_thread_regcache (current_thread, 1);
-
-  collect_register_by_name (regcache, "ra", ra.buf);
-  return ra.reg32;
+  *size = nios2_breakpoint_len;
+  return (const gdb_byte *) &nios2_breakpoint;
 }
 
 /* Implement the breakpoint_at linux_target_ops method.  */
@@ -141,6 +151,13 @@ nios2_breakpoint_at (CORE_ADDR where)
 {
   unsigned int insn;
 
+  /* For R2, first check for the 2-byte CDX trap.n breakpoint encoding.  */
+#if defined(__nios2_arch__) && __nios2_arch__ == 2
+  (*the_target->read_memory) (where, (unsigned char *) &insn, 2);
+  if (insn == CDX_BREAKPOINT)
+    return 1;
+#endif
+
   (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
   if (insn == nios2_breakpoint)
     return 1;
@@ -210,7 +227,7 @@ static struct regset_info nios2_regsets[] =
   { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PRSTATUS,
     nios2_num_regs * 4, GENERAL_REGS,
     nios2_fill_gregset, nios2_store_gregset },
-  { 0, 0, 0, -1, -1, NULL, NULL }
+  NULL_REGSET
 };
 
 static struct regsets_info nios2_regsets_info =
@@ -248,9 +265,9 @@ struct linux_target_ops the_low_target =
   NULL,
   nios2_get_pc,
   nios2_set_pc,
-  (const unsigned char *) &nios2_breakpoint,
-  nios2_breakpoint_len,
-  nios2_reinsert_addr,
+  NULL, /* breakpoint_kind_from_pc */
+  nios2_sw_breakpoint_from_kind,
+  NULL, /* get_next_pcs */
   0,
   nios2_breakpoint_at,
 };
This page took 0.024767 seconds and 4 git commands to generate.