* 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.
This commit is contained in:
Stu Grossman 1997-04-04 16:52:55 +00:00
parent ab83171da5
commit 0a325463ed
3 changed files with 142 additions and 53 deletions

View File

@ -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(),

View File

@ -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)
{
int todo = len - done;
int cando = min(remote_write_size, PBUFSIZ) / 2 - 32; /* num bytes that will fit */
max_buf_size = min (remote_write_size, PBUFSIZ);
max_buf_size = min (max_buf_size, remote_register_buf_size);
if (todo > cando)
todo = cando;
#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)
{
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);
/* 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 ()
{

View File

@ -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;
}