/* Remote target communications for serial-line targets in custom GDB protocol
Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
- 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
This file is part of GDB.
#include "gdbcore.h" /* for exec_bfd */
+#include "remote-fileio.h"
+
/* Prototypes for local functions */
static void cleanup_sigint_signal_handler (void *dummy);
static void initialize_sigint_signal_handler (void);
static void build_remote_gdbarch_data (void);
-static int remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len);
-
-static int remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len);
-
static void remote_files_info (struct target_ops *ignore);
static int remote_xfer_memory (CORE_ADDR memaddr, char *myaddr,
static void extended_remote_mourn (void);
-static void extended_remote_create_inferior (char *, char *, char **);
-static void extended_remote_async_create_inferior (char *, char *, char **);
-
static void remote_mourn_1 (struct target_ops *);
static void remote_send (char *buf, long sizeof_buf);
static int tohex (int nib);
static void remote_detach (char *args, int from_tty);
-static void remote_async_detach (char *args, int from_tty);
static void remote_interrupt (int signo);
static void init_extended_remote_ops (void);
-static void init_remote_cisco_ops (void);
-
-static struct target_ops remote_cisco_ops;
-
static void remote_stop (void);
static int ishex (int ch, int *val);
static int stubhex (int ch);
-static int remote_query (int /*char */ , char *, char *, int *);
-
static int hexnumstr (char *, ULONGEST);
static int hexnumnstr (char *, ULONGEST, int);
/* Description of the remote protocol. Strictly speaking, when the
target is open()ed, remote.c should create a per-target description
of the remote protocol using that target's architecture.
- Unfortunatly, the target stack doesn't include local state. For
+ Unfortunately, the target stack doesn't include local state. For
the moment keep the information in the target's architecture
object. Sigh.. */
long regnum; /* GDB's internal register number. */
LONGEST pnum; /* Remote protocol register number. */
int in_g_packet; /* Always part of G packet. */
- /* long size in bytes; == REGISTER_RAW_SIZE (regnum); at present. */
+ /* long size in bytes; == DEPRECATED_REGISTER_RAW_SIZE (regnum); at present. */
/* char *name; == REGISTER_NAME (regnum); at present. */
};
init_remote_state (struct gdbarch *gdbarch)
{
int regnum;
- struct remote_state *rs = xmalloc (sizeof (struct remote_state));
+ struct remote_state *rs = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct remote_state);
- /* Start out by having the remote protocol mimic the existing
- behavour - just copy in the description of the register cache. */
- rs->sizeof_g_packet = REGISTER_BYTES; /* OK use. */
+ if (DEPRECATED_REGISTER_BYTES != 0)
+ rs->sizeof_g_packet = DEPRECATED_REGISTER_BYTES;
+ else
+ rs->sizeof_g_packet = 0;
/* Assume a 1:1 regnum<->pnum table. */
- rs->regs = xcalloc (NUM_REGS + NUM_PSEUDO_REGS, sizeof (struct packet_reg));
+ rs->regs = GDBARCH_OBSTACK_CALLOC (gdbarch, NUM_REGS + NUM_PSEUDO_REGS,
+ struct packet_reg);
for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
{
struct packet_reg *r = &rs->regs[regnum];
r->pnum = regnum;
r->regnum = regnum;
- r->offset = REGISTER_BYTE (regnum);
+ r->offset = DEPRECATED_REGISTER_BYTE (regnum);
r->in_g_packet = (regnum < NUM_REGS);
- /* ...size = REGISTER_RAW_SIZE (regnum); */
/* ...name = REGISTER_NAME (regnum); */
+
+ /* Compute packet size by accumulating the size of all registers. */
+ if (DEPRECATED_REGISTER_BYTES == 0)
+ rs->sizeof_g_packet += register_size (current_gdbarch, regnum);
}
/* Default maximum number of characters in a packet body. Many
little. */
if (rs->sizeof_g_packet > ((rs->remote_packet_size - 32) / 2))
rs->remote_packet_size = (rs->sizeof_g_packet * 2 + 32);
-
+
/* This one is filled in when a ``g'' packet is received. */
rs->actual_register_packet_size = 0;
return rs;
}
-static void
-free_remote_state (struct gdbarch *gdbarch, void *pointer)
-{
- struct remote_state *data = pointer;
- xfree (data->regs);
- xfree (data);
-}
-
static struct packet_reg *
packet_reg_from_regnum (struct remote_state *rs, long regnum)
{
starts. */
static struct serial *remote_desc = NULL;
-/* This is set by the target (thru the 'S' message)
- to denote that the target is in kernel mode. */
-static int cisco_kernel_mode = 0;
-
/* This variable sets the number of bits in an address that are to be
sent in a memory ("M" or "m") packet. Normally, after stripping
leading zeros, the entire address would be sent. This variable
}
}
-/* Should we try the 'qSymbol' (target symbol lookup service) request? */
-static struct packet_config remote_protocol_qSymbol;
-
-static void
-set_remote_protocol_qSymbol_packet_cmd (char *args, int from_tty,
- struct cmd_list_element *c)
-{
- update_packet_config (&remote_protocol_qSymbol);
-}
-
-static void
-show_remote_protocol_qSymbol_packet_cmd (char *args, int from_tty,
- struct cmd_list_element *c)
-{
- show_packet_config_cmd (&remote_protocol_qSymbol);
-}
-
-/* Should we try the 'e' (step over range) request? */
-static struct packet_config remote_protocol_e;
+/* Should we try the 'vCont' (descriptive resume) request? */
+static struct packet_config remote_protocol_vcont;
static void
-set_remote_protocol_e_packet_cmd (char *args, int from_tty,
- struct cmd_list_element *c)
+set_remote_protocol_vcont_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
{
- update_packet_config (&remote_protocol_e);
+ update_packet_config (&remote_protocol_vcont);
}
static void
-show_remote_protocol_e_packet_cmd (char *args, int from_tty,
- struct cmd_list_element *c)
+show_remote_protocol_vcont_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
{
- show_packet_config_cmd (&remote_protocol_e);
+ show_packet_config_cmd (&remote_protocol_vcont);
}
-
-/* Should we try the 'E' (step over range / w signal #) request? */
-static struct packet_config remote_protocol_E;
+/* Should we try the 'qSymbol' (target symbol lookup service) request? */
+static struct packet_config remote_protocol_qSymbol;
static void
-set_remote_protocol_E_packet_cmd (char *args, int from_tty,
+set_remote_protocol_qSymbol_packet_cmd (char *args, int from_tty,
struct cmd_list_element *c)
{
- update_packet_config (&remote_protocol_E);
+ update_packet_config (&remote_protocol_qSymbol);
}
static void
-show_remote_protocol_E_packet_cmd (char *args, int from_tty,
- struct cmd_list_element *c)
+show_remote_protocol_qSymbol_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
{
- show_packet_config_cmd (&remote_protocol_E);
+ show_packet_config_cmd (&remote_protocol_qSymbol);
}
-
/* Should we try the 'P' (set register) request? */
This variable (NOT available to the user: auto-detect only!)
determines whether GDB will use the new, simpler "ThreadInfo"
query or the older, more complex syntax for thread queries.
- This is an auto-detect variable (set to true at each connect,
+ This is an auto-detect variable (set to true at each connect,
and set to false when the target fails to recognize it). */
static int use_threadinfo_query;
show_packet_config_cmd (&remote_protocol_binary_download);
}
+/* Should we try the 'qPart:auxv' (target auxiliary vector read) request? */
+static struct packet_config remote_protocol_qPart_auxv;
+
+static void
+set_remote_protocol_qPart_auxv_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ update_packet_config (&remote_protocol_qPart_auxv);
+}
+
+static void
+show_remote_protocol_qPart_auxv_packet_cmd (char *args, int from_tty,
+ struct cmd_list_element *c)
+{
+ show_packet_config_cmd (&remote_protocol_qPart_auxv);
+}
+
/* Tokens for use by the asynchronous signal handlers for SIGINT */
static void *sigint_remote_twice_token;
/* These are pointers to hook functions that may be set in order to
modify resume/wait behavior for a particular architecture. */
-void (*target_resume_hook) (void);
-void (*target_wait_loop_hook) (void);
+void (*deprecated_target_resume_hook) (void);
+void (*deprecated_target_wait_loop_hook) (void);
\f
static int remote_get_threadinfo (threadref * threadid, int fieldset, /*TAG mask */
struct gdb_ext_thread_info *info);
-static int adapt_remote_get_threadinfo (gdb_threadref * ref,
- int selection,
- struct gdb_ext_thread_info *info);
-
static char *pack_threadlist_request (char *pkt, int startflag,
int threadcount,
threadref * nextthread);
fetch registers and its stack */
#define TAG_DISPLAY 4 /* A short thing maybe to put on a window */
#define TAG_THREADNAME 8 /* string, maps 1-to-1 with a thread is */
-#define TAG_MOREDISPLAY 16 /* Whatever the kernel wants to say about
+#define TAG_MOREDISPLAY 16 /* Whatever the kernel wants to say about
the process */
static int
return result;
}
-/* Unfortunately, 61 bit thread-ids are bigger than the internal
- representation of a threadid. */
-
-static int
-adapt_remote_get_threadinfo (gdb_threadref *ref, int selection,
- struct gdb_ext_thread_info *info)
-{
- threadref lclref;
-
- int_to_threadref (&lclref, *ref);
- return remote_get_threadinfo (&lclref, selection, info);
-}
-
/* Format: i'Q':8,i"L":8,initflag:8,batchsize:16,lastthreadid:32 */
static char *
return oldpid;
}
-/* Find new threads for info threads command.
- * Original version, using John Metzler's thread protocol.
+/* Find new threads for info threads command.
+ * Original version, using John Metzler's thread protocol.
*/
static void
bufp = buf;
getpkt (bufp, (rs->remote_packet_size), 0);
if (bufp[0] != '\0') /* q packet recognized */
- {
+ {
while (*bufp++ == 'm') /* reply contains one or more TID */
{
do
return;
}
-/*
+/*
* Collect a descriptive string about the given thread.
* The target may say anything it wants to about the thread
* (typically info about its blocked / runnable state, name, etc.).
* This string will appear in the info threads display.
- *
+ *
* Optional: targets are not required to implement this function.
*/
\f
/* Clean up connection to a remote debugger. */
-/* ARGSUSED */
static void
remote_close (int quitting)
{
if (symfile_objfile == NULL)
return;
- offs = (struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS);
- memcpy (offs, symfile_objfile->section_offsets, SIZEOF_SECTION_OFFSETS);
+ offs = ((struct section_offsets *)
+ alloca (SIZEOF_N_SECTION_OFFSETS (symfile_objfile->num_sections)));
+ memcpy (offs, symfile_objfile->section_offsets,
+ SIZEOF_N_SECTION_OFFSETS (symfile_objfile->num_sections));
offs->offsets[SECT_OFF_TEXT (symfile_objfile)] = text_addr;
objfile_relocate (symfile_objfile, offs);
}
-/*
- * Cisco version of section offsets:
- *
- * Instead of having GDB query the target for the section offsets,
- * Cisco lets the target volunteer the information! It's also in
- * a different format, so here are the functions that will decode
- * a section offset packet from a Cisco target.
- */
-
-/*
- * Function: remote_cisco_section_offsets
- *
- * Returns: zero for success, non-zero for failure
- */
-
-static int
-remote_cisco_section_offsets (bfd_vma text_addr,
- bfd_vma data_addr,
- bfd_vma bss_addr,
- bfd_signed_vma *text_offs,
- bfd_signed_vma *data_offs,
- bfd_signed_vma *bss_offs)
-{
- bfd_vma text_base, data_base, bss_base;
- struct minimal_symbol *start;
- asection *sect;
- bfd *abfd;
- int len;
-
- if (symfile_objfile == NULL)
- return -1; /* no can do nothin' */
-
- start = lookup_minimal_symbol ("_start", NULL, NULL);
- if (start == NULL)
- return -1; /* Can't find "_start" symbol */
-
- data_base = bss_base = 0;
- text_base = SYMBOL_VALUE_ADDRESS (start);
-
- abfd = symfile_objfile->obfd;
- for (sect = abfd->sections;
- sect != 0;
- sect = sect->next)
- {
- 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 ||
- data_base > bfd_get_section_vma (abfd, sect))
- data_base = bfd_get_section_vma (abfd, sect);
- if (strcmp (p + len - 3, "bss") == 0) /* ends in "bss" */
- if (bss_base == 0 ||
- bss_base > bfd_get_section_vma (abfd, sect))
- bss_base = bfd_get_section_vma (abfd, sect);
- }
- *text_offs = text_addr - text_base;
- *data_offs = data_addr - data_base;
- *bss_offs = bss_addr - bss_base;
- if (remote_debug)
- {
- char tmp[128];
-
- sprintf (tmp, "VMA: text = 0x");
- sprintf_vma (tmp + strlen (tmp), text_addr);
- sprintf (tmp + strlen (tmp), " data = 0x");
- sprintf_vma (tmp + strlen (tmp), data_addr);
- sprintf (tmp + strlen (tmp), " bss = 0x");
- sprintf_vma (tmp + strlen (tmp), bss_addr);
- fprintf_filtered (gdb_stdlog, tmp);
- fprintf_filtered (gdb_stdlog,
- "Reloc offset: text = 0x%s data = 0x%s bss = 0x%s\n",
- paddr_nz (*text_offs),
- paddr_nz (*data_offs),
- paddr_nz (*bss_offs));
- }
-
- return 0;
-}
-
-/*
- * Function: remote_cisco_objfile_relocate
- *
- * Relocate the symbol file for a remote target.
- */
-
-void
-remote_cisco_objfile_relocate (bfd_signed_vma text_off, bfd_signed_vma data_off,
- bfd_signed_vma bss_off)
-{
- struct section_offsets *offs;
-
- if (text_off != 0 || data_off != 0 || bss_off != 0)
- {
- /* FIXME: This code assumes gdb-stabs.h is being used; it's
- broken for xcoff, dwarf, sdb-coff, etc. But there is no
- simple canonical representation for this stuff. */
-
- offs = (struct section_offsets *) alloca (SIZEOF_SECTION_OFFSETS);
- memcpy (offs, symfile_objfile->section_offsets, SIZEOF_SECTION_OFFSETS);
-
- offs->offsets[SECT_OFF_TEXT (symfile_objfile)] = text_off;
- offs->offsets[SECT_OFF_DATA (symfile_objfile)] = data_off;
- offs->offsets[SECT_OFF_BSS (symfile_objfile)] = bss_off;
-
- /* First call the standard objfile_relocate. */
- objfile_relocate (symfile_objfile, offs);
-
- /* Now we need to fix up the section entries already attached to
- the exec target. These entries will control memory transfers
- from the exec file. */
-
- exec_set_section_offsets (text_off, data_off, bss_off);
- }
-}
-
/* Stub for catch_errors. */
static int
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);
update_packet_config (&remote_protocol_qSymbol);
+ update_packet_config (&remote_protocol_vcont);
for (i = 0; i < NR_Z_PACKET_TYPES; i++)
update_packet_config (&remote_protocol_Z[i]);
/* Force remote_write_bytes to check whether target supports binary
downloading. */
update_packet_config (&remote_protocol_binary_download);
+ update_packet_config (&remote_protocol_qPart_auxv);
}
/* Symbol look-up. */
if (sym == NULL)
sprintf (msg, "qSymbol::%s", &reply[8]);
else
- sprintf (msg, "qSymbol:%s:%s",
+ sprintf (msg, "qSymbol:%s:%s",
paddr_nz (SYMBOL_VALUE_ADDRESS (sym)),
&reply[8]);
putpkt (msg);
if (!async_p)
wait_forever_enabled_p = 1;
+ reopen_exec_file ();
+ reread_symbols ();
+
target_preopen (from_tty);
unpush_target (target);
{
if (serial_setbaudrate (remote_desc, baud_rate))
{
+ /* The requested speed could not be set. Error out to
+ top level after closing remote_desc. Take care to
+ set remote_desc to NULL to avoid closing remote_desc
+ more than once. */
serial_close (remote_desc);
+ remote_desc = NULL;
perror_with_name (name);
}
}
push_target (target); /* Switch to using remote target now */
init_all_packet_configs ();
-
+
general_thread = -2;
continue_thread = -2;
FIXME: cagney/2002-05-19: Instead of re-throwing the exception,
this function should return an error indication letting the
- caller restore the previous state. Unfortunatly the command
+ caller restore the previous state. Unfortunately the command
``target remote'' is directly wired to this function making that
impossible. On a positive note, the CLI side of this problem has
been fixed - the function set_cmd_context() makes it possible for
getpkt (buf, (rs->remote_packet_size), 0);
}
#ifdef SOLIB_CREATE_INFERIOR_HOOK
- /* FIXME: need a master target_open vector from which all
- remote_opens can be called, so that stuff like this can
+ /* 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
+ to the open function for any remote target that wants to
support svr4 shared libraries. */
/* Set up to detect and load shared libraries. */
strcpy (buf, "D");
remote_send (buf, (rs->remote_packet_size));
+ /* Unregister the file descriptor from the event loop. */
+ if (target_is_async_p ())
+ serial_async (remote_desc, NULL, 0);
+
target_mourn_inferior ();
if (from_tty)
puts_filtered ("Ending remote debugging.\n");
-
}
-/* Same as remote_detach, but with async support. */
+/* Same as remote_detach, but don't send the "D" packet; just disconnect. */
+
static void
-remote_async_detach (char *args, int from_tty)
+remote_disconnect (char *args, int from_tty)
{
struct remote_state *rs = get_remote_state ();
char *buf = alloca (rs->remote_packet_size);
if (args)
error ("Argument given to \"detach\" when remotely debugging.");
- /* Tell the remote target to detach. */
- strcpy (buf, "D");
- remote_send (buf, (rs->remote_packet_size));
-
/* Unregister the file descriptor from the event loop. */
if (target_is_async_p ())
serial_async (remote_desc, NULL, 0);
return i;
}
\f
-/* Tell the remote machine to resume. */
+/* Check for the availability of vCont. This function should also check
+ the response. */
-static enum target_signal last_sent_signal = TARGET_SIGNAL_0;
+static void
+remote_vcont_probe (struct remote_state *rs, char *buf)
+{
+ strcpy (buf, "vCont?");
+ putpkt (buf);
+ getpkt (buf, rs->remote_packet_size, 0);
-static int last_sent_step;
+ /* Make sure that the features we assume are supported. */
+ if (strncmp (buf, "vCont", 5) == 0)
+ {
+ char *p = &buf[5];
+ int support_s, support_S, support_c, support_C;
+
+ support_s = 0;
+ support_S = 0;
+ support_c = 0;
+ support_C = 0;
+ while (p && *p == ';')
+ {
+ p++;
+ if (*p == 's' && (*(p + 1) == ';' || *(p + 1) == 0))
+ support_s = 1;
+ else if (*p == 'S' && (*(p + 1) == ';' || *(p + 1) == 0))
+ support_S = 1;
+ else if (*p == 'c' && (*(p + 1) == ';' || *(p + 1) == 0))
+ support_c = 1;
+ else if (*p == 'C' && (*(p + 1) == ';' || *(p + 1) == 0))
+ support_C = 1;
+
+ p = strchr (p, ';');
+ }
-static void
-remote_resume (ptid_t ptid, int step, enum target_signal siggnal)
+ /* If s, S, c, and C are not all supported, we can't use vCont. Clearing
+ BUF will make packet_ok disable the packet. */
+ if (!support_s || !support_S || !support_c || !support_C)
+ buf[0] = 0;
+ }
+
+ packet_ok (buf, &remote_protocol_vcont);
+}
+
+/* Resume the remote inferior by using a "vCont" packet. The thread
+ to be resumed is PTID; STEP and SIGGNAL indicate whether the
+ resumed thread should be single-stepped and/or signalled. If PTID's
+ PID is -1, then all threads are resumed; the thread to be stepped and/or
+ signalled is given in the global INFERIOR_PTID. This function returns
+ non-zero iff it resumes the inferior.
+
+ This function issues a strict subset of all possible vCont commands at the
+ moment. */
+
+static int
+remote_vcont_resume (ptid_t ptid, int step, enum target_signal siggnal)
{
struct remote_state *rs = get_remote_state ();
- char *buf = alloca (rs->remote_packet_size);
int pid = PIDGET (ptid);
- char *p;
-
- if (pid == -1)
- set_thread (0, 0); /* run any thread */
- else
- set_thread (pid, 0); /* run this thread */
+ char *buf = NULL, *outbuf;
+ struct cleanup *old_cleanup;
- last_sent_signal = siggnal;
- last_sent_step = step;
+ buf = xmalloc (rs->remote_packet_size);
+ old_cleanup = make_cleanup (xfree, buf);
- /* A hook for when we need to do something at the last moment before
- resumption. */
- if (target_resume_hook)
- (*target_resume_hook) ();
+ if (remote_protocol_vcont.support == PACKET_SUPPORT_UNKNOWN)
+ remote_vcont_probe (rs, buf);
+ if (remote_protocol_vcont.support == PACKET_DISABLE)
+ {
+ do_cleanups (old_cleanup);
+ return 0;
+ }
- /* 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 we could generate a wider range of packets, we'd have to worry
+ about overflowing BUF. Should there be a generic
+ "multi-part-packet" packet? */
- if (step && step_range_end)
+ if (PIDGET (inferior_ptid) == MAGIC_NULL_PID)
{
- /* 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, (rs->remote_packet_size), 0);
-
- if (packet_ok (buf, &remote_protocol_E) == PACKET_OK)
- return;
- }
- }
+ /* MAGIC_NULL_PTID means that we don't have any active threads, so we
+ don't have any PID numbers the inferior will understand. Make sure
+ to only send forms that do not specify a PID. */
+ if (step && siggnal != TARGET_SIGNAL_0)
+ outbuf = xstrprintf ("vCont;S%02x", siggnal);
+ else if (step)
+ outbuf = xstrprintf ("vCont;s");
+ else if (siggnal != TARGET_SIGNAL_0)
+ outbuf = xstrprintf ("vCont;C%02x", siggnal);
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, (rs->remote_packet_size), 0);
-
- if (packet_ok (buf, &remote_protocol_e) == PACKET_OK)
- return;
- }
- }
+ outbuf = xstrprintf ("vCont;c");
}
-
- if (siggnal != TARGET_SIGNAL_0)
+ else if (pid == -1)
{
- buf[0] = step ? 'S' : 'C';
- buf[1] = tohex (((int) siggnal >> 4) & 0xf);
- buf[2] = tohex (((int) siggnal) & 0xf);
- buf[3] = '\0';
+ /* Resume all threads, with preference for INFERIOR_PTID. */
+ if (step && siggnal != TARGET_SIGNAL_0)
+ outbuf = xstrprintf ("vCont;S%02x:%x;c", siggnal,
+ PIDGET (inferior_ptid));
+ else if (step)
+ outbuf = xstrprintf ("vCont;s:%x;c", PIDGET (inferior_ptid));
+ else if (siggnal != TARGET_SIGNAL_0)
+ outbuf = xstrprintf ("vCont;C%02x:%x;c", siggnal,
+ PIDGET (inferior_ptid));
+ else
+ outbuf = xstrprintf ("vCont;c");
}
else
- strcpy (buf, step ? "s" : "c");
+ {
+ /* Scheduler locking; resume only PTID. */
+ if (step && siggnal != TARGET_SIGNAL_0)
+ outbuf = xstrprintf ("vCont;S%02x:%x", siggnal, pid);
+ else if (step)
+ outbuf = xstrprintf ("vCont;s:%x", pid);
+ else if (siggnal != TARGET_SIGNAL_0)
+ outbuf = xstrprintf ("vCont;C%02x:%x", siggnal, pid);
+ else
+ outbuf = xstrprintf ("vCont;c:%x", pid);
+ }
- putpkt (buf);
+ gdb_assert (outbuf && strlen (outbuf) < rs->remote_packet_size);
+ make_cleanup (xfree, outbuf);
+
+ putpkt (outbuf);
+
+ do_cleanups (old_cleanup);
+
+ return 1;
}
-/* Same as remote_resume, but with async support. */
+/* Tell the remote machine to resume. */
+
+static enum target_signal last_sent_signal = TARGET_SIGNAL_0;
+
+static int last_sent_step;
+
static void
-remote_async_resume (ptid_t ptid, int step, enum target_signal siggnal)
+remote_resume (ptid_t ptid, int step, enum target_signal siggnal)
{
struct remote_state *rs = get_remote_state ();
char *buf = alloca (rs->remote_packet_size);
int pid = PIDGET (ptid);
char *p;
- if (pid == -1)
- set_thread (0, 0); /* run any thread */
- else
- set_thread (pid, 0); /* run this thread */
-
last_sent_signal = siggnal;
last_sent_step = step;
/* A hook for when we need to do something at the last moment before
resumption. */
- if (target_resume_hook)
- (*target_resume_hook) ();
+ if (deprecated_target_resume_hook)
+ (*deprecated_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. */
+ /* The vCont packet doesn't need to specify threads via Hc. */
+ if (remote_vcont_resume (ptid, step, siggnal))
+ return;
- 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, (rs->remote_packet_size), 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, (rs->remote_packet_size), 0);
-
- if (packet_ok (buf, &remote_protocol_e) == PACKET_OK)
- goto register_event_loop;
- }
- }
- }
+ /* All other supported resume packets do use Hc, so call set_thread. */
+ if (pid == -1)
+ set_thread (0, 0); /* run any thread */
+ else
+ set_thread (pid, 0); /* run this thread */
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
strcpy (buf, step ? "s" : "c");
-
+
putpkt (buf);
+}
+
+/* Same as remote_resume, but with async support. */
+static void
+remote_async_resume (ptid_t ptid, int step, enum target_signal siggnal)
+{
+ remote_resume (ptid, step, siggnal);
-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
/* Wait until the remote machine stops, then return,
storing status in STATUS just as `wait' would.
- Returns "pid", which in the case of a multi-threaded
+ Returns "pid", which in the case of a multi-threaded
remote OS, is the thread-id. */
static ptid_t
/* This is a hook for when we need to do something (perhaps the
collection of trace data) every time the target stops. */
- if (target_wait_loop_hook)
- (*target_wait_loop_hook) ();
+ if (deprecated_target_wait_loop_hook)
+ (*deprecated_target_wait_loop_hook) ();
remote_stopped_by_watchpoint_p = 0;
case 'E': /* Error of some sort */
warning ("Remote failure reply: %s", buf);
continue;
+ case 'F': /* File-I/O request */
+ remote_fileio_request (buf);
+ continue;
case 'T': /* Status with PC, SP, FP, ... */
{
int i;
LONGEST pnum = 0;
/* If the packet contains a register number save it in pnum
- and set p1 to point to the character following it.
+ and set p1 to point to the character following it.
Otherwise p1 points to p. */
/* If this packet is an awatch packet, don't parse the 'a'
pnum = strtol (p, &p_temp, 16);
p1 = (unsigned char *) p_temp;
}
- else
+ else
p1 = p;
if (p1 == p) /* No register number present here */
p = p1;
if (*p++ != ':')
- warning ("Malformed packet(b) (missing colon): %s\n\
-Packet: '%s'\n",
- p, buf);
+ error ("Malformed packet(b) (missing colon): %s\nPacket: '%s'\n",
+ p, buf);
if (reg == NULL)
- warning ("Remote sent bad register number %s: %s\n\
-Packet: '%s'\n",
- phex_nz (pnum, 0), p, buf);
+ error ("Remote sent bad register number %s: %s\nPacket: '%s'\n",
+ phex_nz (pnum, 0), p, buf);
- fieldsize = hex2bin (p, regs, REGISTER_RAW_SIZE (reg->regnum));
+ fieldsize = hex2bin (p, regs, DEPRECATED_REGISTER_RAW_SIZE (reg->regnum));
p += 2 * fieldsize;
- if (fieldsize < REGISTER_RAW_SIZE (reg->regnum))
+ if (fieldsize < DEPRECATED_REGISTER_RAW_SIZE (reg->regnum))
warning ("Remote reply is too short: %s", buf);
supply_register (reg->regnum, regs);
}
if (*p++ != ';')
- {
- warning ("Remote register badly formatted: %s", buf);
- warning (" here: %s", p);
- }
+ error ("Remote register badly formatted: %s\nhere: %s", buf, p);
}
}
/* fall through */
if (buf[3] == 'p')
{
- /* Export Cisco kernel mode as a convenience variable
- (so that it can be used in the GDB prompt if desired). */
-
- if (cisco_kernel_mode == 1)
- set_internalvar (lookup_internalvar ("cisco_kernel_mode"),
- value_from_string ("PDEBUG-"));
- cisco_kernel_mode = 0;
thread_num = strtol ((const char *) &buf[4], NULL, 16);
record_currthread (thread_num);
}
- else if (buf[3] == 'k')
- {
- /* Export Cisco kernel mode as a convenience variable
- (so that it can be used in the GDB prompt if desired). */
-
- if (cisco_kernel_mode == 1)
- set_internalvar (lookup_internalvar ("cisco_kernel_mode"),
- value_from_string ("KDEBUG-"));
- cisco_kernel_mode = 1;
- }
goto got_status;
- case 'N': /* Cisco special: status and offsets */
- {
- bfd_vma text_addr, data_addr, bss_addr;
- bfd_signed_vma text_off, data_off, bss_off;
- unsigned char *p1;
-
- status->kind = TARGET_WAITKIND_STOPPED;
- status->value.sig = (enum target_signal)
- (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
-
- if (symfile_objfile == NULL)
- {
- warning ("Relocation packet received with no symbol file. \
-Packet Dropped");
- goto got_status;
- }
-
- /* Relocate object file. Buffer format is NAATT;DD;BB
- * where AA is the signal number, TT is the new text
- * address, DD * is the new data address, and BB is the
- * new bss address. */
-
- p = &buf[3];
- text_addr = strtoul (p, (char **) &p1, 16);
- if (p1 == p || *p1 != ';')
- warning ("Malformed relocation packet: Packet '%s'", buf);
- p = p1 + 1;
- data_addr = strtoul (p, (char **) &p1, 16);
- if (p1 == p || *p1 != ';')
- warning ("Malformed relocation packet: Packet '%s'", buf);
- p = p1 + 1;
- bss_addr = strtoul (p, (char **) &p1, 16);
- if (p1 == p)
- warning ("Malformed relocation packet: Packet '%s'", buf);
-
- if (remote_cisco_section_offsets (text_addr, data_addr, bss_addr,
- &text_off, &data_off, &bss_off)
- == 0)
- if (text_off != 0 || data_off != 0 || bss_off != 0)
- remote_cisco_objfile_relocate (text_off, data_off, bss_off);
-
- goto got_status;
- }
case 'W': /* Target exited */
{
/* The remote process exited. */
/* This is a hook for when we need to do something (perhaps the
collection of trace data) every time the target stops. */
- if (target_wait_loop_hook)
- (*target_wait_loop_hook) ();
+ if (deprecated_target_wait_loop_hook)
+ (*deprecated_target_wait_loop_hook) ();
switch (buf[0])
{
case 'E': /* Error of some sort */
warning ("Remote failure reply: %s", buf);
continue;
+ case 'F': /* File-I/O request */
+ remote_fileio_request (buf);
+ continue;
case 'T': /* Status with PC, SP, FP, ... */
{
int i;
long pnum = 0;
/* If the packet contains a register number, save it in pnum
- and set p1 to point to the character following it.
+ and set p1 to point to the character following it.
Otherwise p1 points to p. */
/* If this packet is an awatch packet, don't parse the 'a'
as a register number. */
-
+
if (!strncmp (p, "awatch", strlen ("awatch")) != 0)
{
/* Read the register number. */
pnum = strtol (p, &p_temp, 16);
p1 = (unsigned char *) p_temp;
}
- else
+ else
p1 = p;
if (p1 == p) /* No register number present here */
{
p1 = (unsigned char *) strchr (p, ':');
if (p1 == NULL)
- warning ("Malformed packet(a) (missing colon): %s\n\
-Packet: '%s'\n",
- p, buf);
+ error ("Malformed packet(a) (missing colon): %s\nPacket: '%s'\n",
+ p, buf);
if (strncmp (p, "thread", p1 - p) == 0)
{
p_temp = unpack_varlen_hex (++p1, &thread_num);
p = p_temp;
}
}
-
+
else
{
struct packet_reg *reg = packet_reg_from_pnum (rs, pnum);
p = p1;
if (*p++ != ':')
- warning ("Malformed packet(b) (missing colon): %s\n\
-Packet: '%s'\n",
- p, buf);
+ error ("Malformed packet(b) (missing colon): %s\nPacket: '%s'\n",
+ p, buf);
if (reg == NULL)
- warning ("Remote sent bad register number %ld: %s\n\
-Packet: '%s'\n",
- pnum, p, buf);
+ error ("Remote sent bad register number %ld: %s\nPacket: '%s'\n",
+ pnum, p, buf);
- fieldsize = hex2bin (p, regs, REGISTER_RAW_SIZE (reg->regnum));
+ fieldsize = hex2bin (p, regs, DEPRECATED_REGISTER_RAW_SIZE (reg->regnum));
p += 2 * fieldsize;
- if (fieldsize < REGISTER_RAW_SIZE (reg->regnum))
+ if (fieldsize < DEPRECATED_REGISTER_RAW_SIZE (reg->regnum))
warning ("Remote reply is too short: %s", buf);
supply_register (reg->regnum, regs);
}
if (*p++ != ';')
- {
- warning ("Remote register badly formatted: %s", buf);
- warning (" here: %s", p);
- }
+ error ("Remote register badly formatted: %s\nhere: %s",
+ buf, p);
}
}
/* fall through */
if (buf[3] == 'p')
{
- /* Export Cisco kernel mode as a convenience variable
- (so that it can be used in the GDB prompt if desired). */
-
- if (cisco_kernel_mode == 1)
- set_internalvar (lookup_internalvar ("cisco_kernel_mode"),
- value_from_string ("PDEBUG-"));
- cisco_kernel_mode = 0;
thread_num = strtol ((const char *) &buf[4], NULL, 16);
record_currthread (thread_num);
}
- else if (buf[3] == 'k')
- {
- /* Export Cisco kernel mode as a convenience variable
- (so that it can be used in the GDB prompt if desired). */
-
- if (cisco_kernel_mode == 1)
- set_internalvar (lookup_internalvar ("cisco_kernel_mode"),
- value_from_string ("KDEBUG-"));
- cisco_kernel_mode = 1;
- }
goto got_status;
- case 'N': /* Cisco special: status and offsets */
- {
- bfd_vma text_addr, data_addr, bss_addr;
- bfd_signed_vma text_off, data_off, bss_off;
- unsigned char *p1;
-
- status->kind = TARGET_WAITKIND_STOPPED;
- status->value.sig = (enum target_signal)
- (((fromhex (buf[1])) << 4) + (fromhex (buf[2])));
-
- if (symfile_objfile == NULL)
- {
- warning ("Relocation packet recieved with no symbol file. \
-Packet Dropped");
- goto got_status;
- }
-
- /* Relocate object file. Buffer format is NAATT;DD;BB
- * where AA is the signal number, TT is the new text
- * address, DD * is the new data address, and BB is the
- * new bss address. */
-
- p = &buf[3];
- text_addr = strtoul (p, (char **) &p1, 16);
- if (p1 == p || *p1 != ';')
- warning ("Malformed relocation packet: Packet '%s'", buf);
- p = p1 + 1;
- data_addr = strtoul (p, (char **) &p1, 16);
- if (p1 == p || *p1 != ';')
- warning ("Malformed relocation packet: Packet '%s'", buf);
- p = p1 + 1;
- bss_addr = strtoul (p, (char **) &p1, 16);
- if (p1 == p)
- warning ("Malformed relocation packet: Packet '%s'", buf);
-
- if (remote_cisco_section_offsets (text_addr, data_addr, bss_addr,
- &text_off, &data_off, &bss_off)
- == 0)
- if (text_off != 0 || data_off != 0 || bss_off != 0)
- remote_cisco_objfile_relocate (text_off, data_off, bss_off);
-
- goto got_status;
- }
case 'W': /* Target exited */
{
/* The remote process exited. */
/* Read the remote registers into the block REGS. */
/* Currently we just read all the registers, so we don't use regnum. */
-/* ARGSUSED */
static void
remote_fetch_registers (int regnum)
{
struct packet_reg *r = &rs->regs[i];
if (r->in_g_packet)
{
- supply_register (r->regnum, regs + r->offset);
- if (buf[r->offset * 2] == 'x')
- set_register_cached (i, -1);
+ if (r->offset * 2 >= strlen (buf))
+ /* A short packet that didn't include the register's
+ value, this implies that the register is zero (and
+ not that the register is unavailable). Supply that
+ zero value. */
+ regcache_raw_supply (current_regcache, r->regnum, NULL);
+ else if (buf[r->offset * 2] == 'x')
+ {
+ gdb_assert (r->offset * 2 < strlen (buf));
+ /* The register isn't available, mark it as such (at
+ the same time setting the value to zero). */
+ regcache_raw_supply (current_regcache, r->regnum, NULL);
+ set_register_cached (i, -1);
+ }
+ else
+ regcache_raw_supply (current_regcache, r->regnum,
+ regs + r->offset);
}
}
}
static void
remote_prepare_to_store (void)
{
+ struct remote_state *rs = get_remote_state ();
+ int i;
+ char buf[MAX_REGISTER_SIZE];
+
/* Make sure the entire registers array is valid. */
switch (remote_protocol_P.support)
{
case PACKET_DISABLE:
case PACKET_SUPPORT_UNKNOWN:
- /* NOTE: This isn't rs->sizeof_g_packet because here, we are
- forcing the register cache to read its and not the target
- registers. */
- deprecated_read_register_bytes (0, (char *) NULL,
- REGISTER_BYTES); /* OK use. */
+ /* Make sure all the necessary registers are cached. */
+ for (i = 0; i < NUM_REGS; i++)
+ if (rs->regs[i].in_g_packet)
+ regcache_raw_read (current_regcache, rs->regs[i].regnum, buf);
break;
case PACKET_ENABLE:
break;
sprintf (buf, "P%s=", phex_nz (reg->pnum, 0));
p = buf + strlen (buf);
regcache_collect (reg->regnum, regp);
- bin2hex (regp, p, REGISTER_RAW_SIZE (reg->regnum));
+ bin2hex (regp, p, DEPRECATED_REGISTER_RAW_SIZE (reg->regnum));
remote_send (buf, rs->remote_packet_size);
return buf[0] != '\0';
{
char *buf = alloca (rs->remote_packet_size);
char *p;
-
+
p = buf;
*p++ = 'X';
p += hexnumstr (p, (ULONGEST) addr);
p += hexnumstr (p, (ULONGEST) 0);
*p++ = ':';
*p = '\0';
-
+
putpkt_binary (buf, (int) (p - buf));
getpkt (buf, (rs->remote_packet_size), 0);
Returns number of bytes transferred, or 0 (setting errno) for
error. Only transfer a single packet. */
-static int
+int
remote_write_bytes (CORE_ADDR memaddr, char *myaddr, int len)
{
unsigned char *buf;
- int max_buf_size; /* Max size of packet output buffer */
unsigned char *p;
unsigned char *plen;
long sizeof_buf;
int plenlen;
int todo;
int nr_bytes;
+ int payload_size;
+ unsigned char *payload_start;
- /* Verify that the target can support a binary download */
+ /* Verify that the target can support a binary download. */
check_binary_download (memaddr);
- /* Determine the max packet size. */
- max_buf_size = get_memory_write_packet_size ();
- sizeof_buf = max_buf_size + 1; /* Space for trailing NUL */
+ /* Compute the size, and then allocate space for the largest
+ possible packet. Include space for an extra trailing NUL. */
+ sizeof_buf = get_memory_write_packet_size () + 1;
buf = alloca (sizeof_buf);
- /* Subtract header overhead from max payload size - $M<memaddr>,<len>:#nn */
- max_buf_size -= 2 + hexnumlen (memaddr + len - 1) + 1 + hexnumlen (len) + 4;
+ /* Compute the size of the actual payload by subtracting out the
+ packet header and footer overhead: "$M<memaddr>,<len>:...#nn". */
+ payload_size = (get_memory_write_packet_size () - (strlen ("$M,:#NN")
+ + hexnumlen (memaddr)
+ + hexnumlen (len)));
- /* construct "M"<memaddr>","<len>":" */
- /* sprintf (buf, "M%lx,%x:", (unsigned long) memaddr, todo); */
- p = buf;
+ /* Construct the packet header: "[MX]<memaddr>,<len>:". */
- /* Append [XM]. Compute a best guess of the number of bytes
+ /* Append "[XM]". Compute a best guess of the number of bytes
actually transfered. */
+ p = buf;
switch (remote_protocol_binary_download.support)
{
case PACKET_ENABLE:
*p++ = 'X';
/* Best guess at number of bytes that will fit. */
- todo = min (len, max_buf_size);
+ todo = min (len, payload_size);
break;
case PACKET_DISABLE:
*p++ = 'M';
/* num bytes that will fit */
- todo = min (len, max_buf_size / 2);
+ todo = min (len, payload_size / 2);
break;
case PACKET_SUPPORT_UNKNOWN:
internal_error (__FILE__, __LINE__,
default:
internal_error (__FILE__, __LINE__, "bad switch");
}
-
- /* Append <memaddr> */
+
+ /* Append "<memaddr>". */
memaddr = remote_address_masked (memaddr);
p += hexnumstr (p, (ULONGEST) memaddr);
+
+ /* Append ",". */
*p++ = ',';
-
- /* Append <len>. Retain the location/size of <len>. It may
- need to be adjusted once the packet body has been created. */
+
+ /* Append <len>. Retain the location/size of <len>. It may need to
+ be adjusted once the packet body has been created. */
plen = p;
plenlen = hexnumstr (p, (ULONGEST) todo);
p += plenlen;
+
+ /* Append ":". */
*p++ = ':';
*p = '\0';
-
- /* Append the packet body. */
+
+ /* Append the packet body. */
+ payload_start = p;
switch (remote_protocol_binary_download.support)
{
case PACKET_ENABLE:
increasing byte addresses. Only escape certain critical
characters. */
for (nr_bytes = 0;
- (nr_bytes < todo) && (p - buf) < (max_buf_size - 2);
+ (nr_bytes < todo) && (p - payload_start) < payload_size;
nr_bytes++)
{
switch (myaddr[nr_bytes] & 0xff)
}
if (nr_bytes < todo)
{
- /* Escape chars have filled up the buffer prematurely,
+ /* Escape chars have filled up the buffer prematurely,
and we have actually sent fewer bytes than planned.
Fix-up the length field of the packet. Use the same
number of characters as before. */
-
plen += hexnumnstr (plen, (ULONGEST) nr_bytes, plenlen);
*plen = ':'; /* overwrite \0 from hexnumnstr() */
}
default:
internal_error (__FILE__, __LINE__, "bad switch");
}
-
+
putpkt_binary (buf, (int) (p - buf));
getpkt (buf, sizeof_buf, 0);
-
+
if (buf[0] == 'E')
{
/* There is no correspondance between what the remote protocol
errno = EIO;
return 0;
}
-
+
/* Return NR_BYTES, not TODO, in case escape chars caused us to send fewer
bytes than we'd planned. */
return nr_bytes;
caller and its callers caller ;-) already contains code for
handling partial reads. */
-static int
+int
remote_read_bytes (CORE_ADDR memaddr, char *myaddr, int len)
{
char *buf;
SHOULD_WRITE is nonzero. Returns length of data written or read; 0
for error. TARGET is unused. */
-/* ARGSUSED */
static int
remote_xfer_memory (CORE_ADDR mem_addr, char *buffer, int mem_len,
int should_write, struct mem_attrib *attrib,
return res;
}
-
-#if 0
-/* Enable after 4.12. */
-
-void
-remote_search (int len, char *data, char *mask, CORE_ADDR startaddr,
- int increment, CORE_ADDR lorange, CORE_ADDR hirange,
- CORE_ADDR *addr_found, char *data_found)
-{
- if (increment == -4 && len == 4)
- {
- long mask_long, data_long;
- long data_found_long;
- CORE_ADDR addr_we_found;
- char *buf = alloca (rs->remote_packet_size);
- long returned_long[2];
- char *p;
-
- mask_long = extract_unsigned_integer (mask, len);
- data_long = extract_unsigned_integer (data, len);
- sprintf (buf, "t%x:%x,%x", startaddr, data_long, mask_long);
- putpkt (buf);
- getpkt (buf, (rs->remote_packet_size), 0);
- if (buf[0] == '\0')
- {
- /* The stub doesn't support the 't' request. We might want to
- remember this fact, but on the other hand the stub could be
- switched on us. Maybe we should remember it only until
- the next "target remote". */
- generic_search (len, data, mask, startaddr, increment, lorange,
- hirange, addr_found, data_found);
- return;
- }
-
- if (buf[0] == 'E')
- /* There is no correspondance between what the remote protocol uses
- for errors and errno codes. We would like a cleaner way of
- representing errors (big enough to include errno codes, bfd_error
- codes, and others). But for now just use EIO. */
- memory_error (EIO, startaddr);
- p = buf;
- addr_we_found = 0;
- while (*p != '\0' && *p != ',')
- addr_we_found = (addr_we_found << 4) + fromhex (*p++);
- if (*p == '\0')
- error ("Protocol error: short return for search");
-
- data_found_long = 0;
- while (*p != '\0' && *p != ',')
- data_found_long = (data_found_long << 4) + fromhex (*p++);
- /* Ignore anything after this comma, for future extensions. */
-
- if (addr_we_found < lorange || addr_we_found >= hirange)
- {
- *addr_found = 0;
- return;
- }
-
- *addr_found = addr_we_found;
- *data_found = store_unsigned_integer (data_we_found, len);
- return;
- }
- generic_search (len, data, mask, startaddr, increment, lorange,
- hirange, addr_found, data_found);
-}
-#endif /* 0 */
-\f
static void
remote_files_info (struct target_ops *ignore)
{
}
}
-static int remote_cisco_mode;
-
/* Come here after finding the start of the frame. Collect the rest
into BUF, verifying the checksum, length, and handling run-length
compression. No more than sizeof_buf-1 characters are read so that
check_0 = readchar (remote_timeout);
if (check_0 >= 0)
check_1 = readchar (remote_timeout);
-
+
if (check_0 == SERIAL_TIMEOUT || check_1 == SERIAL_TIMEOUT)
{
if (remote_debug)
int repeat;
csum += c;
- if (remote_cisco_mode == 0)
- {
- c = readchar (remote_timeout);
- csum += c;
- repeat = c - ' ' + 3; /* Compute repeat count */
- }
- else
- {
- /* Cisco's run-length encoding variant uses two
- hex chars to represent the repeat count. */
-
- c = readchar (remote_timeout);
- csum += c;
- repeat = fromhex (c) << 4;
- c = readchar (remote_timeout);
- csum += c;
- repeat += fromhex (c);
- }
+ c = readchar (remote_timeout);
+ csum += c;
+ repeat = c - ' ' + 3; /* Compute repeat count */
/* The character before ``*'' is repeated. */
- if (repeat > 0 && repeat <= 255
+ if (repeat > 0 && repeat <= 255
&& bc > 0
&& bc + repeat - 1 < sizeof_buf - 1)
{
{
/* We do _not_ want to mourn the target like this; this will
remove the extended remote target from the target stack,
- and the next time the user says "run" it'll fail.
+ and the next time the user says "run" it'll fail.
FIXME: What is the right thing to do here? */
#if 0
/* In the extended protocol we want to be able to do things like
"run" and have them basically work as expected. So we need
- a special create_inferior function.
+ a special create_inferior function.
FIXME: One day add support for changing the exec file
we're debugging, arguments and an environment. */
static void
-extended_remote_create_inferior (char *exec_file, char *args, char **env)
+extended_remote_create_inferior (char *exec_file, char *args, char **env,
+ int from_tty)
{
/* Rip out the breakpoints; we'll reinsert them after restarting
the remote server. */
/* Async version of extended_remote_create_inferior. */
static void
-extended_remote_async_create_inferior (char *exec_file, char *args, char **env)
+extended_remote_async_create_inferior (char *exec_file, char *args, char **env,
+ int from_tty)
{
/* Rip out the breakpoints; we'll reinsert them after restarting
the remote server. */
}
\f
-/* On some machines, e.g. 68k, we may use a different breakpoint instruction
- than other targets; in those use REMOTE_BREAKPOINT instead of just
- BREAKPOINT. Also, bi-endian targets may define LITTLE_REMOTE_BREAKPOINT
- and BIG_REMOTE_BREAKPOINT. If none of these are defined, we just call
- the standard routines that are in mem-break.c. */
+/* On some machines, e.g. 68k, we may use a different breakpoint
+ instruction than other targets; in those use
+ DEPRECATED_REMOTE_BREAKPOINT instead of just BREAKPOINT_FROM_PC.
+ Also, bi-endian targets may define
+ DEPRECATED_LITTLE_REMOTE_BREAKPOINT and
+ DEPRECATED_BIG_REMOTE_BREAKPOINT. If none of these are defined, we
+ just call the standard routines that are in mem-break.c. */
-/* FIXME, these ought to be done in a more dynamic fashion. For instance,
- the choice of breakpoint instruction affects target program design and
- vice versa, and by making it user-tweakable, the special code here
- goes away and we need fewer special GDB configurations. */
+/* NOTE: cagney/2003-06-08: This is silly. A remote and simulator
+ target should use an identical BREAKPOINT_FROM_PC. As for native,
+ the ARCH-OS-tdep.c code can override the default. */
-#if defined (LITTLE_REMOTE_BREAKPOINT) && defined (BIG_REMOTE_BREAKPOINT) && !defined(REMOTE_BREAKPOINT)
-#define REMOTE_BREAKPOINT
+#if defined (DEPRECATED_LITTLE_REMOTE_BREAKPOINT) && defined (DEPRECATED_BIG_REMOTE_BREAKPOINT) && !defined(DEPRECATED_REMOTE_BREAKPOINT)
+#define DEPRECATED_REMOTE_BREAKPOINT
#endif
-#ifdef REMOTE_BREAKPOINT
+#ifdef DEPRECATED_REMOTE_BREAKPOINT
/* If the target isn't bi-endian, just pretend it is. */
-#if !defined (LITTLE_REMOTE_BREAKPOINT) && !defined (BIG_REMOTE_BREAKPOINT)
-#define LITTLE_REMOTE_BREAKPOINT REMOTE_BREAKPOINT
-#define BIG_REMOTE_BREAKPOINT REMOTE_BREAKPOINT
+#if !defined (DEPRECATED_LITTLE_REMOTE_BREAKPOINT) && !defined (DEPRECATED_BIG_REMOTE_BREAKPOINT)
+#define DEPRECATED_LITTLE_REMOTE_BREAKPOINT DEPRECATED_REMOTE_BREAKPOINT
+#define DEPRECATED_BIG_REMOTE_BREAKPOINT DEPRECATED_REMOTE_BREAKPOINT
#endif
-static unsigned char big_break_insn[] = BIG_REMOTE_BREAKPOINT;
-static unsigned char little_break_insn[] = LITTLE_REMOTE_BREAKPOINT;
+static unsigned char big_break_insn[] = DEPRECATED_BIG_REMOTE_BREAKPOINT;
+static unsigned char little_break_insn[] = DEPRECATED_LITTLE_REMOTE_BREAKPOINT;
-#endif /* REMOTE_BREAKPOINT */
+#endif /* DEPRECATED_REMOTE_BREAKPOINT */
-/* Insert a breakpoint on targets that don't have any better breakpoint
- support. We read the contents of the target location and stash it,
- then overwrite it with a breakpoint instruction. ADDR is the target
- location in the target machine. CONTENTS_CACHE is a pointer to
- memory allocated for saving the target contents. It is guaranteed
- by the caller to be long enough to save sizeof BREAKPOINT bytes (this
- is accomplished via BREAKPOINT_MAX). */
+/* Insert a breakpoint on targets that don't have any better
+ breakpoint support. We read the contents of the target location
+ and stash it, then overwrite it with a breakpoint instruction.
+ ADDR is the target location in the target machine. CONTENTS_CACHE
+ is a pointer to memory allocated for saving the target contents.
+ It is guaranteed by the caller to be long enough to save the number
+ of bytes returned by BREAKPOINT_FROM_PC. */
static int
remote_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
{
struct remote_state *rs = get_remote_state ();
-#ifdef REMOTE_BREAKPOINT
+#ifdef DEPRECATED_REMOTE_BREAKPOINT
int val;
-#endif
+#endif
int bp_size;
/* Try the "Z" s/w breakpoint packet if it is not already disabled.
If it succeeds, then set the support to PACKET_ENABLE. If it
fails, and the user has explicitly requested the Z support then
report an error, otherwise, mark it disabled and go on. */
-
+
if (remote_protocol_Z[Z_PACKET_SOFTWARE_BP].support != PACKET_DISABLE)
{
char *buf = alloca (rs->remote_packet_size);
char *p = buf;
-
+
addr = remote_address_masked (addr);
*(p++) = 'Z';
*(p++) = '0';
p += hexnumstr (p, (ULONGEST) addr);
BREAKPOINT_FROM_PC (&addr, &bp_size);
sprintf (p, ",%d", bp_size);
-
+
putpkt (buf);
getpkt (buf, (rs->remote_packet_size), 0);
}
}
-#ifdef REMOTE_BREAKPOINT
+#ifdef DEPRECATED_REMOTE_BREAKPOINT
val = target_read_memory (addr, contents_cache, sizeof big_break_insn);
if (val == 0)
return val;
#else
return memory_insert_breakpoint (addr, contents_cache);
-#endif /* REMOTE_BREAKPOINT */
+#endif /* DEPRECATED_REMOTE_BREAKPOINT */
}
static int
{
char *buf = alloca (rs->remote_packet_size);
char *p = buf;
-
+
*(p++) = 'z';
*(p++) = '0';
*(p++) = ',';
p += hexnumstr (p, (ULONGEST) addr);
BREAKPOINT_FROM_PC (&addr, &bp_size);
sprintf (p, ",%d", bp_size);
-
+
putpkt (buf);
getpkt (buf, (rs->remote_packet_size), 0);
return (buf[0] == 'E');
}
-#ifdef REMOTE_BREAKPOINT
+#ifdef DEPRECATED_REMOTE_BREAKPOINT
return target_write_memory (addr, contents_cache, sizeof big_break_insn);
#else
return memory_remove_breakpoint (addr, contents_cache);
-#endif /* REMOTE_BREAKPOINT */
+#endif /* DEPRECATED_REMOTE_BREAKPOINT */
}
static int
error ("Can't set hardware watchpoints without the '%s' (%s) packet\n",
remote_protocol_Z[packet].name,
remote_protocol_Z[packet].title);
-
+
sprintf (buf, "Z%x,", packet);
p = strchr (buf, '\0');
addr = remote_address_masked (addr);
p += hexnumstr (p, (ULONGEST) addr);
sprintf (p, ",%x", len);
-
+
putpkt (buf);
getpkt (buf, (rs->remote_packet_size), 0);
error ("Can't clear hardware watchpoints without the '%s' (%s) packet\n",
remote_protocol_Z[packet].name,
remote_protocol_Z[packet].title);
-
+
sprintf (buf, "z%x,", packet);
p = strchr (buf, '\0');
addr = remote_address_masked (addr);
int remote_hw_watchpoint_limit = -1;
int remote_hw_breakpoint_limit = -1;
-int
+static int
remote_check_watch_resources (int type, int cnt, int ot)
{
if (type == bp_hardware_breakpoint)
return -1;
}
-int
+static int
remote_stopped_by_watchpoint (void)
{
return remote_stopped_by_watchpoint_p;
}
-CORE_ADDR
+extern int stepped_after_stopped_by_watchpoint;
+
+static CORE_ADDR
remote_stopped_data_address (void)
{
- if (remote_stopped_by_watchpoint ())
+ if (remote_stopped_by_watchpoint ()
+ || stepped_after_stopped_by_watchpoint)
return remote_watch_data_address;
return (CORE_ADDR)0;
}
struct remote_state *rs = get_remote_state ();
char *buf = alloca (rs->remote_packet_size);
char *p = buf;
-
+
/* The length field should be set to the size of a breakpoint
instruction. */
- BREAKPOINT_FROM_PC (&addr, &len);
+ BREAKPOINT_FROM_PC (&addr, &len);
if (remote_protocol_Z[Z_PACKET_HARDWARE_BP].support == PACKET_DISABLE)
error ("Can't set hardware breakpoint without the '%s' (%s) packet\n",
remote_protocol_Z[Z_PACKET_HARDWARE_BP].name,
remote_protocol_Z[Z_PACKET_HARDWARE_BP].title);
-
+
*(p++) = 'Z';
*(p++) = '1';
*(p++) = ',';
-
+
addr = remote_address_masked (addr);
p += hexnumstr (p, (ULONGEST) addr);
sprintf (p, ",%x", len);
}
-static int
+static int
remote_remove_hw_breakpoint (CORE_ADDR addr, char *shadow)
{
int len;
error ("Can't clear hardware breakpoint without the '%s' (%s) packet\n",
remote_protocol_Z[Z_PACKET_HARDWARE_BP].name,
remote_protocol_Z[Z_PACKET_HARDWARE_BP].title);
-
+
*(p++) = 'z';
*(p++) = '1';
*(p++) = ',';
-
+
addr = remote_address_masked (addr);
p += hexnumstr (p, (ULONGEST) addr);
sprintf (p, ",%x", len);
putpkt(buf);
getpkt (buf, (rs->remote_packet_size), 0);
-
+
switch (packet_ok (buf, &remote_protocol_Z[Z_PACKET_HARDWARE_BP]))
{
case PACKET_ERROR:
if (!(s->flags & SEC_LOAD))
continue; /* skip non-loadable section */
- size = bfd_get_section_size_before_reloc (s);
+ size = bfd_get_section_size (s);
if (size == 0)
continue; /* skip zero-length section */
printf_filtered ("No loaded section named '%s'.\n", args);
}
-static int
-remote_query (int query_type, char *buf, char *outbuf, int *bufsiz)
+static LONGEST
+remote_xfer_partial (struct target_ops *ops, enum target_object object,
+ const char *annex, void *readbuf, const void *writebuf,
+ ULONGEST offset, LONGEST len)
{
struct remote_state *rs = get_remote_state ();
int i;
char *buf2 = alloca (rs->remote_packet_size);
char *p2 = &buf2[0];
+ char query_type;
- if (!bufsiz)
- error ("null pointer to remote bufer size specified");
+ /* Only handle reads. */
+ if (writebuf != NULL || readbuf == NULL)
+ return -1;
- /* minimum outbuf size is (rs->remote_packet_size) - if bufsiz is not large enough let
- the caller know and return what the minimum size is */
- /* Note: a zero bufsiz can be used to query the minimum buffer size */
- if (*bufsiz < (rs->remote_packet_size))
+ /* Map pre-existing objects onto letters. DO NOT do this for new
+ objects!!! Instead specify new query packets. */
+ switch (object)
{
- *bufsiz = (rs->remote_packet_size);
+ case TARGET_OBJECT_KOD:
+ query_type = 'K';
+ break;
+ case TARGET_OBJECT_AVR:
+ query_type = 'R';
+ break;
+
+ case TARGET_OBJECT_AUXV:
+ if (remote_protocol_qPart_auxv.support != PACKET_DISABLE)
+ {
+ unsigned int total = 0;
+ while (len > 0)
+ {
+ LONGEST n = min ((rs->remote_packet_size - 2) / 2, len);
+ snprintf (buf2, rs->remote_packet_size,
+ "qPart:auxv:read::%s,%s",
+ phex_nz (offset, sizeof offset),
+ phex_nz (n, sizeof n));
+ i = putpkt (buf2);
+ if (i < 0)
+ return total > 0 ? total : i;
+ buf2[0] = '\0';
+ getpkt (buf2, rs->remote_packet_size, 0);
+ if (packet_ok (buf2, &remote_protocol_qPart_auxv) != PACKET_OK)
+ return total > 0 ? total : -1;
+ if (buf2[0] == 'O' && buf2[1] == 'K' && buf2[2] == '\0')
+ break; /* Got EOF indicator. */
+ /* Got some data. */
+ i = hex2bin (buf2, readbuf, len);
+ if (i > 0)
+ {
+ readbuf = (void *) ((char *) readbuf + i);
+ offset += i;
+ len -= i;
+ total += i;
+ }
+ }
+ return total;
+ }
+ return -1;
+
+ default:
return -1;
}
+ /* Note: a zero OFFSET and LEN can be used to query the minimum
+ buffer size. */
+ if (offset == 0 && len == 0)
+ return (rs->remote_packet_size);
+ /* Minimum outbuf size is (rs->remote_packet_size) - if bufsiz is
+ not large enough let the caller. */
+ if (len < (rs->remote_packet_size))
+ return -1;
+ len = rs->remote_packet_size;
+
/* except for querying the minimum buffer size, target must be open */
if (!remote_desc)
error ("remote query is only available after target open");
- /* we only take uppercase letters as query types, at least for now */
- if ((query_type < 'A') || (query_type > 'Z'))
- error ("invalid remote query type");
-
- if (!buf)
- error ("null remote query specified");
-
- if (!outbuf)
- error ("remote query requires a buffer to receive data");
-
- outbuf[0] = '\0';
+ gdb_assert (annex != NULL);
+ gdb_assert (readbuf != NULL);
*p2++ = 'q';
*p2++ = query_type;
plus one extra in case we are debugging (remote_debug),
we have PBUFZIZ - 7 left to pack the query string */
i = 0;
- while (buf[i] && (i < ((rs->remote_packet_size) - 8)))
+ while (annex[i] && (i < ((rs->remote_packet_size) - 8)))
{
- /* bad caller may have sent forbidden characters */
- if ((!isprint (buf[i])) || (buf[i] == '$') || (buf[i] == '#'))
- error ("illegal characters in query string");
-
- *p2++ = buf[i];
+ /* Bad caller may have sent forbidden characters. */
+ gdb_assert (isprint (annex[i]) && annex[i] != '$' && annex[i] != '#');
+ *p2++ = annex[i];
i++;
}
- *p2 = buf[i];
-
- if (buf[i])
- error ("query larger than available buffer");
+ *p2 = '\0';
+ gdb_assert (annex[i] == '\0');
i = putpkt (buf2);
if (i < 0)
return i;
- getpkt (outbuf, *bufsiz, 0);
+ getpkt (readbuf, len, 0);
- return 0;
+ return strlen (readbuf);
}
static void
remote_ops.to_open = remote_open;
remote_ops.to_close = remote_close;
remote_ops.to_detach = remote_detach;
+ remote_ops.to_disconnect = remote_disconnect;
remote_ops.to_resume = remote_resume;
remote_ops.to_wait = remote_wait;
remote_ops.to_fetch_registers = remote_fetch_registers;
remote_ops.to_pid_to_str = remote_pid_to_str;
remote_ops.to_extra_thread_info = remote_threads_extra_info;
remote_ops.to_stop = remote_stop;
- remote_ops.to_query = remote_query;
+ remote_ops.to_xfer_partial = remote_xfer_partial;
remote_ops.to_rcmd = remote_rcmd;
remote_ops.to_stratum = process_stratum;
remote_ops.to_has_all_memory = 1;
extended_remote_ops.to_mourn_inferior = extended_remote_mourn;
}
-/*
- * Command: info remote-process
- *
- * This implements Cisco's version of the "info proc" command.
- *
- * This query allows the target stub to return an arbitrary string
- * (or strings) giving arbitrary information about the target process.
- * This is optional; the target stub isn't required to implement it.
- *
- * Syntax: qfProcessInfo request first string
- * qsProcessInfo request subsequent string
- * reply: 'O'<hex-encoded-string>
- * 'l' last reply (empty)
- */
-
-static void
-remote_info_process (char *args, int from_tty)
-{
- struct remote_state *rs = get_remote_state ();
- char *buf = alloca (rs->remote_packet_size);
-
- if (remote_desc == 0)
- error ("Command can only be used when connected to the remote target.");
-
- putpkt ("qfProcessInfo");
- getpkt (buf, (rs->remote_packet_size), 0);
- if (buf[0] == 0)
- return; /* Silently: target does not support this feature. */
-
- if (buf[0] == 'E')
- error ("info proc: target error.");
-
- while (buf[0] == 'O') /* Capitol-O packet */
- {
- remote_console_output (&buf[1]);
- putpkt ("qsProcessInfo");
- getpkt (buf, (rs->remote_packet_size), 0);
- }
-}
-
-/*
- * Target Cisco
- */
-
-static void
-remote_cisco_open (char *name, int from_tty)
-{
- int ex;
- if (name == 0)
- error ("To open a remote debug connection, you need to specify what \n"
- "device is attached to the remote system (e.g. host:port).");
-
- /* See FIXME above */
- wait_forever_enabled_p = 1;
-
- target_preopen (from_tty);
-
- unpush_target (&remote_cisco_ops);
-
- remote_desc = remote_serial_open (name);
- if (!remote_desc)
- perror_with_name (name);
-
- /*
- * If a baud rate was specified on the gdb command line it will
- * be greater than the initial value of -1. If it is, use it otherwise
- * default to 9600
- */
-
- baud_rate = (baud_rate > 0) ? baud_rate : 9600;
- if (serial_setbaudrate (remote_desc, baud_rate))
- {
- serial_close (remote_desc);
- perror_with_name (name);
- }
-
- serial_raw (remote_desc);
-
- /* If there is something sitting in the buffer we might take it as a
- response to a command, which would be bad. */
- serial_flush_input (remote_desc);
-
- if (from_tty)
- {
- puts_filtered ("Remote debugging using ");
- puts_filtered (name);
- puts_filtered ("\n");
- }
-
- remote_cisco_mode = 1;
-
- push_target (&remote_cisco_ops); /* Switch to using cisco target now */
-
- init_all_packet_configs ();
-
- general_thread = -2;
- continue_thread = -2;
-
- /* Probe for ability to use "ThreadInfo" query, as required. */
- use_threadinfo_query = 1;
- use_threadextra_query = 1;
-
- /* Without this, some commands which require an active target (such
- as kill) won't work. This variable serves (at least) double duty
- as both the pid of the target process (if it has such), and as a
- flag indicating that a target is active. These functions should
- be split out into seperate variables, especially since GDB will
- someday have a notion of debugging several processes. */
- inferior_ptid = pid_to_ptid (MAGIC_NULL_PID);
-
- /* Start the remote connection; if error, discard this target. See
- the comments in remote_open_1() for further details such as the
- need to re-throw the exception. */
- ex = catch_exceptions (uiout,
- remote_start_remote_dummy, NULL,
- "Couldn't establish connection to remote"
- " target\n",
- RETURN_MASK_ALL);
- if (ex < 0)
- {
- pop_target ();
- throw_exception (ex);
- }
-}
-
-static void
-remote_cisco_close (int quitting)
-{
- remote_cisco_mode = 0;
- remote_close (quitting);
-}
-
-static void
-remote_cisco_mourn (void)
-{
- remote_mourn_1 (&remote_cisco_ops);
-}
-
-enum
-{
- READ_MORE,
- FATAL_ERROR,
- ENTER_DEBUG,
- DISCONNECT_TELNET
-}
-minitelnet_return;
-
-/* Shared between readsocket() and readtty(). The size is arbitrary,
- however all targets are known to support a 400 character packet. */
-static char tty_input[400];
-
-static int escape_count;
-static int echo_check;
-extern int quit_flag;
-
-static int
-readsocket (void)
-{
- int data;
-
- /* Loop until the socket doesn't have any more data */
-
- while ((data = readchar (0)) >= 0)
- {
- /* Check for the escape sequence */
- if (data == '|')
- {
- /* If this is the fourth escape, get out */
- if (++escape_count == 4)
- {
- return ENTER_DEBUG;
- }
- else
- { /* This is a '|', but not the fourth in a row.
- Continue without echoing it. If it isn't actually
- one of four in a row, it'll be echoed later. */
- continue;
- }
- }
- else
- /* Not a '|' */
- {
- /* Ensure any pending '|'s are flushed. */
-
- for (; escape_count > 0; escape_count--)
- putchar ('|');
- }
-
- if (data == '\r') /* If this is a return character, */
- continue; /* - just supress it. */
-
- if (echo_check != -1) /* Check for echo of user input. */
- {
- if (tty_input[echo_check] == data)
- {
- gdb_assert (echo_check <= sizeof (tty_input));
- echo_check++; /* Character matched user input: */
- continue; /* Continue without echoing it. */
- }
- else if ((data == '\n') && (tty_input[echo_check] == '\r'))
- { /* End of the line (and of echo checking). */
- echo_check = -1; /* No more echo supression */
- continue; /* Continue without echoing. */
- }
- else
- { /* Failed check for echo of user input.
- We now have some suppressed output to flush! */
- int j;
-
- for (j = 0; j < echo_check; j++)
- putchar (tty_input[j]);
- echo_check = -1;
- }
- }
- putchar (data); /* Default case: output the char. */
- }
-
- if (data == SERIAL_TIMEOUT) /* Timeout returned from readchar. */
- return READ_MORE; /* Try to read some more */
- else
- return FATAL_ERROR; /* Trouble, bail out */
-}
-
-static int
-readtty (void)
-{
- int tty_bytecount;
-
- /* First, read a buffer full from the terminal */
- tty_bytecount = read (fileno (stdin), tty_input, sizeof (tty_input) - 1);
- if (tty_bytecount == -1)
- {
- perror ("readtty: read failed");
- return FATAL_ERROR;
- }
-
- /* Remove a quoted newline. */
- if (tty_input[tty_bytecount - 1] == '\n' &&
- tty_input[tty_bytecount - 2] == '\\') /* line ending in backslash */
- {
- tty_input[--tty_bytecount] = 0; /* remove newline */
- tty_input[--tty_bytecount] = 0; /* remove backslash */
- }
-
- /* Turn trailing newlines into returns */
- if (tty_input[tty_bytecount - 1] == '\n')
- tty_input[tty_bytecount - 1] = '\r';
-
- /* If the line consists of a ~, enter debugging mode. */
- if ((tty_input[0] == '~') && (tty_bytecount == 2))
- return ENTER_DEBUG;
-
- /* Make this a zero terminated string and write it out */
- tty_input[tty_bytecount] = 0;
- if (serial_write (remote_desc, tty_input, tty_bytecount))
- {
- perror_with_name ("readtty: write failed");
- return FATAL_ERROR;
- }
-
- return READ_MORE;
-}
-
-static int
-minitelnet (void)
-{
- fd_set input; /* file descriptors for select */
- int tablesize; /* max number of FDs for select */
- int status;
- int quit_count = 0;
-
- escape_count = 0;
- echo_check = -1;
-
- tablesize = 8 * sizeof (input);
-
- for (;;)
- {
- /* Check for anything from our socket - doesn't block. Note that
- this must be done *before* the select as there may be
- buffered I/O waiting to be processed. */
-
- if ((status = readsocket ()) == FATAL_ERROR)
- {
- error ("Debugging terminated by communications error");
- }
- else if (status != READ_MORE)
- {
- return (status);
- }
-
- fflush (stdout); /* Flush output before blocking */
-
- /* Now block on more socket input or TTY input */
-
- FD_ZERO (&input);
- FD_SET (fileno (stdin), &input);
- FD_SET (deprecated_serial_fd (remote_desc), &input);
-
- status = select (tablesize, &input, 0, 0, 0);
- if ((status == -1) && (errno != EINTR))
- {
- error ("Communications error on select %d", errno);
- }
-
- /* Handle Control-C typed */
-
- if (quit_flag)
- {
- if ((++quit_count) == 2)
- {
- if (query ("Interrupt GDB? "))
- {
- printf_filtered ("Interrupted by user.\n");
- throw_exception (RETURN_QUIT);
- }
- quit_count = 0;
- }
- quit_flag = 0;
-
- if (remote_break)
- serial_send_break (remote_desc);
- else
- serial_write (remote_desc, "\003", 1);
-
- continue;
- }
-
- /* Handle console input */
-
- if (FD_ISSET (fileno (stdin), &input))
- {
- quit_count = 0;
- echo_check = 0;
- status = readtty ();
- if (status == READ_MORE)
- continue;
-
- return status; /* telnet session ended */
- }
- }
-}
-
-static ptid_t
-remote_cisco_wait (ptid_t ptid, struct target_waitstatus *status)
-{
- if (minitelnet () != ENTER_DEBUG)
- {
- error ("Debugging session terminated by protocol error");
- }
- putpkt ("?");
- return remote_wait (ptid, status);
-}
-
-static void
-init_remote_cisco_ops (void)
-{
- remote_cisco_ops.to_shortname = "cisco";
- remote_cisco_ops.to_longname = "Remote serial target in cisco-specific protocol";
- remote_cisco_ops.to_doc =
- "Use a remote machine via TCP, using a cisco-specific protocol.\n\
-Specify the serial device it is connected to (e.g. host:2020).";
- remote_cisco_ops.to_open = remote_cisco_open;
- remote_cisco_ops.to_close = remote_cisco_close;
- remote_cisco_ops.to_detach = remote_detach;
- remote_cisco_ops.to_resume = remote_resume;
- remote_cisco_ops.to_wait = remote_cisco_wait;
- remote_cisco_ops.to_fetch_registers = remote_fetch_registers;
- remote_cisco_ops.to_store_registers = remote_store_registers;
- remote_cisco_ops.to_prepare_to_store = remote_prepare_to_store;
- remote_cisco_ops.to_xfer_memory = remote_xfer_memory;
- remote_cisco_ops.to_files_info = remote_files_info;
- remote_cisco_ops.to_insert_breakpoint = remote_insert_breakpoint;
- remote_cisco_ops.to_remove_breakpoint = remote_remove_breakpoint;
- remote_cisco_ops.to_remove_hw_breakpoint = remote_remove_hw_breakpoint;
- remote_cisco_ops.to_insert_hw_breakpoint = remote_insert_hw_breakpoint;
- remote_cisco_ops.to_insert_watchpoint = remote_insert_watchpoint;
- remote_cisco_ops.to_remove_watchpoint = remote_remove_watchpoint;
- remote_cisco_ops.to_stopped_by_watchpoint = remote_stopped_by_watchpoint;
- remote_cisco_ops.to_stopped_data_address = remote_stopped_data_address;
- remote_cisco_ops.to_can_use_hw_breakpoint = remote_check_watch_resources;
- remote_cisco_ops.to_kill = remote_kill;
- remote_cisco_ops.to_load = generic_load;
- remote_cisco_ops.to_mourn_inferior = remote_cisco_mourn;
- remote_cisco_ops.to_thread_alive = remote_thread_alive;
- remote_cisco_ops.to_find_new_threads = remote_threads_info;
- remote_cisco_ops.to_pid_to_str = remote_pid_to_str;
- remote_cisco_ops.to_extra_thread_info = remote_threads_extra_info;
- remote_cisco_ops.to_stratum = process_stratum;
- remote_cisco_ops.to_has_all_memory = 1;
- remote_cisco_ops.to_has_memory = 1;
- remote_cisco_ops.to_has_stack = 1;
- remote_cisco_ops.to_has_registers = 1;
- remote_cisco_ops.to_has_execution = 1;
- remote_cisco_ops.to_magic = OPS_MAGIC;
-}
-
static int
remote_can_async_p (void)
{
Specify the serial device it is connected to (e.g. /dev/ttya).";
remote_async_ops.to_open = remote_async_open;
remote_async_ops.to_close = remote_close;
- remote_async_ops.to_detach = remote_async_detach;
+ remote_async_ops.to_detach = remote_detach;
+ remote_async_ops.to_disconnect = remote_disconnect;
remote_async_ops.to_resume = remote_async_resume;
remote_async_ops.to_wait = remote_async_wait;
remote_async_ops.to_fetch_registers = remote_fetch_registers;
remote_async_ops.to_pid_to_str = remote_pid_to_str;
remote_async_ops.to_extra_thread_info = remote_threads_extra_info;
remote_async_ops.to_stop = remote_stop;
- remote_async_ops.to_query = remote_query;
+ remote_async_ops.to_xfer_partial = remote_xfer_partial;
remote_async_ops.to_rcmd = remote_rcmd;
remote_async_ops.to_stratum = process_stratum;
remote_async_ops.to_has_all_memory = 1;
/* FIXME: cagney/2002-06-15: This function should iterate over
remote_show_cmdlist for a list of sub commands to show. */
show_remote_protocol_Z_packet_cmd (args, from_tty, NULL);
- show_remote_protocol_e_packet_cmd (args, from_tty, NULL);
- show_remote_protocol_E_packet_cmd (args, from_tty, NULL);
show_remote_protocol_P_packet_cmd (args, from_tty, NULL);
show_remote_protocol_qSymbol_packet_cmd (args, from_tty, NULL);
+ show_remote_protocol_vcont_packet_cmd (args, from_tty, NULL);
show_remote_protocol_binary_download_cmd (args, from_tty, NULL);
+ show_remote_protocol_qPart_auxv_packet_cmd (args, from_tty, NULL);
}
static void
struct cmd_list_element *tmpcmd;
/* architecture specific data */
- remote_gdbarch_data_handle = register_gdbarch_data (init_remote_state,
- free_remote_state);
+ remote_gdbarch_data_handle = gdbarch_data_register_post_init (init_remote_state);
/* Old tacky stuff. NOTE: This comes after the remote protocol so
that the remote protocol has been initialized. */
- register_gdbarch_swap (&remote_address_size,
- sizeof (&remote_address_size), NULL);
- register_gdbarch_swap (NULL, 0, build_remote_gdbarch_data);
+ DEPRECATED_REGISTER_GDBARCH_SWAP (remote_address_size);
+ deprecated_register_gdbarch_swap (NULL, 0, build_remote_gdbarch_data);
init_remote_ops ();
add_target (&remote_ops);
init_extended_async_remote_ops ();
add_target (&extended_async_remote_ops);
- init_remote_cisco_ops ();
- add_target (&remote_cisco_ops);
-
/* Hook into new objfile notification. */
- remote_new_objfile_chain = target_new_objfile_hook;
- target_new_objfile_hook = remote_new_objfile;
+ remote_new_objfile_chain = deprecated_target_new_objfile_hook;
+ deprecated_target_new_objfile_hook = remote_new_objfile;
#if 0
init_remote_threadtests ();
&showlist);
#endif
- add_info ("remote-process", remote_info_process,
- "Query the remote system for process info.");
+ add_packet_config_cmd (&remote_protocol_vcont,
+ "vCont", "verbose-resume",
+ set_remote_protocol_vcont_packet_cmd,
+ show_remote_protocol_vcont_packet_cmd,
+ &remote_set_cmdlist, &remote_show_cmdlist,
+ 0);
add_packet_config_cmd (&remote_protocol_qSymbol,
"qSymbol", "symbol-lookup",
&remote_set_cmdlist, &remote_show_cmdlist,
0);
- 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);
- /* Disable by default. The ``e'' packet has nasty interactions with
- the threading code - it relies on global state. */
- remote_protocol_e.detect = AUTO_BOOLEAN_FALSE;
- update_packet_config (&remote_protocol_e);
-
- 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);
- /* Disable by default. The ``e'' packet has nasty interactions with
- the threading code - it relies on global state. */
- remote_protocol_E.detect = AUTO_BOOLEAN_FALSE;
- update_packet_config (&remote_protocol_E);
-
add_packet_config_cmd (&remote_protocol_P,
"P", "set-register",
set_remote_protocol_P_packet_cmd,
&remote_set_cmdlist, &remote_show_cmdlist,
0);
+ add_packet_config_cmd (&remote_protocol_qPart_auxv,
+ "qPart_auxv", "read-aux-vector",
+ set_remote_protocol_qPart_auxv_packet_cmd,
+ show_remote_protocol_qPart_auxv_packet_cmd,
+ &remote_set_cmdlist, &remote_show_cmdlist,
+ 0);
+
/* Keep the old ``set remote Z-packet ...'' working. */
add_setshow_auto_boolean_cmd ("Z-packet", class_obscure,
&remote_Z_packet_detect, "\
set_remote_protocol_Z_packet_cmd,
show_remote_protocol_Z_packet_cmd,
&remote_set_cmdlist, &remote_show_cmdlist);
+
+ /* Eventually initialize fileio. See fileio.c */
+ initialize_remote_fileio (remote_set_cmdlist, remote_show_cmdlist);
}