/* Remote target communications for serial-line targets in custom GDB protocol
- Copyright 1988, 1991-2000, 2001 Free Software Foundation, Inc.
+ Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+ 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
This file is part of GDB.
#include "gdb_string.h"
#include <ctype.h>
#include <fcntl.h>
-#include "frame.h"
#include "inferior.h"
#include "bfd.h"
#include "symfile.h"
#include "gdb-stabs.h"
#include "gdbthread.h"
#include "remote.h"
+#include "regcache.h"
#include <ctype.h>
#include <sys/time.h>
#include <signal.h>
#include "serial.h"
+#include "gdbcore.h" /* for exec_bfd */
+
/* Prototypes for local functions */
static void cleanup_sigint_signal_handler (void *dummy);
static void initialize_sigint_signal_handler (void);
config->support = PACKET_ENABLE;
break;
case PACKET_DISABLE:
- internal_error ("packet_ok: attempt to use a disabled packet");
+ internal_error (__FILE__, __LINE__,
+ "packet_ok: attempt to use a disabled packet");
break;
case PACKET_ENABLE:
break;
}
}
+/* Should we try the 'e' (step over range) request? */
+static struct packet_config remote_protocol_e;
+
+static void
+set_remote_protocol_e_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ update_packet_config (&remote_protocol_e);
+}
+
+static void
+show_remote_protocol_e_packet_cmd (char *args, int from_tty)
+{
+ show_packet_config_cmd (&remote_protocol_e);
+}
+
+
+/* Should we try the 'E' (step over range / w signal #) request? */
+static struct packet_config remote_protocol_E;
+
+static void
+set_remote_protocol_E_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ update_packet_config (&remote_protocol_E);
+}
+
+static void
+show_remote_protocol_E_packet_cmd (char *args, int from_tty)
+{
+ show_packet_config_cmd (&remote_protocol_E);
+}
+
+
/* Should we try the 'P' (set register) request? */
static struct packet_config remote_protocol_P;
int n = 0; /* position in display_buf */
if (remote_desc == 0) /* paranoia */
- internal_error ("remote_threads_extra_info");
+ internal_error (__FILE__, __LINE__,
+ "remote_threads_extra_info");
if (use_threadextra_query)
{
asection *sect;
bfd *abfd;
int len;
- char *p;
if (symfile_objfile == NULL)
return -1; /* no can do nothin' */
sect != 0;
sect = sect->next)
{
- p = (unsigned char *) bfd_get_section_name (abfd, sect);
+ const char *p = bfd_get_section_name (abfd, sect);
len = strlen (p);
if (strcmp (p + len - 4, "data") == 0) /* ends in "data" */
if (data_base == 0 ||
init_all_packet_configs (void)
{
int i;
+ update_packet_config (&remote_protocol_e);
+ update_packet_config (&remote_protocol_E);
update_packet_config (&remote_protocol_P);
for (i = 0; i < NR_Z_PACKET_TYPES; i++)
update_packet_config (&remote_protocol_Z[i]);
if (extended_p)
{
- /* tell the remote that we're using the extended protocol. */
+ /* Tell the remote that we are using the extended protocol. */
char *buf = alloca (PBUFSIZ);
putpkt ("!");
getpkt (buf, PBUFSIZ, 0);
}
+ /* FIXME: need a master target_open vector from which all
+ remote_opens can be called, so that stuff like this can
+ go there. Failing that, the following code must be copied
+ to the open function for any remote target that wants to
+ support svr4 shared libraries. */
+#ifdef SOLIB_CREATE_INFERIOR_HOOK
+ if (exec_bfd) /* No use without an exec file. */
+ SOLIB_CREATE_INFERIOR_HOOK (inferior_pid);
+#endif
}
/* Just like remote_open but with asynchronous support. */
if (extended_p)
{
- /* tell the remote that we're using the extended protocol. */
+ /* Tell the remote that we are using the extended protocol. */
char *buf = alloca (PBUFSIZ);
putpkt ("!");
getpkt (buf, PBUFSIZ, 0);
}
+ /* FIXME: need a master target_open vector from which all
+ remote_opens can be called, so that stuff like this can
+ go there. Failing that, the following code must be copied
+ to the open function for any remote target that wants to
+ support svr4 shared libraries. */
+#ifdef SOLIB_CREATE_INFERIOR_HOOK
+ if (exec_bfd) /* No use without an exec file. */
+ SOLIB_CREATE_INFERIOR_HOOK (inferior_pid);
+#endif
}
/* This takes a program previously attached to and detaches it. After
remote_resume (int pid, int step, enum target_signal siggnal)
{
char *buf = alloca (PBUFSIZ);
+ char *p;
if (pid == -1)
set_thread (0, 0); /* run any thread */
if (target_resume_hook)
(*target_resume_hook) ();
+
+ /* The s/S/c/C packets do not return status. So if the target does
+ not support the S or C packets, the debug agent returns an empty
+ string which is detected in remote_wait(). This protocol defect
+ is fixed in the e/E packets. */
+
+ if (step && step_range_end)
+ {
+ /* If the target does not support the 'E' packet, we try the 'S'
+ packet. Ideally we would fall back to the 'e' packet if that
+ too is not supported. But that would require another copy of
+ the code to issue the 'e' packet (and fall back to 's' if not
+ supported) in remote_wait(). */
+
+ if (siggnal != TARGET_SIGNAL_0)
+ {
+ if (remote_protocol_E.support != PACKET_DISABLE)
+ {
+ p = buf;
+ *p++ = 'E';
+ *p++ = tohex (((int) siggnal >> 4) & 0xf);
+ *p++ = tohex (((int) siggnal) & 0xf);
+ *p++ = ',';
+ p += hexnumstr (p, (ULONGEST) step_range_start);
+ *p++ = ',';
+ p += hexnumstr (p, (ULONGEST) step_range_end);
+ *p++ = 0;
+
+ putpkt (buf);
+ getpkt (buf, PBUFSIZ, 0);
+
+ if (packet_ok(buf, &remote_protocol_E) == PACKET_OK)
+ return;
+ }
+ }
+ else
+ {
+ if (remote_protocol_e.support != PACKET_DISABLE)
+ {
+ p = buf;
+ *p++ = 'e';
+ p += hexnumstr (p, (ULONGEST) step_range_start);
+ *p++ = ',';
+ p += hexnumstr (p, (ULONGEST) step_range_end);
+ *p++ = 0;
+
+ putpkt (buf);
+ getpkt (buf, PBUFSIZ, 0);
+
+ if (packet_ok(buf, &remote_protocol_e) == PACKET_OK)
+ return;
+ }
+ }
+ }
+
if (siggnal != TARGET_SIGNAL_0)
{
buf[0] = step ? 'S' : 'C';
buf[1] = tohex (((int) siggnal >> 4) & 0xf);
- buf[2] = tohex ((int) siggnal & 0xf);
+ buf[2] = tohex (((int) siggnal) & 0xf);
buf[3] = '\0';
}
else
remote_async_resume (int pid, int step, enum target_signal siggnal)
{
char *buf = alloca (PBUFSIZ);
+ char *p;
if (pid == -1)
set_thread (0, 0); /* run any thread */
if (target_resume_hook)
(*target_resume_hook) ();
+ /* The s/S/c/C packets do not return status. So if the target does
+ not support the S or C packets, the debug agent returns an empty
+ string which is detected in remote_wait(). This protocol defect
+ is fixed in the e/E packets. */
+
+ if (step && step_range_end)
+ {
+ /* If the target does not support the 'E' packet, we try the 'S'
+ packet. Ideally we would fall back to the 'e' packet if that
+ too is not supported. But that would require another copy of
+ the code to issue the 'e' packet (and fall back to 's' if not
+ supported) in remote_wait(). */
+
+ if (siggnal != TARGET_SIGNAL_0)
+ {
+ if (remote_protocol_E.support != PACKET_DISABLE)
+ {
+ p = buf;
+ *p++ = 'E';
+ *p++ = tohex (((int) siggnal >> 4) & 0xf);
+ *p++ = tohex (((int) siggnal) & 0xf);
+ *p++ = ',';
+ p += hexnumstr (p, (ULONGEST) step_range_start);
+ *p++ = ',';
+ p += hexnumstr (p, (ULONGEST) step_range_end);
+ *p++ = 0;
+
+ putpkt (buf);
+ getpkt (buf, PBUFSIZ, 0);
+
+ if (packet_ok(buf, &remote_protocol_E) == PACKET_OK)
+ goto register_event_loop;
+ }
+ }
+ else
+ {
+ if (remote_protocol_e.support != PACKET_DISABLE)
+ {
+ p = buf;
+ *p++ = 'e';
+ p += hexnumstr (p, (ULONGEST) step_range_start);
+ *p++ = ',';
+ p += hexnumstr (p, (ULONGEST) step_range_end);
+ *p++ = 0;
+
+ putpkt (buf);
+ getpkt (buf, PBUFSIZ, 0);
+
+ if (packet_ok(buf, &remote_protocol_e) == PACKET_OK)
+ goto register_event_loop;
+ }
+ }
+ }
+
if (siggnal != TARGET_SIGNAL_0)
{
buf[0] = step ? 'S' : 'C';
}
else
strcpy (buf, step ? "s" : "c");
+
+ putpkt (buf);
+register_event_loop:
/* We are about to start executing the inferior, let's register it
with the event loop. NOTE: this is the one place where all the
execution commands end up. We could alternatively do this in each
this information already found in the continuation block? */
if (target_is_async_p ())
target_executing = 1;
- putpkt (buf);
}
\f
todo = min (len, max_buf_size / 2);
break;
case PACKET_SUPPORT_UNKNOWN:
- internal_error ("%s:%d: remote_write_bytes: bad internal state",
- __FILE__, __LINE__);
+ internal_error (__FILE__, __LINE__,
+ "remote_write_bytes: bad internal state");
default:
- internal_error ("%s:%d: bad switch", __FILE__, __LINE__);
+ internal_error (__FILE__, __LINE__, "bad switch");
}
/* Append <memaddr> */
*p = '\0';
break;
case PACKET_SUPPORT_UNKNOWN:
- internal_error ("%s:%d: remote_write_bytes: bad internal state",
- __FILE__, __LINE__);
+ internal_error (__FILE__, __LINE__,
+ "remote_write_bytes: bad internal state");
default:
- internal_error ("%s:%d: bad switch", __FILE__, __LINE__);
+ internal_error (__FILE__, __LINE__, "bad switch");
}
putpkt_binary (buf, (int) (p - buf));
executing user code to stop. If FOREVER == 0, this function is
allowed to time out gracefully and return an indication of this to
the caller. */
-int
+static int
getpkt_sane (char *buf,
long sizeof_buf,
int forever)
return 4;
break;
default:
- internal_error ("hw_bp_to_z: bad watchpoint type %d", type);
+ internal_error (__FILE__, __LINE__,
+ "hw_bp_to_z: bad watchpoint type %d", type);
}
}
case PACKET_OK:
return 0;
}
- internal_error ("remote_insert_watchpoint: reached end of function");
+ internal_error (__FILE__, __LINE__,
+ "remote_insert_watchpoint: reached end of function");
}
/* FIXME: This function should be static and a member of the remote
case PACKET_OK:
return 0;
}
- internal_error ("remote_remove_watchpoint: reached end of function");
+ internal_error (__FILE__, __LINE__,
+ "remote_remove_watchpoint: reached end of function");
}
/* FIXME: This function should be static and a member of the remote
case PACKET_OK:
return 0;
}
- internal_error ("remote_remove_watchpoint: reached end of function");
+ internal_error (__FILE__, __LINE__,
+ "remote_remove_watchpoint: reached end of function");
}
/* FIXME: This function should be static and a member of the remote
case PACKET_OK:
return 0;
}
- internal_error ("remote_remove_watchpoint: reached end of function");
+ internal_error (__FILE__, __LINE__,
+ "remote_remove_watchpoint: reached end of function");
}
/* Some targets are only capable of doing downloads, and afterwards
struct cleanup *old_chain;
char *tmp;
char *sectdata;
- char *sectname;
+ const char *sectname;
char *buf = alloca (PBUFSIZ);
bfd_size_type size;
bfd_vma lma;
if (size == 0)
continue; /* skip zero-length section */
- sectname = (char *) bfd_get_section_name (exec_bfd, s);
+ sectname = bfd_get_section_name (exec_bfd, s);
if (args && strcmp (args, sectname) != 0)
continue; /* not the section selected by user */
#endif /* 0 */
+/* Convert a thread ID to a string. Returns the string in a static
+ buffer. */
+
+static char *
+remote_pid_to_str (int pid)
+{
+ static char buf[30];
+
+ sprintf (buf, "Thread %d", pid);
+ return buf;
+}
+
static void
init_remote_ops (void)
{
remote_ops.to_thread_alive = remote_thread_alive;
remote_ops.to_find_new_threads = remote_threads_info;
remote_ops.to_extra_thread_info = remote_threads_extra_info;
+ remote_ops.to_pid_to_str = remote_pid_to_str;
remote_ops.to_stop = remote_stop;
remote_ops.to_query = remote_query;
remote_ops.to_rcmd = remote_rcmd;
remote_async (void (*callback) (enum inferior_event_type event_type, void *context), void *context)
{
if (current_target.to_async_mask_value == 0)
- internal_error ("Calling remote_async when async is masked");
+ internal_error (__FILE__, __LINE__,
+ "Calling remote_async when async is masked");
if (callback != NULL)
{
static void
show_remote_cmd (char *args, int from_tty)
{
+
show_remote_protocol_Z_packet_cmd (args, from_tty);
+ show_remote_protocol_e_packet_cmd (args, from_tty);
+ show_remote_protocol_E_packet_cmd (args, from_tty);
show_remote_protocol_P_packet_cmd (args, from_tty);
show_remote_protocol_binary_download_cmd (args, from_tty);
}
/* Cisco stuff */
tty_input = xmalloc (PBUFSIZ);
- remote_address_size = TARGET_PTR_BIT;
+ remote_address_size = TARGET_ADDR_BIT;
}
void
add_info ("remote-process", remote_info_process,
"Query the remote system for process info.");
+ add_packet_config_cmd (&remote_protocol_e,
+ "e", "step-over-range",
+ set_remote_protocol_e_packet_cmd,
+ show_remote_protocol_e_packet_cmd,
+ &remote_set_cmdlist, &remote_show_cmdlist,
+ 0);
+
+ add_packet_config_cmd (&remote_protocol_E,
+ "E", "step-over-range-w-signal",
+ set_remote_protocol_E_packet_cmd,
+ show_remote_protocol_E_packet_cmd,
+ &remote_set_cmdlist, &remote_show_cmdlist,
+ 0);
+
add_packet_config_cmd (&remote_protocol_P,
"P", "set-register",
set_remote_protocol_P_packet_cmd,