aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog17
-rw-r--r--gdb/remote.c167
-rw-r--r--gdb/sh-tdep.c9
3 files changed, 141 insertions, 52 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index b5ddf0d..5773c7e 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,20 @@
+Fri Apr 4 08:21:21 1997 Stu Grossman (grossman@critters.cygnus.com)
+
+ * remote.c: Fix doc for `C' and `S' commands to indicate full
+ address.
+ * (remote_ops extended_remote_ops remote_desc remote_write_size):
+ Make static.
+ * (remote_fetch_registers remote_write_bytes remote_read_bytes):
+ Record size of response to fetch registers command, use this to
+ limit size of memory read and write commands.
+ * (push_remote_target): New function to make it possible to have
+ another target switch to the remote target.
+ * target.h: Add prototype for push_remote_target.
+ * sh-tdep.c (sh_frame_find_saved_regs): Fix sign extension bugs
+ for hosts which default to unsigned chars (such as SGI's).
+ * (_initialize_sh_tdep): Don't set remote_write_size. It's now
+ handled automatically in remote.c.
+
Thu Apr 3 15:10:30 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
* blockframe.c: blockvector_for_pc_sect(), block_for_pc_sect(),
diff --git a/gdb/remote.c b/gdb/remote.c
index 65caedb..1e23db1 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -1,5 +1,5 @@
/* Remote target communications for serial-line targets in custom GDB protocol
- Copyright 1988, 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+ Copyright 1988, 1991, 1992, 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
This file is part of GDB.
@@ -97,10 +97,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
If AA..AA is omitted,
resume at same address.
- continue with Csig;AA Continue with signal sig (hex signal
- signal number).
+ continue with Csig;AA..AA Continue with signal sig (hex signal
+ signal number). If ;AA..AA is omitted, resume
+ at same address.
- step with Ssig;AA Like 'C' but step not continue.
+ step with Ssig;AA..AA Like 'C' but step not continue.
signal
last signal ? Reply the current reason for stopping.
@@ -278,8 +279,8 @@ static int remote_insert_breakpoint PARAMS ((CORE_ADDR, char *));
static int remote_remove_breakpoint PARAMS ((CORE_ADDR, char *));
-extern struct target_ops remote_ops; /* Forward decl */
-extern struct target_ops extended_remote_ops; /* Forward decl */
+static struct target_ops remote_ops; /* Forward decl */
+static struct target_ops extended_remote_ops; /* Forward decl */
/* This was 5 seconds, which is a long time to sit and wait.
Unless this is going though some terminal server or multiplexer or
@@ -300,7 +301,7 @@ static int remote_break;
/* Descriptor for I/O to remote machine. Initialize it to NULL so that
remote_open knows that we don't have a file open when the program
starts. */
-serial_t remote_desc = NULL;
+static serial_t remote_desc = NULL;
/* Having this larger than 400 causes us to be incompatible with m68k-stub.c
and i386-stub.c. Normally, no one would notice because it only matters
@@ -329,10 +330,22 @@ serial_t remote_desc = NULL;
static int remote_write_size = PBUFSIZ;
+/* This is the size (in chars) of the first response to the `g' command. This
+ is used to limit the size of the memory read and write commands to prevent
+ stub buffers from overflowing. */
+
+static int remote_register_buf_size = 0;
+
/* Should we try the 'P' request? If this is set to one when the stub
doesn't support 'P', the only consequence is some unnecessary traffic. */
static int stub_supports_P = 1;
+/* 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) PARAMS ((void));
+void (*target_wait_loop_hook) PARAMS ((void));
+
/* These are the threads which we last sent to the remote system. -1 for all
or -2 for not sent yet. */
@@ -663,6 +676,11 @@ remote_resume (pid, step, siggnal)
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 (siggnal != TARGET_SIGNAL_0)
{
buf[0] = step ? 'S' : 'C';
@@ -754,6 +772,11 @@ remote_wait (pid, status)
getpkt ((char *) buf, 1);
signal (SIGINT, ofunc);
+ /* 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) ();
+
switch (buf[0])
{
case 'E': /* Error of some sort */
@@ -915,6 +938,9 @@ remote_fetch_registers (regno)
sprintf (buf, "g");
remote_send (buf);
+ if (remote_register_buf_size == 0)
+ remote_register_buf_size = strlen (buf);
+
/* Unimplemented registers read as all bits zero. */
memset (regs, 0, REGISTER_BYTES);
@@ -1068,6 +1094,21 @@ remote_store_word (addr, word)
#endif /* 0 (unused?) */
+
+/* Return the number of hex digits in num. */
+
+static int
+hexnumlen (num)
+ ULONGEST num;
+{
+ int i;
+
+ for (i = 0; num != 0; i++)
+ num >>= 4;
+
+ return min (i, 1);
+}
+
/* Write memory data directly to the remote machine.
This does not inform the data cache; the data cache uses this.
MEMADDR is the address in the remote memory space.
@@ -1082,24 +1123,32 @@ remote_write_bytes (memaddr, myaddr, len)
char *myaddr;
int len;
{
- char buf[PBUFSIZ];
- int i;
- char *p;
- int done;
+ int max_buf_size; /* Max size of packet output buffer */
+ int origlen;
+
/* Chop the transfer down if necessary */
- done = 0;
- while (done < len)
+ max_buf_size = min (remote_write_size, PBUFSIZ);
+ max_buf_size = min (max_buf_size, remote_register_buf_size);
+
+#define PACKET_OVERHEAD (1 + 1 + 1 + 2) /* $x#xx - Overhead for all types of packets */
+
+ /* packet overhead + <memaddr>,<len>: */
+ max_buf_size -= PACKET_OVERHEAD + hexnumlen (memaddr + len - 1) + 1 + hexnumlen (len) + 1;
+
+ origlen = len;
+ while (len > 0)
{
- int todo = len - done;
- int cando = min(remote_write_size, PBUFSIZ) / 2 - 32; /* num bytes that will fit */
+ char buf[PBUFSIZ];
+ char *p;
+ int todo;
+ int i;
- if (todo > cando)
- todo = cando;
+ todo = min (len, max_buf_size / 2); /* num bytes that will fit */
/* FIXME-32x64: Need a version of print_address_numeric which puts the
result in a buffer like sprintf. */
- sprintf (buf, "M%lx,%x:", (unsigned long) memaddr + done, todo);
+ sprintf (buf, "M%lx,%x:", (unsigned long) memaddr, todo);
/* We send target system values byte by byte, in increasing byte addresses,
each byte encoded as two hex characters. */
@@ -1107,8 +1156,8 @@ remote_write_bytes (memaddr, myaddr, len)
p = buf + strlen (buf);
for (i = 0; i < todo; i++)
{
- *p++ = tohex ((myaddr[i + done] >> 4) & 0xf);
- *p++ = tohex (myaddr[i + done] & 0xf);
+ *p++ = tohex ((myaddr[i] >> 4) & 0xf);
+ *p++ = tohex (myaddr[i] & 0xf);
}
*p = '\0';
@@ -1124,9 +1173,11 @@ remote_write_bytes (memaddr, myaddr, len)
errno = EIO;
return 0;
}
- done += todo;
+ myaddr += todo;
+ memaddr += todo;
+ len -= todo;
}
- return len;
+ return origlen;
}
/* Read memory data directly from the remote machine.
@@ -1143,28 +1194,30 @@ remote_read_bytes (memaddr, myaddr, len)
char *myaddr;
int len;
{
- char buf[PBUFSIZ];
- int i;
- char *p;
- int done;
- /* Chop transfer down if neccessary */
+ int max_buf_size; /* Max size of packet output buffer */
+ int origlen;
-#if 0
- /* FIXME: This is wrong for larger packets */
- if (len > PBUFSIZ / 2 - 1)
- abort ();
-#endif
- done = 0;
- while (done < len)
+ /* Chop the transfer down if necessary */
+
+ max_buf_size = min (remote_write_size, PBUFSIZ);
+ max_buf_size = min (max_buf_size, remote_register_buf_size);
+
+ /* packet overhead */
+ max_buf_size -= PACKET_OVERHEAD;
+
+ origlen = len;
+ while (len > 0)
{
- int todo = len - done;
- int cando = PBUFSIZ / 2 - 32; /* number of bytes that will fit. */
- if (todo > cando)
- todo = cando;
+ char buf[PBUFSIZ];
+ char *p;
+ int todo;
+ int i;
+
+ todo = min (len, max_buf_size / 2); /* num bytes that will fit */
/* FIXME-32x64: Need a version of print_address_numeric which puts the
result in a buffer like sprintf. */
- sprintf (buf, "m%lx,%x", (unsigned long) memaddr + done, todo);
+ sprintf (buf, "m%lx,%x", (unsigned long) memaddr, todo);
putpkt (buf);
getpkt (buf, 0);
@@ -1187,13 +1240,15 @@ remote_read_bytes (memaddr, myaddr, len)
if (p[0] == 0 || p[1] == 0)
/* Reply is short. This means that we were able to read only part
of what we wanted to. */
- return i + done;
- myaddr[i + done] = fromhex (p[0]) * 16 + fromhex (p[1]);
+ return i + (origlen - len);
+ myaddr[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
p += 2;
}
- done += todo;
+ myaddr += todo;
+ memaddr += todo;
+ len -= todo;
}
- return len;
+ return origlen;
}
/* Read or write LEN bytes from inferior memory at MEMADDR, transferring
@@ -1782,7 +1837,8 @@ remote_remove_breakpoint (addr, contents_cache)
/* Define the target subroutine names */
-struct target_ops remote_ops = {
+static struct target_ops remote_ops =
+{
"remote", /* to_shortname */
"Remote serial target in gdb-specific protocol", /* to_longname */
"Use a remote computer via a serial line, using a gdb-specific protocol.\n\
@@ -1826,7 +1882,8 @@ Specify the serial device it is connected to (e.g. /dev/ttya).", /* to_doc */
OPS_MAGIC /* to_magic */
};
-struct target_ops extended_remote_ops = {
+static struct target_ops extended_remote_ops =
+{
"extended-remote", /* to_shortname */
"Extended remote serial target in gdb-specific protocol",/* to_longname */
"Use a remote computer via a serial line, using a gdb-specific protocol.\n\
@@ -1872,6 +1929,26 @@ Specify the serial device it is connected to (e.g. /dev/ttya).", /* to_doc */
OPS_MAGIC /* to_magic */
};
+/* Some targets are only capable of doing downloads, and afterwards they switch
+ to the remote serial protocol. This function provides a clean way to get
+ from the download target to the remote target. It's basically just a
+ wrapper so that we don't have to expose any of the internal workings of
+ remote.c.
+
+ Prior to calling this routine, you should shutdown the current target code,
+ else you will get the "A program is being debugged already..." message.
+ Usually a call to pop_target() suffices.
+*/
+
+void
+push_remote_target (name, from_tty)
+ char *name;
+ int from_tty;
+{
+ printf_filtered ("Switching to remote protocol\n");
+ remote_open (name, from_tty);
+}
+
void
_initialize_remote ()
{
diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c
index 4a3eb2e..dcec846 100644
--- a/gdb/sh-tdep.c
+++ b/gdb/sh-tdep.c
@@ -262,7 +262,7 @@ sh_frame_find_saved_regs (fi, fsr)
}
else if (IS_MOV_R3 (insn))
{
- r3_val = (char) (insn & 0xff);
+ r3_val = ((insn & 0xff) ^ 0x80) - 0x80;
pc += 2;
insn = read_memory_integer (pc, 2);
}
@@ -281,7 +281,7 @@ sh_frame_find_saved_regs (fi, fsr)
else if (IS_ADD_SP (insn))
{
pc += 2;
- depth += -((char) (insn & 0xff));
+ depth -= ((insn & 0xff) ^ 0x80) - 0x80;
insn = read_memory_integer (pc, 2);
}
else
@@ -706,9 +706,4 @@ Set this to be able to access processor-type-specific registers.\n\
sh_set_processor_type_command (strsave (DEFAULT_SH_TYPE), 0);
add_com ("regs", class_vars, sh_show_regs, "Print all registers");
-
- /* Reduce the remote write size because some CMONs can't take
- more than 400 bytes in a packet. 300 seems like a safe bet. */
- remote_write_size = 300;
}
-