/* Remote debugging interface for boot monitors, for GDB.
- Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001, 2002, 2006, 2007 Free Software Foundation, Inc.
Contributed by Cygnus Support. Written by Rob Savoye for Cygnus.
Resurrected from the ashes by Stu Grossman.
static char *dev_name;
static struct target_ops *targ_ops;
-static void monitor_vsprintf (char *sndbuf, char *pattern, va_list args);
-
-static int readchar (int timeout);
-
-static void monitor_fetch_register (int regno);
-static void monitor_store_register (int regno);
-
-static void monitor_printable_string (char *newstr, char *oldstr, int len);
-static void monitor_error (char *function, char *message, CORE_ADDR memaddr, int len, char *string, int final_char);
-static void monitor_detach (char *args, int from_tty);
-static void monitor_resume (ptid_t ptid, int step, enum target_signal sig);
-static void monitor_interrupt (int signo);
-static void monitor_interrupt_twice (int signo);
static void monitor_interrupt_query (void);
-static void monitor_wait_cleanup (void *old_timeout);
-
-static ptid_t monitor_wait (ptid_t ptid, struct target_waitstatus *status);
-static void monitor_fetch_registers (int regno);
-static void monitor_store_registers (int regno);
-static void monitor_prepare_to_store (void);
-static int monitor_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len,
- int write,
- struct mem_attrib *attrib,
- struct target_ops *target);
-static void monitor_files_info (struct target_ops *ops);
-static int monitor_insert_breakpoint (CORE_ADDR addr, gdb_byte *shadow);
-static int monitor_remove_breakpoint (CORE_ADDR addr, gdb_byte *shadow);
-static void monitor_kill (void);
-static void monitor_load (char *file, int from_tty);
-static void monitor_mourn_inferior (void);
+static void monitor_interrupt_twice (int);
static void monitor_stop (void);
+static void monitor_dump_regs (struct regcache *regcache);
-static int monitor_read_memory (CORE_ADDR addr, char *myaddr, int len);
-static int monitor_write_memory (CORE_ADDR addr, char *myaddr, int len);
-static int monitor_write_memory_bytes (CORE_ADDR addr, char *myaddr, int len);
-static int monitor_write_memory_block (CORE_ADDR memaddr,
- char *myaddr, int len);
-static int monitor_expect_regexp (struct re_pattern_buffer *pat,
- char *buf, int buflen);
-static void monitor_dump_regs (void);
#if 0
static int from_hex (int a);
-static unsigned long get_hex_word (void);
#endif
-static void parse_register_dump (char *, int);
static struct monitor_ops *current_monitor;
monitor_printf (current_monitor->line_term);
- start_remote ();
+ start_remote (from_tty);
}
/* Close out all files and local state before this target loses
/* Convert VALSTR into the target byte-ordered value of REGNO and store it. */
char *
-monitor_supply_register (int regno, char *valstr)
+monitor_supply_register (struct regcache *regcache, int regno, char *valstr)
{
ULONGEST val;
unsigned char regbuf[MAX_REGISTER_SIZE];
store_unsigned_integer (regbuf, register_size (current_gdbarch, regno), val);
- regcache_raw_supply (current_regcache, regno, regbuf);
+ regcache_raw_supply (regcache, regno, regbuf);
return p;
}
string which are passed down to monitor specific code. */
static void
-parse_register_dump (char *buf, int len)
+parse_register_dump (struct regcache *regcache, char *buf, int len)
{
monitor_debug ("MON Parsing register dump\n");
while (1)
vallen = register_strings.end[2] - register_strings.start[2];
val = buf + register_strings.start[2];
- current_monitor->supply_register (regname, regnamelen, val, vallen);
+ current_monitor->supply_register (regcache, regname, regnamelen,
+ val, vallen);
buf += register_strings.end[0];
len -= register_strings.end[0];
}
if (current_monitor->register_pattern)
- parse_register_dump (buf, resp_len);
+ parse_register_dump (current_regcache, buf, resp_len);
#else
monitor_debug ("Wait fetching registers after stop\n");
- monitor_dump_regs ();
+ monitor_dump_regs (current_regcache);
#endif
status->kind = TARGET_WAITKIND_STOPPED;
errno value. */
static void
-monitor_fetch_register (int regno)
+monitor_fetch_register (struct regcache *regcache, int regno)
{
const char *name;
char *zerobuf;
if (!name || (*name == '\0'))
{
monitor_debug ("No register known for %d\n", regno);
- regcache_raw_supply (current_regcache, regno, zerobuf);
+ regcache_raw_supply (regcache, regno, zerobuf);
return;
}
current_monitor->getreg.term_cmd) /* ack expected */
monitor_expect_prompt (NULL, 0); /* get response */
- monitor_supply_register (regno, regbuf);
+ monitor_supply_register (regcache, regno, regbuf);
}
/* Sometimes, it takes several commands to dump the registers */
case they need to compose the operation.
*/
int
-monitor_dump_reg_block (char *block_cmd)
+monitor_dump_reg_block (struct regcache *regcache, char *block_cmd)
{
char buf[TARGET_BUF_SIZE];
int resp_len;
monitor_printf (block_cmd);
resp_len = monitor_expect_prompt (buf, sizeof (buf));
- parse_register_dump (buf, resp_len);
+ parse_register_dump (regcache, buf, resp_len);
return 1;
}
/* Call the specific function if it has been provided */
static void
-monitor_dump_regs (void)
+monitor_dump_regs (struct regcache *regcache)
{
char buf[TARGET_BUF_SIZE];
int resp_len;
if (current_monitor->dumpregs)
- (*(current_monitor->dumpregs)) (); /* call supplied function */
+ (*(current_monitor->dumpregs)) (regcache); /* call supplied function */
else if (current_monitor->dump_registers) /* default version */
{
monitor_printf (current_monitor->dump_registers);
resp_len = monitor_expect_prompt (buf, sizeof (buf));
- parse_register_dump (buf, resp_len);
+ parse_register_dump (regcache, buf, resp_len);
}
else
internal_error (__FILE__, __LINE__, _("failed internal consistency check")); /* Need some way to read registers */
}
static void
-monitor_fetch_registers (int regno)
+monitor_fetch_registers (struct regcache *regcache, int regno)
{
monitor_debug ("MON fetchregs\n");
if (current_monitor->getreg.cmd)
{
if (regno >= 0)
{
- monitor_fetch_register (regno);
+ monitor_fetch_register (regcache, regno);
return;
}
- for (regno = 0; regno < NUM_REGS; regno++)
- monitor_fetch_register (regno);
+ for (regno = 0; regno < gdbarch_num_regs (current_gdbarch); regno++)
+ monitor_fetch_register (regcache, regno);
}
else
{
- monitor_dump_regs ();
+ monitor_dump_regs (regcache);
}
}
/* Store register REGNO, or all if REGNO == 0. Return errno value. */
static void
-monitor_store_register (int regno)
+monitor_store_register (struct regcache *regcache, int regno)
{
const char *name;
ULONGEST val;
return;
}
- val = read_register (regno);
+ regcache_cooked_read_unsigned (regcache, regno, &val);
monitor_debug ("MON storeg %d %s\n", regno,
phex (val, register_size (current_gdbarch, regno)));
/* Store the remote registers. */
static void
-monitor_store_registers (int regno)
+monitor_store_registers (struct regcache *regcache, int regno)
{
if (regno >= 0)
{
- monitor_store_register (regno);
+ monitor_store_register (regcache, regno);
return;
}
- for (regno = 0; regno < NUM_REGS; regno++)
- monitor_store_register (regno);
+ for (regno = 0; regno < gdbarch_num_regs (current_gdbarch); regno++)
+ monitor_store_register (regcache, regno);
}
/* Get ready to modify the registers array. On machines which store
debugged. */
static void
-monitor_prepare_to_store (void)
+monitor_prepare_to_store (struct regcache *regcache)
{
/* Do nothing, since we can store individual regs */
}
monitor_debug ("MON write %d %s\n", len, paddr (memaddr));
if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
- memaddr = ADDR_BITS_REMOVE (memaddr);
+ memaddr = gdbarch_addr_bits_remove (current_gdbarch, memaddr);
/* Use memory fill command for leading 0 bytes. */
paddr_nz (memaddr), (long) myaddr, len);
if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
- memaddr = ADDR_BITS_REMOVE (memaddr);
+ memaddr = gdbarch_addr_bits_remove (current_gdbarch, memaddr);
if (current_monitor->flags & MO_GETMEM_READ_SINGLE)
return monitor_read_memory_single (memaddr, myaddr, len);
return; /* ignore attempts to kill target system */
}
-/* All we actually do is set the PC to the start address of exec_bfd, and start
- the program at that point. */
+/* All we actually do is set the PC to the start address of exec_bfd. */
static void
monitor_create_inferior (char *exec_file, char *args, char **env,
first_time = 1;
clear_proceed_status ();
- proceed (bfd_get_start_address (exec_bfd), TARGET_SIGNAL_0, 0);
+ write_pc (bfd_get_start_address (exec_bfd));
}
/* Clean up when a program exits.
/* Tell the monitor to add a breakpoint. */
static int
-monitor_insert_breakpoint (CORE_ADDR addr, gdb_byte *shadow)
+monitor_insert_breakpoint (struct bp_target_info *bp_tgt)
{
+ CORE_ADDR addr = bp_tgt->placed_address;
int i;
const unsigned char *bp;
int bplen;
error (_("No set_break defined for this monitor"));
if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
- addr = ADDR_BITS_REMOVE (addr);
+ addr = gdbarch_addr_bits_remove (current_gdbarch, addr);
/* Determine appropriate breakpoint size for this address. */
bp = gdbarch_breakpoint_from_pc (current_gdbarch, &addr, &bplen);
+ bp_tgt->placed_address = addr;
+ bp_tgt->placed_size = bplen;
for (i = 0; i < current_monitor->num_breakpoints; i++)
{
if (breakaddr[i] == 0)
{
breakaddr[i] = addr;
- monitor_read_memory (addr, shadow, bplen);
monitor_printf (current_monitor->set_break, addr);
monitor_expect_prompt (NULL, 0);
return 0;
/* Tell the monitor to remove a breakpoint. */
static int
-monitor_remove_breakpoint (CORE_ADDR addr, gdb_byte *shadow)
+monitor_remove_breakpoint (struct bp_target_info *bp_tgt)
{
+ CORE_ADDR addr = bp_tgt->placed_address;
int i;
monitor_debug ("MON rmbkpt %s\n", paddr (addr));
if (current_monitor->clr_break == NULL)
error (_("No clr_break defined for this monitor"));
- if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
- addr = ADDR_BITS_REMOVE (addr);
-
for (i = 0; i < current_monitor->num_breakpoints; i++)
{
if (breakaddr[i] == addr)