/* Remote debugging interface for boot monitors, for GDB.
Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2006, 2007, 2008 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2006, 2007, 2008, 2009, 2010
+ Free Software Foundation, Inc.
Contributed by Cygnus Support. Written by Rob Savoye for Cygnus.
Resurrected from the ashes by Stu Grossman.
/* Monitor specific debugging information. Typically only useful to
the developer of a new monitor interface. */
-static void monitor_debug (const char *fmt, ...) ATTR_FORMAT(printf, 1, 2);
+static void monitor_debug (const char *fmt, ...) ATTRIBUTE_PRINTF (1, 2);
static int monitor_debug_p = 0;
if (monitor_debug_p)
{
va_list args;
+
va_start (args, fmt);
vfprintf_filtered (gdb_stdlog, fmt, args);
va_end (args);
{
int real_len = (len == 0 && string != (char *) 0) ? strlen (string) : len;
char *safe_string = alloca ((real_len * 4) + 1);
+
monitor_printable_string (safe_string, string, real_len);
if (final_char)
- error (_("%s (0x%s): %s: %s%c"), function, paddr_nz (memaddr), message, safe_string, final_char);
+ error (_("%s (%s): %s: %s%c"),
+ function, paddress (target_gdbarch, memaddr),
+ message, safe_string, final_char);
else
- error (_("%s (0x%s): %s: %s"), function, paddr_nz (memaddr), message, safe_string);
+ error (_("%s (%s): %s: %s"),
+ function, paddress (target_gdbarch, memaddr),
+ message, safe_string);
}
/* Convert hex digit A to a number. */
static void
monitor_vsprintf (char *sndbuf, char *pattern, va_list args)
{
+ int addr_bit = gdbarch_addr_bit (target_gdbarch);
char format[10];
char fmt;
char *p;
break;
case 'A':
arg_addr = va_arg (args, CORE_ADDR);
- strcpy (sndbuf, paddr_nz (arg_addr));
+ strcpy (sndbuf, phex_nz (arg_addr, addr_bit / 8));
break;
case 's':
arg_string = va_arg (args, char *);
if (monitor_debug_p)
{
char *safe_string = (char *) alloca ((strlen (sndbuf) * 4) + 1);
+
monitor_printable_string (safe_string, sndbuf, 0);
fprintf_unfiltered (gdb_stdlog, "sent[%s]\n", safe_string);
}
if (monitor_debug_p)
{
char *safe_string = (char *) alloca ((len * 4) + 1);
+
monitor_printable_string (safe_string, sndbuf, 0);
fprintf_unfiltered (gdb_stdlog, "sent[%s]\n", safe_string);
}
if (monitor_debug_p || remote_debug)
{
char buf[2];
+
buf[0] = c;
buf[1] = '\0';
puts_debug ("read -->", buf, "<--");
{
char *mybuf;
char *p;
+
monitor_debug ("MON Expecting regexp\n");
if (buf)
mybuf = buf;
{
char *name;
char **p;
+ struct inferior *inf;
if (mon_ops->magic != MONITOR_OPS_MAGIC)
error (_("Magic number of monitor_ops struct wrong."));
/* Make run command think we are busy... */
inferior_ptid = monitor_ptid;
+ inf = current_inferior ();
+ inferior_appeared (inf, ptid_get_pid (inferior_ptid));
add_thread_silent (inferior_ptid);
/* Give monitor_wait something to read */
monitor_desc = NULL;
delete_thread_silent (monitor_ptid);
+ delete_inferior_silent (ptid_get_pid (monitor_ptid));
}
/* Terminate the open connection to the remote debugger. Use this
when you want to detach and do something else with your gdb. */
static void
-monitor_detach (char *args, int from_tty)
+monitor_detach (struct target_ops *ops, char *args, int from_tty)
{
pop_target (); /* calls monitor_close to do the real work */
if (from_tty)
char *
monitor_supply_register (struct regcache *regcache, int regno, char *valstr)
{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
ULONGEST val;
unsigned char regbuf[MAX_REGISTER_SIZE];
char *p;
/* supply register stores in target byte order, so swap here */
- store_unsigned_integer (regbuf,
- register_size (get_regcache_arch (regcache), regno),
+ store_unsigned_integer (regbuf, register_size (gdbarch, regno), byte_order,
val);
regcache_raw_supply (regcache, regno, regbuf);
/* Tell the remote machine to resume. */
static void
-monitor_resume (ptid_t ptid, int step, enum target_signal sig)
+monitor_resume (struct target_ops *ops,
+ ptid_t ptid, int step, enum target_signal sig)
{
/* Some monitors require a different command when starting a program */
monitor_debug ("MON resume\n");
{
int regnamelen, vallen;
char *regname, *val;
+
/* Element 0 points to start of register name, and element 1
points to the start of the register value. */
struct re_registers register_strings;
{
target_terminal_ours ();
- if (query ("Interrupted while waiting for the program.\n\
-Give up (and stop debugging it)? "))
+ if (query (_("Interrupted while waiting for the program.\n\
+Give up (and stop debugging it)? ")))
{
target_mourn_inferior ();
deprecated_throw_reason (RETURN_QUIT);
struct target_waitstatus *status)
{
int resp_len;
+
do
{
resp_len = monitor_expect_prompt (buf, bufmax);
status just as `wait' would. */
static ptid_t
-monitor_wait (ptid_t ptid, struct target_waitstatus *status)
+monitor_wait (struct target_ops *ops,
+ ptid_t ptid, struct target_waitstatus *status, int options)
{
int old_timeout = timeout;
char buf[TARGET_BUF_SIZE];
if (current_monitor->flags & MO_HEX_PREFIX)
{
int c;
+
c = readchar (timeout);
while (c == ' ')
c = readchar (timeout);
for (i = 0; i < register_size (get_regcache_arch (regcache), regno) * 2; i++)
{
int c;
+
c = readchar (timeout);
while (c == ' ')
c = readchar (timeout);
{
char buf[TARGET_BUF_SIZE];
int resp_len;
+
monitor_printf (block_cmd);
resp_len = monitor_expect_prompt (buf, sizeof (buf));
parse_register_dump (regcache, buf, resp_len);
{
char buf[TARGET_BUF_SIZE];
int resp_len;
+
if (current_monitor->dumpregs)
(*(current_monitor->dumpregs)) (regcache); /* call supplied function */
else if (current_monitor->dump_registers) /* default version */
}
static void
-monitor_fetch_registers (struct regcache *regcache, int regno)
+monitor_fetch_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
monitor_debug ("MON fetchregs\n");
if (current_monitor->getreg.cmd)
static void
monitor_store_register (struct regcache *regcache, int regno)
{
+ int reg_size = register_size (get_regcache_arch (regcache), regno);
const char *name;
ULONGEST val;
}
regcache_cooked_read_unsigned (regcache, regno, &val);
- monitor_debug ("MON storeg %d %s\n", regno,
- phex (val,
- register_size (get_regcache_arch (regcache), regno)));
+ monitor_debug ("MON storeg %d %s\n", regno, phex (val, reg_size));
/* send the register deposit command */
monitor_debug ("EXP setreg.resp_delim\n");
monitor_expect_regexp (&setreg_resp_delim_pattern, NULL, 0);
if (current_monitor->flags & MO_SETREG_INTERACTIVE)
- monitor_printf ("%s\r", paddr_nz (val));
+ monitor_printf ("%s\r", phex_nz (val, reg_size));
}
if (current_monitor->setreg.term)
{
monitor_debug ("EXP setreg.term\n");
monitor_expect (current_monitor->setreg.term, NULL, 0);
if (current_monitor->flags & MO_SETREG_INTERACTIVE)
- monitor_printf ("%s\r", paddr_nz (val));
+ monitor_printf ("%s\r", phex_nz (val, reg_size));
monitor_expect_prompt (NULL, 0);
}
else
/* Store the remote registers. */
static void
-monitor_store_registers (struct regcache *regcache, int regno)
+monitor_store_registers (struct target_ops *ops,
+ struct regcache *regcache, int regno)
{
if (regno >= 0)
{
static int
monitor_write_memory (CORE_ADDR memaddr, char *myaddr, int len)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
unsigned int val, hostval;
char *cmd;
int i;
- monitor_debug ("MON write %d %s\n", len, paddr (memaddr));
+ monitor_debug ("MON write %d %s\n", len, paddress (target_gdbarch, memaddr));
if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
- memaddr = gdbarch_addr_bits_remove (current_gdbarch, memaddr);
+ memaddr = gdbarch_addr_bits_remove (target_gdbarch, memaddr);
/* Use memory fill command for leading 0 bytes. */
cmd = current_monitor->setmem.cmdb;
}
- val = extract_unsigned_integer (myaddr, len);
+ val = extract_unsigned_integer (myaddr, len, byte_order);
if (len == 4)
{
monitor_printf_noecho (cmd, memaddr, val);
else if (current_monitor->flags & MO_SETMEM_INTERACTIVE)
{
-
monitor_printf_noecho (cmd, memaddr);
if (current_monitor->setmem.resp_delim)
monitor_printf ("%x\r", val);
}
if (current_monitor->setmem.term_cmd)
- { /* Emit this to get out of the memory editing state */
+ { /* Emit this to get out of the memory editing state */
monitor_printf ("%s", current_monitor->setmem.term_cmd);
/* Drop through to expecting a prompt */
}
{
unsigned char val;
int written = 0;
+
if (len == 0)
return 0;
/* Enter the sub mode */
{
int i, j;
unsigned char x;
+
i = 0;
j = 7;
while (i < 4)
unsigned char *scan, *limit; /* loop controls */
unsigned char c, nib;
int leadzero = 1;
+
scan = disbuf;
limit = scan + 8;
{
unsigned long long *dp;
+
dp = (unsigned long long *) scan;
*dp = value;
}
long long *llptr;
long long value;
int written = 0;
+
llptr = (unsigned long long *) myaddr;
if (len == 0)
return 0;
monitor_write_memory_block (CORE_ADDR memaddr, char *myaddr, int len)
{
int written;
+
written = 0;
/* FIXME: This would be a good place to put the zero test */
#if 1
static int
monitor_read_memory_single (CORE_ADDR memaddr, char *myaddr, int len)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
unsigned int val;
char membuf[sizeof (int) * 2 + 1];
char *p;
{
int i;
+
for (i = 0; i < len * 2; i++)
{
int c;
/* supply register stores in target byte order, so swap here */
- store_unsigned_integer (myaddr, len, val);
+ store_unsigned_integer (myaddr, len, byte_order, val);
return len;
}
}
monitor_debug ("MON read block ta(%s) ha(%lx) %d\n",
- paddr_nz (memaddr), (long) myaddr, len);
+ paddress (target_gdbarch, memaddr), (long) myaddr, len);
if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
- memaddr = gdbarch_addr_bits_remove (current_gdbarch, memaddr);
+ memaddr = gdbarch_addr_bits_remove (target_gdbarch, memaddr);
if (current_monitor->flags & MO_GETMEM_READ_SINGLE)
return monitor_read_memory_single (memaddr, myaddr, len);
{
int retval, tmp;
struct re_registers resp_strings;
+
monitor_debug ("MON getmem.resp_delim %s\n", current_monitor->getmem.resp_delim);
memset (&resp_strings, 0, sizeof (struct re_registers));
}
static void
-monitor_kill (void)
+monitor_kill (struct target_ops *ops)
{
return; /* ignore attempts to kill target system */
}
/* 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,
- int from_tty)
+monitor_create_inferior (struct target_ops *ops, char *exec_file,
+ char *args, char **env, int from_tty)
{
if (args && (*args != '\000'))
error (_("Args are not supported by the monitor."));
first_time = 1;
clear_proceed_status ();
- write_pc (bfd_get_start_address (exec_bfd));
+ regcache_write_pc (get_current_regcache (),
+ bfd_get_start_address (exec_bfd));
}
/* Clean up when a program exits.
instructions. */
static void
-monitor_mourn_inferior (void)
+monitor_mourn_inferior (struct target_ops *ops)
{
unpush_target (targ_ops);
generic_mourn_inferior (); /* Do all the proper things now */
/* Tell the monitor to add a breakpoint. */
static int
-monitor_insert_breakpoint (struct bp_target_info *bp_tgt)
+monitor_insert_breakpoint (struct gdbarch *gdbarch,
+ struct bp_target_info *bp_tgt)
{
CORE_ADDR addr = bp_tgt->placed_address;
int i;
- const unsigned char *bp;
int bplen;
- monitor_debug ("MON inst bkpt %s\n", paddr (addr));
+ monitor_debug ("MON inst bkpt %s\n", paddress (gdbarch, addr));
if (current_monitor->set_break == NULL)
error (_("No set_break defined for this monitor"));
if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
- addr = gdbarch_addr_bits_remove (current_gdbarch, addr);
+ addr = gdbarch_addr_bits_remove (gdbarch, addr);
/* Determine appropriate breakpoint size for this address. */
- bp = gdbarch_breakpoint_from_pc (current_gdbarch, &addr, &bplen);
+ gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen);
bp_tgt->placed_address = addr;
bp_tgt->placed_size = bplen;
/* Tell the monitor to remove a breakpoint. */
static int
-monitor_remove_breakpoint (struct bp_target_info *bp_tgt)
+monitor_remove_breakpoint (struct gdbarch *gdbarch,
+ struct bp_target_info *bp_tgt)
{
CORE_ADDR addr = bp_tgt->placed_address;
int i;
- monitor_debug ("MON rmbkpt %s\n", paddr (addr));
+ monitor_debug ("MON rmbkpt %s\n", paddress (gdbarch, addr));
if (current_monitor->clr_break == NULL)
error (_("No clr_break defined for this monitor"));
}
}
fprintf_unfiltered (gdb_stderr,
- "Can't find breakpoint associated with 0x%s\n",
- paddr_nz (addr));
+ "Can't find breakpoint associated with %s\n",
+ paddress (gdbarch, addr));
return 1;
}
/* Finally, make the PC point at the start address */
if (exec_bfd)
- write_pc (bfd_get_start_address (exec_bfd));
+ regcache_write_pc (get_current_regcache (),
+ bfd_get_start_address (exec_bfd));
/* There used to be code here which would clear inferior_ptid and
call clear_symtab_users. None of that should be necessary:
/* Check to see if a thread is still alive. */
static int
-monitor_thread_alive (ptid_t ptid)
+monitor_thread_alive (struct target_ops *ops, ptid_t ptid)
{
if (ptid_equal (ptid, monitor_ptid))
/* The monitor's task is always alive. */
buffer. */
static char *
-monitor_pid_to_str (ptid_t ptid)
+monitor_pid_to_str (struct target_ops *ops, ptid_t ptid)
{
static char buf[64];
monitor_ops.to_thread_alive = monitor_thread_alive;
monitor_ops.to_pid_to_str = monitor_pid_to_str;
monitor_ops.to_stratum = process_stratum;
- monitor_ops.to_has_all_memory = 1;
- monitor_ops.to_has_memory = 1;
- monitor_ops.to_has_stack = 1;
- monitor_ops.to_has_registers = 1;
- monitor_ops.to_has_execution = 1;
+ monitor_ops.to_has_all_memory = default_child_has_all_memory;
+ monitor_ops.to_has_memory = default_child_has_memory;
+ monitor_ops.to_has_stack = default_child_has_stack;
+ monitor_ops.to_has_registers = default_child_has_registers;
+ monitor_ops.to_has_execution = default_child_has_execution;
monitor_ops.to_magic = OPS_MAGIC;
} /* init_base_monitor_ops */