static void monitor_fetch_register PARAMS ((int regno));
static void monitor_store_register PARAMS ((int regno));
+static int monitor_printable_string PARAMS ((char *newstr, char *oldstr));
+static void monitor_error PARAMS ((char *format, CORE_ADDR memaddr, int len, char *string, int final_char));
static void monitor_detach PARAMS ((char *args, int from_tty));
static void monitor_resume PARAMS ((int pid, int step, enum target_signal sig));
static void monitor_interrupt PARAMS ((int signo));
static void monitor_interrupt_twice PARAMS ((int signo));
static void monitor_interrupt_query PARAMS ((void));
-static void monitor_wait_cleanup PARAMS ((int old_timeout));
+static void monitor_wait_cleanup PARAMS ((void *old_timeout));
static int monitor_wait PARAMS ((int pid, struct target_waitstatus *status));
static void monitor_fetch_registers PARAMS ((int regno));
/* Extra remote debugging for developing a new rom monitor variation */
#if ! defined(EXTRA_RDEBUG)
-#define EXTRA_RDEBUG 1
-#endif
-#if EXTRA_RDEBUG
-#define RDEBUG(stuff) { if (remote_debug) printf stuff ; }
-#else
-#define RDEBUG(stuff) {}
+#define EXTRA_RDEBUG 0
#endif
+#define RDEBUG(stuff) { if (EXTRA_RDEBUG && remote_debug) printf stuff ; }
/* Descriptor for I/O to remote machine. Initialize it to NULL so
that monitor_open knows that we don't have a file open when the
static int first_time=0; /* is this the first time we're executing after
gaving created the child proccess? */
+/* Convert a string into a printable representation, Return # byte in the
+ new string. */
+
+static int
+monitor_printable_string (newstr, oldstr)
+ char *newstr;
+ char *oldstr;
+{
+ char *save = newstr;
+ int ch;
+
+ while ((ch = *oldstr++) != '\0')
+ {
+ switch (ch)
+ {
+ default:
+ if (isprint (ch))
+ *newstr++ = ch;
+
+ else
+ {
+ sprintf (newstr, "\\x%02x", ch & 0xff);
+ newstr += 4;
+ }
+ break;
+
+ case '\\': *newstr++ = '\\'; *newstr++ = '\\'; break;
+ case '\b': *newstr++ = '\\'; *newstr++ = 'b'; break;
+ case '\f': *newstr++ = '\\'; *newstr++ = 't'; break;
+ case '\n': *newstr++ = '\\'; *newstr++ = 'n'; break;
+ case '\r': *newstr++ = '\\'; *newstr++ = 'r'; break;
+ case '\t': *newstr++ = '\\'; *newstr++ = 't'; break;
+ case '\v': *newstr++ = '\\'; *newstr++ = 'v'; break;
+ }
+ }
+
+ *newstr++ = '\0';
+ return newstr - save;
+}
+
+/* Print monitor errors with a string, converting the string to printable
+ representation. */
+
+static void
+monitor_error (format, memaddr, len, string, final_char)
+ char *format;
+ CORE_ADDR memaddr;
+ int len;
+ char *string;
+ int final_char;
+{
+ int real_len = (len == 0 && string != (char *)0) ? strlen (string) : len;
+ char *safe_string = alloca ((real_len * 4) + 1);
+ char *p, *q;
+ int ch;
+ int safe_len = monitor_printable_string (safe_string, string);
+
+ if (final_char)
+ error (format, (int)memaddr, p - safe_string, safe_string, final_char);
+ else
+ error (format, (int)memaddr, p - safe_string, safe_string);
+}
+
/* Convert hex digit A to a number. */
static int
Only format specifiers of the form "[0-9]*[a-z]" are recognized.
If it is a '%s' format, the argument is a string; otherwise the
argument is assumed to be a long integer.
+
+ %% is also turned into a single %.
*/
static void
/* Fetch the next argument and print it. */
switch (fmt)
{
+ case '%':
+ strcpy (sndbuf, "%");
+ break;
case 'A':
arg_addr = va_arg (args, CORE_ADDR);
strcpy (sndbuf, paddr_nz (arg_addr));
monitor_vsprintf (sndbuf, pattern, args);
+ len = strlen (sndbuf);
+ if (len + 1 > sizeof sndbuf)
+ abort ();
+
#if 0
if (remote_debug > 0)
puts_debug ("sent -->", sndbuf, "<--");
#endif
- RDEBUG(("sent[%s]\n",sndbuf)) ;
+ if (EXTRA_RDEBUG
+ && remote_debug)
+ {
+ char *safe_string = (char *) alloca ((strlen (sndbuf) * 4) + 1);
+ monitor_printable_string (safe_string, sndbuf);
+ printf ("sent[%s]\n", safe_string);
+ }
- len = strlen (sndbuf);
-
- if (len + 1 > sizeof sndbuf)
- abort ();
-
monitor_write (sndbuf, len);
}
monitor_vsprintf (sndbuf, pattern, args);
+ len = strlen (sndbuf);
+ if (len + 1 > sizeof sndbuf)
+ abort ();
+
#if 0
if (remote_debug > 0)
puts_debug ("sent -->", sndbuf, "<--");
#endif
- RDEBUG(("sent[%s]\n",sndbuf))
- len = strlen (sndbuf);
- if (len + 1 > sizeof sndbuf)
- abort ();
+ if (EXTRA_RDEBUG
+ && remote_debug)
+ {
+ char *safe_string = (char *) alloca ((len * 4) + 1);
+ monitor_printable_string (safe_string, sndbuf);
+ printf ("sent[%s]\n", safe_string);
+ }
monitor_write (sndbuf, len);
int buflen;
{
if (SERIAL_WRITE(monitor_desc, buf, buflen))
- fprintf_unfiltered (stderr, "SERIAL_WRITE failed: %s\n", safe_strerror (errno));
+ fprintf_unfiltered (gdb_stderr, "SERIAL_WRITE failed: %s\n",
+ safe_strerror (errno));
}
if (c == SERIAL_TIMEOUT)
#if 0 /* MAINTENANCE_CMDS */
- /* I fail to see how detaching here can be useful
+ /* I fail to see how detaching here can be useful */
if (in_monitor_wait) /* Watchdog went off */
{
target_mourn_inferior ();
int obuflen = buflen;
int c;
extern struct target_ops *targ_ops;
- RDEBUG(("MON Expecting '%s'\n",string)) ;
+
+ if (EXTRA_RDEBUG
+ && remote_debug)
+ {
+ char *safe_string = (char *) alloca ((strlen (string) * 4) + 1);
+ monitor_printable_string (safe_string, string);
+ printf ("MON Expecting '%s'\n", safe_string);
+ }
immediate_quit = 1;
while (1)
char *fastmap;
{
int tmp;
- char *val;
+ const char *val;
compiled_pattern->fastmap = fastmap;
/* Tell the remote machine to resume. */
-int flush_monitor_dcache(void) { dcache_flush (remote_dcache); }
+void
+flush_monitor_dcache ()
+{
+ dcache_flush (remote_dcache);
+}
static void
monitor_resume (pid, step, sig)
points to the start of the register value. */
struct re_registers register_strings;
+ memset (®ister_strings, 0, sizeof (struct re_registers));
+
if (re_search (®ister_pattern, buf, len, 0, len,
®ister_strings) == -1)
break;
static void
monitor_wait_cleanup (old_timeout)
- int old_timeout;
+ void *old_timeout;
{
- timeout = old_timeout;
+ timeout = *(int*)old_timeout;
signal (SIGINT, ofunc);
in_monitor_wait = 0;
}
status->kind = TARGET_WAITKIND_EXITED;
status->value.integer = 0;
- old_chain = make_cleanup (monitor_wait_cleanup, old_timeout);
+ old_chain = make_cleanup (monitor_wait_cleanup, &old_timeout);
RDEBUG(("MON wait\n"))
#if 0 /* MAINTENANCE_CMDS */
}
-static monitor_write_even_block(memaddr,myaddr,len)
+static int
+monitor_write_even_block(memaddr,myaddr,len)
CORE_ADDR memaddr ;
char * myaddr ;
int len ;
}
-static longlongendswap(unsigned char * a)
+static void
+longlongendswap (unsigned char * a)
{
int i,j ;
unsigned char x ;
if ((c == '0') && ((c = readchar (timeout)) == 'x'))
;
else
- error ("monitor_read_memory_single (0x%x): bad response from monitor: %.*s%c.",
- memaddr, i, membuf, c);
+ monitor_error ("monitor_read_memory_single (0x%x): bad response from monitor: %.*s%c.",
+ memaddr, i, membuf, c);
}
for (i = 0; i < len * 2; i++)
{
if (c == ' ')
continue;
- error ("monitor_read_memory_single (0x%x): bad response from monitor: %.*s%c.",
- memaddr, i, membuf, c);
+ monitor_error ("monitor_read_memory_single (0x%x): bad response from monitor: %.*s%c.",
+ memaddr, i, membuf, c);
}
membuf[i] = c;
val = strtoul (membuf, &p, 16);
if (val == 0 && membuf == p)
- error ("monitor_read_memory_single (0x%x): bad value from monitor: %s.",
- memaddr, membuf);
+ monitor_error ("monitor_read_memory_single (0x%x): bad value from monitor: %s.",
+ memaddr, 0, membuf, 0);
/* supply register stores in target byte order, so swap here */
int i;
CORE_ADDR dumpaddr;
+ if (len <= 0)
+ {
+ RDEBUG (("Zero length call to monitor_read_memory\n"));
+ return 0;
+ }
+
if (remote_debug) printf("MON read block ta(%08x) ha(%08x) %d\n",
(unsigned long) memaddr , (unsigned long)myaddr, len);
resp_len = monitor_expect (current_monitor->getmem.term, buf, sizeof buf); /* get response */
if (resp_len <= 0)
- error ("monitor_read_memory (0x%x): excessive response from monitor: %.*s.",
- memaddr, resp_len, buf);
+ monitor_error ("monitor_read_memory (0x%x): excessive response from monitor: %.*s.",
+ memaddr, resp_len, buf, 0);
if (current_monitor->getmem.term_cmd)
{
struct re_registers resp_strings;
RDEBUG(("MON getmem.resp_delim %s\n",current_monitor->getmem.resp_delim)) ;
+ memset (&resp_strings, 0, sizeof (struct re_registers));
tmp = strlen (p);
retval = re_search (&getmem_resp_delim_pattern, p, tmp, 0, tmp,
&resp_strings);
if (retval < 0)
- error ("monitor_read_memory (0x%x): bad response from monitor: %.*s.",
- memaddr, resp_len, buf);
+ monitor_error ("monitor_read_memory (0x%x): bad response from monitor: %.*s.",
+ memaddr, resp_len, buf, 0);
p += resp_strings.end[0];
#if 0
p = strstr (p, current_monitor->getmem.resp_delim);
if (!p)
- error ("monitor_read_memory (0x%x): bad response from monitor: %.*s.",
- memaddr, resp_len, buf);
+ monitor_error ("monitor_read_memory (0x%x): bad response from monitor: %.*s.",
+ memaddr, resp_len, buf, 0);
p += strlen (current_monitor->getmem.resp_delim);
#endif
}
break;
if (*p == '\000' || *p == '\n' || *p == '\r')
- error ("monitor_read_memory (0x%x): badly terminated response from monitor: %.*s", memaddr, resp_len, buf);
+ monitor_error ("monitor_read_memory (0x%x): badly terminated response from monitor: %.*s",
+ memaddr, resp_len, buf, 0);
p++;
}
val = strtoul (p, &p1, 16);
if (val == 0 && p == p1)
- error ("monitor_read_memory (0x%x): bad value from monitor: %.*s.", memaddr,
- resp_len, buf);
+ monitor_error ("monitor_read_memory (0x%x): bad value from monitor: %.*s.",
+ memaddr, resp_len, buf, 0);
*myaddr++ = val;
return len;
}
-/* This version supports very large reads by looping on multiline
- dump bytes outputs. Beware of buffering limits.
- */
-static int monotor_read_memory_block(memaddr,myaddr,len)
- CORE_ADDR memaddr ;
- char * myaddr ;
- int len ;
-{
-}
-
static int
monitor_xfer_memory (memaddr, myaddr, len, write, target)
CORE_ADDR memaddr;
return 0;
}
}
- fprintf_unfiltered (stderr, "Can't find breakpoint associated with 0x%x\n", addr);
+ fprintf_unfiltered (gdb_stderr,
+ "Can't find breakpoint associated with 0x%x\n", addr);
return 1;
}
return dev_name;
}
-static struct target_ops monitor_ops =
+static struct target_ops monitor_ops ;
+
+static void init_base_monitor_ops(void)
{
- NULL, /* to_shortname */
- NULL, /* to_longname */
- NULL, /* to_doc */
- NULL, /* to_open */
- monitor_close, /* to_close */
- NULL, /* to_attach */
- monitor_detach, /* to_detach */
- monitor_resume, /* to_resume */
- monitor_wait, /* to_wait */
- monitor_fetch_registers, /* to_fetch_registers */
- monitor_store_registers, /* to_store_registers */
- monitor_prepare_to_store, /* to_prepare_to_store */
- monitor_xfer_memory, /* to_xfer_memory */
- monitor_files_info, /* to_files_info */
- monitor_insert_breakpoint, /* to_insert_breakpoint */
- monitor_remove_breakpoint, /* to_remove_breakpoint */
- 0, /* to_terminal_init */
- 0, /* to_terminal_inferior */
- 0, /* to_terminal_ours_for_output */
- 0, /* to_terminal_ours */
- 0, /* to_terminal_info */
- monitor_kill, /* to_kill */
- monitor_load, /* to_load */
- 0, /* to_lookup_symbol */
- monitor_create_inferior, /* to_create_inferior */
- monitor_mourn_inferior, /* to_mourn_inferior */
- 0, /* to_can_run */
- 0, /* to_notice_signals */
- 0, /* to_thread_alive */
- monitor_stop, /* to_stop */
- process_stratum, /* to_stratum */
- 0, /* to_next */
- 1, /* to_has_all_memory */
- 1, /* to_has_memory */
- 1, /* to_has_stack */
- 1, /* to_has_registers */
- 1, /* to_has_execution */
- 0, /* sections */
- 0, /* sections_end */
- OPS_MAGIC /* to_magic */
-};
+ monitor_ops.to_shortname = NULL;
+ monitor_ops.to_longname = NULL;
+ monitor_ops.to_doc = NULL;
+ monitor_ops.to_open = NULL;
+ monitor_ops.to_close = monitor_close;
+ monitor_ops.to_attach = NULL;
+ monitor_ops.to_post_attach = NULL;
+ monitor_ops.to_require_attach = NULL;
+ monitor_ops.to_detach = monitor_detach;
+ monitor_ops.to_require_detach = NULL;
+ monitor_ops.to_resume = monitor_resume;
+ monitor_ops.to_wait = monitor_wait;
+ monitor_ops.to_post_wait = NULL;
+ monitor_ops.to_fetch_registers = monitor_fetch_registers;
+ monitor_ops.to_store_registers = monitor_store_registers;
+ monitor_ops.to_prepare_to_store = monitor_prepare_to_store;
+ monitor_ops.to_xfer_memory = monitor_xfer_memory;
+ monitor_ops.to_files_info = monitor_files_info;
+ monitor_ops.to_insert_breakpoint = monitor_insert_breakpoint;
+ monitor_ops.to_remove_breakpoint = monitor_remove_breakpoint;
+ monitor_ops.to_terminal_init = 0;
+ monitor_ops.to_terminal_inferior = 0;
+ monitor_ops.to_terminal_ours_for_output = 0;
+ monitor_ops.to_terminal_ours = 0;
+ monitor_ops.to_terminal_info = 0;
+ monitor_ops.to_kill = monitor_kill;
+ monitor_ops.to_load = monitor_load;
+ monitor_ops.to_lookup_symbol = 0;
+ monitor_ops.to_create_inferior = monitor_create_inferior;
+ monitor_ops.to_post_startup_inferior = NULL;
+ monitor_ops.to_acknowledge_created_inferior = NULL;
+ monitor_ops.to_clone_and_follow_inferior = NULL;
+ monitor_ops.to_post_follow_inferior_by_clone = NULL;
+ monitor_ops.to_insert_fork_catchpoint = NULL;
+ monitor_ops.to_remove_fork_catchpoint = NULL;
+ monitor_ops.to_insert_vfork_catchpoint = NULL;
+ monitor_ops.to_remove_vfork_catchpoint = NULL;
+ monitor_ops.to_has_forked = NULL;
+ monitor_ops.to_has_vforked = NULL;
+ monitor_ops.to_can_follow_vfork_prior_to_exec = NULL;
+ monitor_ops.to_post_follow_vfork = NULL;
+ monitor_ops.to_insert_exec_catchpoint = NULL;
+ monitor_ops.to_remove_exec_catchpoint = NULL;
+ monitor_ops.to_has_execd = NULL;
+ monitor_ops.to_reported_exec_events_per_exec_call = NULL;
+ monitor_ops.to_has_exited = NULL;
+ monitor_ops.to_mourn_inferior = monitor_mourn_inferior;
+ monitor_ops.to_can_run = 0;
+ monitor_ops.to_notice_signals = 0;
+ monitor_ops.to_thread_alive = 0;
+ monitor_ops.to_stop = monitor_stop;
+ monitor_ops.to_pid_to_exec_file = NULL;
+ monitor_ops.to_core_file_to_sym_file = NULL;
+ monitor_ops.to_stratum = process_stratum;
+ monitor_ops.DONT_USE = 0;
+ 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_sections = 0;
+ monitor_ops.to_sections_end = 0;
+ monitor_ops.to_magic = OPS_MAGIC ;
+} /* init_monitor_ops */
/* Init the target_ops structure pointed at by OPS */
init_monitor_ops (ops)
struct target_ops *ops;
{
+ if (monitor_ops.to_magic != OPS_MAGIC)
+ init_base_monitor_ops ();
+
memcpy (ops, &monitor_ops, sizeof monitor_ops);
}
void
_initialize_remote_monitors ()
{
+ init_base_monitor_ops() ;
add_show_from_set (add_set_cmd ("hash", no_class, var_boolean,
(char *)&hashmark,
"Set display of activity while downloading a file.\n\
add_com ("monitor", class_obscure, monitor_command,
"Send a command to the debug monitor.");
}
+
+