/* GNU/Linux/Nios II specific low level interface, for the remote server for
GDB.
- Copyright (C) 2008-2013 Free Software Foundation, Inc.
+ Copyright (C) 2008-2015 Free Software Foundation, Inc.
Contributed by Mentor Graphics, Inc.
#include "server.h"
#include "linux-low.h"
-#include <sys/ptrace.h>
+#include "elf/common.h"
+#include "nat/gdb_ptrace.h"
#include <endian.h>
#include "gdb_proc_service.h"
#include <asm/ptrace.h>
/* The following definition must agree with the number of registers
defined in "struct user_regs" in GLIBC
- (ports/sysdeps/unix/sysv/linux/nios2/sys/user.h), and also with
+ (sysdeps/unix/sysv/linux/nios2/sys/user.h), and also with
NIOS2_NUM_REGS in GDB proper. */
#define nios2_num_regs 49
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
+/* Implementation of linux_target_ops method "sw_breakpoint_from_kind". */
+
+static const gdb_byte *
+nios2_sw_breakpoint_from_kind (int kind, int *size)
+{
+ *size = nios2_breakpoint_len;
+ return (const gdb_byte *) &nios2_breakpoint;
+}
+
/* Implement the breakpoint_reinsert_addr linux_target_ops method. */
static CORE_ADDR
nios2_reinsert_addr (void)
{
union nios2_register ra;
- struct regcache *regcache = get_thread_regcache (current_inferior, 1);
+ struct regcache *regcache = get_thread_regcache (current_thread, 1);
collect_register_by_name (regcache, "ra", ra.buf);
return ra.reg32;
{
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;
return PS_OK;
}
-#ifdef HAVE_PTRACE_GETREGS
-
/* Helper functions to collect/supply a single register REGNO. */
static void
for (i = 0; i < nios2_num_regs; i++)
nios2_supply_register (regcache, i, regset + i);
}
-#endif /* HAVE_PTRACE_GETREGS */
static struct regset_info nios2_regsets[] =
{
-#ifdef HAVE_PTRACE_GETREGS
- { PTRACE_GETREGS, PTRACE_SETREGS, 0, nios2_num_regs * 4, GENERAL_REGS,
+ { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PRSTATUS,
+ nios2_num_regs * 4, GENERAL_REGS,
nios2_fill_gregset, nios2_store_gregset },
-#endif /* HAVE_PTRACE_GETREGS */
- { 0, 0, 0, -1, -1, NULL, NULL }
+ NULL_REGSET
};
static struct regsets_info nios2_regsets_info =
NULL,
nios2_get_pc,
nios2_set_pc,
- (const unsigned char *) &nios2_breakpoint,
- nios2_breakpoint_len,
+ NULL, /* breakpoint_kind_from_pc */
+ nios2_sw_breakpoint_from_kind,
nios2_reinsert_addr,
0,
nios2_breakpoint_at,