/* Remote debugging interface for MIPS remote debugging protocol.
- Copyright (C) 1993-2013 Free Software Foundation, Inc.
+ Copyright (C) 1993-2015 Free Software Foundation, Inc.
Contributed by Cygnus Support. Written by Ian Lance Taylor
<ian@cygnus.com>.
#include "defs.h"
#include "inferior.h"
+#include "infrun.h"
#include "bfd.h"
#include "symfile.h"
#include "gdbcmd.h"
#include "gdbcore.h"
#include "serial.h"
#include "target.h"
-#include "exceptions.h"
-#include "gdb_string.h"
-#include "gdb_stat.h"
+#include <sys/stat.h>
#include "gdb_usleep.h"
#include "regcache.h"
#include <ctype.h>
static void mips_initialize (void);
-static void mips_open (char *name, int from_tty);
-
-static void pmon_open (char *name, int from_tty);
-
-static void ddb_open (char *name, int from_tty);
-
-static void lsi_open (char *name, int from_tty);
-
-static void mips_close (void);
+static void mips_close (struct target_ops *self);
static int mips_map_regno (struct gdbarch *, int);
static void mips_set_register (int regno, ULONGEST value);
-static void mips_prepare_to_store (struct regcache *regcache);
+static void mips_prepare_to_store (struct target_ops *self,
+ struct regcache *regcache);
static int mips_fetch_word (CORE_ADDR addr, unsigned int *valp);
static int mips_store_word (CORE_ADDR addr, unsigned int value,
int *old_contents);
-static int mips_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len,
- int write,
- struct mem_attrib *attrib,
- struct target_ops *target);
+static enum target_xfer_status mips_xfer_memory (gdb_byte *readbuf,
+ const gdb_byte *writebuf,
+ ULONGEST memaddr,
+ ULONGEST len,
+ ULONGEST *xfered_len);
static void mips_files_info (struct target_ops *ignore);
static void pmon_download (char *buffer, int length);
-static void pmon_load_fast (char *file);
-
-static void mips_load (char *file, int from_tty);
+static void mips_load (struct target_ops *self, const char *file, int from_tty);
static int mips_make_srec (char *buffer, int type, CORE_ADDR memaddr,
unsigned char *myaddr, int len);
/* unsigned */ int len;
unsigned char *packet;
int cksum;
- int try;
+ int attempt;
len = strlen (s);
if (len > DATA_MAXLEN)
/* We can only have one outstanding data packet, so we just wait for
the acknowledgement here. Keep retransmitting the packet until
we get one, or until we've tried too many times. */
- for (try = 0; try < mips_send_retries; try++)
+ for (attempt = 0; attempt < mips_send_retries; attempt++)
{
int garbage;
int ch;
/* Open a connection to the remote board. */
static void
-common_open (struct target_ops *ops, char *name, int from_tty,
+common_open (struct target_ops *ops, const char *name, int from_tty,
enum mips_monitor_type new_monitor,
const char *new_monitor_prompt)
{
/* Open a connection to an IDT board. */
static void
-mips_open (char *name, int from_tty)
+mips_open (const char *name, int from_tty)
{
const char *monitor_prompt = NULL;
if (gdbarch_bfd_arch_info (target_gdbarch ()) != NULL
/* Open a connection to a PMON board. */
static void
-pmon_open (char *name, int from_tty)
+pmon_open (const char *name, int from_tty)
{
common_open (&pmon_ops, name, from_tty, MON_PMON, "PMON> ");
}
/* Open a connection to a DDB board. */
static void
-ddb_open (char *name, int from_tty)
+ddb_open (const char *name, int from_tty)
{
common_open (&ddb_ops, name, from_tty, MON_DDB, "NEC010>");
}
/* Open a connection to a rockhopper board. */
static void
-rockhopper_open (char *name, int from_tty)
+rockhopper_open (const char *name, int from_tty)
{
common_open (&rockhopper_ops, name, from_tty, MON_ROCKHOPPER, "NEC01>");
}
/* Open a connection to an LSI board. */
static void
-lsi_open (char *name, int from_tty)
+lsi_open (const char *name, int from_tty)
{
int i;
/* Close a connection to the remote board. */
static void
-mips_close (void)
+mips_close (struct target_ops *self)
{
if (mips_is_open)
{
registers, so this function doesn't have to do anything. */
static void
-mips_prepare_to_store (struct regcache *regcache)
+mips_prepare_to_store (struct target_ops *self, struct regcache *regcache)
{
}
return 0;
}
-/* Read or write LEN bytes from inferior memory at MEMADDR,
- transferring to or from debugger address MYADDR. Write to inferior
- if SHOULD_WRITE is nonzero. Returns length of data written or
- read; 0 for error. Note that protocol gives us the correct value
- for a longword, since it transfers values in ASCII. We want the
- byte values, so we have to swap the longword values. */
+/* Helper for mips_xfer_partial that handles memory transfers.
+ Arguments are like target_xfer_partial. Note that the protocol
+ gives us the correct value for a longword, since it transfers
+ values in ASCII. We want the byte values, so we have to swap the
+ longword values. */
static int mask_address_p = 1;
-static int
-mips_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int write,
- struct mem_attrib *attrib, struct target_ops *target)
+static enum target_xfer_status
+mips_xfer_memory (gdb_byte *readbuf, const gdb_byte *writebuf,
+ ULONGEST memaddr, ULONGEST len, ULONGEST *xfered_len)
{
enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
int i;
/* Allocate buffer of that many longwords. */
buffer = alloca (count * 4);
- if (write)
+ if (writebuf != NULL)
{
/* Fill start and end extra bytes of buffer with existing data. */
if (addr != memaddr || len < 4)
unsigned int val;
if (mips_fetch_word (addr, &val))
- return 0;
+ return TARGET_XFER_E_IO;
/* Need part of initial word -- fetch it. */
store_unsigned_integer (&buffer[0], 4, byte_order, val);
/* Need part of last word -- fetch it. FIXME: we do this even
if we don't need it. */
if (mips_fetch_word (addr + (count - 1) * 4, &val))
- return 0;
+ return TARGET_XFER_E_IO;
store_unsigned_integer (&buffer[(count - 1) * 4],
4, byte_order, val);
/* Copy data to be written over corresponding part of buffer. */
- memcpy ((char *) buffer + (memaddr & 3), myaddr, len);
+ memcpy ((char *) buffer + (memaddr & 3), writebuf, len);
/* Write the entire buffer. */
gdb_flush (gdb_stdout);
}
if (status)
- {
- errno = status;
- return 0;
- }
+ return TARGET_XFER_E_IO;
/* FIXME: Do we want a QUIT here? */
}
if (count >= 256)
unsigned int val;
if (mips_fetch_word (addr, &val))
- return 0;
+ return TARGET_XFER_E_IO;
store_unsigned_integer (&buffer[i * 4], 4, byte_order, val);
QUIT;
}
/* Copy appropriate bytes out of the buffer. */
- memcpy (myaddr, buffer + (memaddr & 3), len);
+ memcpy (readbuf, buffer + (memaddr & 3), len);
+ }
+ *xfered_len = len;
+ return TARGET_XFER_OK;
+}
+
+/* Target to_xfer_partial implementation. */
+
+static enum target_xfer_status
+mips_xfer_partial (struct target_ops *ops, enum target_object object,
+ const char *annex, gdb_byte *readbuf,
+ const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
+ ULONGEST *xfered_len)
+{
+ switch (object)
+ {
+ case TARGET_OBJECT_MEMORY:
+ return mips_xfer_memory (readbuf, writebuf, offset, len, xfered_len);
+
+ default:
+ return ops->beneath->to_xfer_partial (ops->beneath, object, annex,
+ readbuf, writebuf, offset, len,
+ xfered_len);
}
- return len;
}
/* Print info on this target. */
target contents. */
static int
-mips_insert_breakpoint (struct gdbarch *gdbarch,
+mips_insert_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
struct bp_target_info *bp_tgt)
{
if (monitor_supports_breakpoints)
- return mips_set_breakpoint (bp_tgt->placed_address, MIPS_INSN32_SIZE,
- BREAK_FETCH);
+ {
+ bp_tgt->placed_address = bp_tgt->reqstd_address;
+ return mips_set_breakpoint (bp_tgt->placed_address, MIPS_INSN32_SIZE,
+ BREAK_FETCH);
+ }
else
- return memory_insert_breakpoint (gdbarch, bp_tgt);
+ return memory_insert_breakpoint (ops, gdbarch, bp_tgt);
}
/* Remove a breakpoint. */
static int
-mips_remove_breakpoint (struct gdbarch *gdbarch,
+mips_remove_breakpoint (struct target_ops *ops, struct gdbarch *gdbarch,
struct bp_target_info *bp_tgt)
{
if (monitor_supports_breakpoints)
return mips_clear_breakpoint (bp_tgt->placed_address, MIPS_INSN32_SIZE,
BREAK_FETCH);
else
- return memory_remove_breakpoint (gdbarch, bp_tgt);
+ return memory_remove_breakpoint (ops, gdbarch, bp_tgt);
}
/* Tell whether this target can support a hardware breakpoint. CNT
implements the target_can_use_hardware_watchpoint macro. */
static int
-mips_can_use_watchpoint (int type, int cnt, int othertype)
+mips_can_use_watchpoint (struct target_ops *self,
+ enum bptype type, int cnt, int othertype)
{
return cnt < MAX_LSI_BREAKPOINTS && strcmp (target_shortname, "lsi") == 0;
}
watchpoint. */
static int
-mips_insert_watchpoint (CORE_ADDR addr, int len, int type,
+mips_insert_watchpoint (struct target_ops *self,
+ CORE_ADDR addr, int len, enum target_hw_bp_type type,
struct expression *cond)
{
- if (mips_set_breakpoint (addr, len, type))
+ /* These enum types are compatible by design. */
+ enum break_type btype = (enum break_type) type;
+
+ if (mips_set_breakpoint (addr, len, btype))
return -1;
return 0;
/* Remove a watchpoint. */
static int
-mips_remove_watchpoint (CORE_ADDR addr, int len, int type,
+mips_remove_watchpoint (struct target_ops *self,
+ CORE_ADDR addr, int len, enum target_hw_bp_type type,
struct expression *cond)
{
- if (mips_clear_breakpoint (addr, len, type))
+ /* These enum types are compatible by design. */
+ enum break_type btype = (enum break_type) type;
+
+ if (mips_clear_breakpoint (addr, len, btype))
return -1;
return 0;
if not. */
static int
-mips_stopped_by_watchpoint (void)
+mips_stopped_by_watchpoint (struct target_ops *ops)
{
return hit_watchpoint;
}
/* Download a binary file by converting it to S records. */
static void
-mips_load_srec (char *args)
+mips_load_srec (const char *args)
{
bfd *abfd;
asection *s;
using the FastLoad format. */
static void
-pmon_load_fast (char *file)
+pmon_load_fast (const char *file)
{
bfd *abfd;
asection *s;
/* mips_load -- download a file. */
static void
-mips_load (char *file, int from_tty)
+mips_load (struct target_ops *self, const char *file, int from_tty)
{
struct regcache *regcache;
mips_ops.to_fetch_registers = mips_fetch_registers;
mips_ops.to_store_registers = mips_store_registers;
mips_ops.to_prepare_to_store = mips_prepare_to_store;
- mips_ops.deprecated_xfer_memory = mips_xfer_memory;
+ mips_ops.to_xfer_partial = mips_xfer_partial;
mips_ops.to_files_info = mips_files_info;
mips_ops.to_insert_breakpoint = mips_insert_breakpoint;
mips_ops.to_remove_breakpoint = mips_remove_breakpoint;