* 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:
parent
ab83171da5
commit
0a325463ed
|
@ -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>
|
Thu Apr 3 15:10:30 1997 Michael Snyder <msnyder@cleaver.cygnus.com>
|
||||||
|
|
||||||
* blockframe.c: blockvector_for_pc_sect(), block_for_pc_sect(),
|
* blockframe.c: blockvector_for_pc_sect(), block_for_pc_sect(),
|
||||||
|
|
169
gdb/remote.c
169
gdb/remote.c
|
@ -1,5 +1,5 @@
|
||||||
/* Remote target communications for serial-line targets in custom GDB protocol
|
/* 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.
|
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,
|
If AA..AA is omitted,
|
||||||
resume at same address.
|
resume at same address.
|
||||||
|
|
||||||
continue with Csig;AA Continue with signal sig (hex signal
|
continue with Csig;AA..AA Continue with signal sig (hex signal
|
||||||
signal number).
|
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
|
signal
|
||||||
|
|
||||||
last signal ? Reply the current reason for stopping.
|
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 *));
|
static int remote_remove_breakpoint PARAMS ((CORE_ADDR, char *));
|
||||||
|
|
||||||
extern struct target_ops remote_ops; /* Forward decl */
|
static struct target_ops remote_ops; /* Forward decl */
|
||||||
extern struct target_ops extended_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.
|
/* This was 5 seconds, which is a long time to sit and wait.
|
||||||
Unless this is going though some terminal server or multiplexer or
|
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
|
/* 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
|
remote_open knows that we don't have a file open when the program
|
||||||
starts. */
|
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
|
/* 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
|
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;
|
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
|
/* 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. */
|
doesn't support 'P', the only consequence is some unnecessary traffic. */
|
||||||
static int stub_supports_P = 1;
|
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
|
/* These are the threads which we last sent to the remote system. -1 for all
|
||||||
or -2 for not sent yet. */
|
or -2 for not sent yet. */
|
||||||
|
@ -663,6 +676,11 @@ remote_resume (pid, step, siggnal)
|
||||||
last_sent_signal = siggnal;
|
last_sent_signal = siggnal;
|
||||||
last_sent_step = step;
|
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)
|
if (siggnal != TARGET_SIGNAL_0)
|
||||||
{
|
{
|
||||||
buf[0] = step ? 'S' : 'C';
|
buf[0] = step ? 'S' : 'C';
|
||||||
|
@ -754,6 +772,11 @@ remote_wait (pid, status)
|
||||||
getpkt ((char *) buf, 1);
|
getpkt ((char *) buf, 1);
|
||||||
signal (SIGINT, ofunc);
|
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])
|
switch (buf[0])
|
||||||
{
|
{
|
||||||
case 'E': /* Error of some sort */
|
case 'E': /* Error of some sort */
|
||||||
|
@ -915,6 +938,9 @@ remote_fetch_registers (regno)
|
||||||
sprintf (buf, "g");
|
sprintf (buf, "g");
|
||||||
remote_send (buf);
|
remote_send (buf);
|
||||||
|
|
||||||
|
if (remote_register_buf_size == 0)
|
||||||
|
remote_register_buf_size = strlen (buf);
|
||||||
|
|
||||||
/* Unimplemented registers read as all bits zero. */
|
/* Unimplemented registers read as all bits zero. */
|
||||||
memset (regs, 0, REGISTER_BYTES);
|
memset (regs, 0, REGISTER_BYTES);
|
||||||
|
|
||||||
|
@ -1068,6 +1094,21 @@ remote_store_word (addr, word)
|
||||||
#endif /* 0 (unused?) */
|
#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.
|
/* Write memory data directly to the remote machine.
|
||||||
This does not inform the data cache; the data cache uses this.
|
This does not inform the data cache; the data cache uses this.
|
||||||
MEMADDR is the address in the remote memory space.
|
MEMADDR is the address in the remote memory space.
|
||||||
|
@ -1082,24 +1123,32 @@ remote_write_bytes (memaddr, myaddr, len)
|
||||||
char *myaddr;
|
char *myaddr;
|
||||||
int len;
|
int len;
|
||||||
{
|
{
|
||||||
char buf[PBUFSIZ];
|
int max_buf_size; /* Max size of packet output buffer */
|
||||||
int i;
|
int origlen;
|
||||||
char *p;
|
|
||||||
int done;
|
|
||||||
/* Chop the transfer down if necessary */
|
/* Chop the transfer down if necessary */
|
||||||
|
|
||||||
done = 0;
|
max_buf_size = min (remote_write_size, PBUFSIZ);
|
||||||
while (done < len)
|
max_buf_size = min (max_buf_size, remote_register_buf_size);
|
||||||
{
|
|
||||||
int todo = len - done;
|
|
||||||
int cando = min(remote_write_size, PBUFSIZ) / 2 - 32; /* num bytes that will fit */
|
|
||||||
|
|
||||||
if (todo > cando)
|
#define PACKET_OVERHEAD (1 + 1 + 1 + 2) /* $x#xx - Overhead for all types of packets */
|
||||||
todo = cando;
|
|
||||||
|
/* 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
|
/* FIXME-32x64: Need a version of print_address_numeric which puts the
|
||||||
result in a buffer like sprintf. */
|
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,
|
/* We send target system values byte by byte, in increasing byte addresses,
|
||||||
each byte encoded as two hex characters. */
|
each byte encoded as two hex characters. */
|
||||||
|
@ -1107,8 +1156,8 @@ remote_write_bytes (memaddr, myaddr, len)
|
||||||
p = buf + strlen (buf);
|
p = buf + strlen (buf);
|
||||||
for (i = 0; i < todo; i++)
|
for (i = 0; i < todo; i++)
|
||||||
{
|
{
|
||||||
*p++ = tohex ((myaddr[i + done] >> 4) & 0xf);
|
*p++ = tohex ((myaddr[i] >> 4) & 0xf);
|
||||||
*p++ = tohex (myaddr[i + done] & 0xf);
|
*p++ = tohex (myaddr[i] & 0xf);
|
||||||
}
|
}
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
|
@ -1124,9 +1173,11 @@ remote_write_bytes (memaddr, myaddr, len)
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
done += todo;
|
myaddr += todo;
|
||||||
|
memaddr += todo;
|
||||||
|
len -= todo;
|
||||||
}
|
}
|
||||||
return len;
|
return origlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read memory data directly from the remote machine.
|
/* Read memory data directly from the remote machine.
|
||||||
|
@ -1143,28 +1194,30 @@ remote_read_bytes (memaddr, myaddr, len)
|
||||||
char *myaddr;
|
char *myaddr;
|
||||||
int len;
|
int len;
|
||||||
{
|
{
|
||||||
char buf[PBUFSIZ];
|
int max_buf_size; /* Max size of packet output buffer */
|
||||||
int i;
|
int origlen;
|
||||||
char *p;
|
|
||||||
int done;
|
|
||||||
/* Chop transfer down if neccessary */
|
|
||||||
|
|
||||||
#if 0
|
/* Chop the transfer down if necessary */
|
||||||
/* FIXME: This is wrong for larger packets */
|
|
||||||
if (len > PBUFSIZ / 2 - 1)
|
max_buf_size = min (remote_write_size, PBUFSIZ);
|
||||||
abort ();
|
max_buf_size = min (max_buf_size, remote_register_buf_size);
|
||||||
#endif
|
|
||||||
done = 0;
|
/* packet overhead */
|
||||||
while (done < len)
|
max_buf_size -= PACKET_OVERHEAD;
|
||||||
|
|
||||||
|
origlen = len;
|
||||||
|
while (len > 0)
|
||||||
{
|
{
|
||||||
int todo = len - done;
|
char buf[PBUFSIZ];
|
||||||
int cando = PBUFSIZ / 2 - 32; /* number of bytes that will fit. */
|
char *p;
|
||||||
if (todo > cando)
|
int todo;
|
||||||
todo = cando;
|
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
|
/* FIXME-32x64: Need a version of print_address_numeric which puts the
|
||||||
result in a buffer like sprintf. */
|
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);
|
putpkt (buf);
|
||||||
getpkt (buf, 0);
|
getpkt (buf, 0);
|
||||||
|
|
||||||
|
@ -1187,13 +1240,15 @@ remote_read_bytes (memaddr, myaddr, len)
|
||||||
if (p[0] == 0 || p[1] == 0)
|
if (p[0] == 0 || p[1] == 0)
|
||||||
/* Reply is short. This means that we were able to read only part
|
/* Reply is short. This means that we were able to read only part
|
||||||
of what we wanted to. */
|
of what we wanted to. */
|
||||||
return i + done;
|
return i + (origlen - len);
|
||||||
myaddr[i + done] = fromhex (p[0]) * 16 + fromhex (p[1]);
|
myaddr[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
|
||||||
p += 2;
|
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
|
/* 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 */
|
/* Define the target subroutine names */
|
||||||
|
|
||||||
struct target_ops remote_ops = {
|
static struct target_ops remote_ops =
|
||||||
|
{
|
||||||
"remote", /* to_shortname */
|
"remote", /* to_shortname */
|
||||||
"Remote serial target in gdb-specific protocol", /* to_longname */
|
"Remote serial target in gdb-specific protocol", /* to_longname */
|
||||||
"Use a remote computer via a serial line, using a gdb-specific protocol.\n\
|
"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 */
|
OPS_MAGIC /* to_magic */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct target_ops extended_remote_ops = {
|
static struct target_ops extended_remote_ops =
|
||||||
|
{
|
||||||
"extended-remote", /* to_shortname */
|
"extended-remote", /* to_shortname */
|
||||||
"Extended remote serial target in gdb-specific protocol",/* to_longname */
|
"Extended remote serial target in gdb-specific protocol",/* to_longname */
|
||||||
"Use a remote computer via a serial line, using a gdb-specific protocol.\n\
|
"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 */
|
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
|
void
|
||||||
_initialize_remote ()
|
_initialize_remote ()
|
||||||
{
|
{
|
||||||
|
|
|
@ -262,7 +262,7 @@ sh_frame_find_saved_regs (fi, fsr)
|
||||||
}
|
}
|
||||||
else if (IS_MOV_R3 (insn))
|
else if (IS_MOV_R3 (insn))
|
||||||
{
|
{
|
||||||
r3_val = (char) (insn & 0xff);
|
r3_val = ((insn & 0xff) ^ 0x80) - 0x80;
|
||||||
pc += 2;
|
pc += 2;
|
||||||
insn = read_memory_integer (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))
|
else if (IS_ADD_SP (insn))
|
||||||
{
|
{
|
||||||
pc += 2;
|
pc += 2;
|
||||||
depth += -((char) (insn & 0xff));
|
depth -= ((insn & 0xff) ^ 0x80) - 0x80;
|
||||||
insn = read_memory_integer (pc, 2);
|
insn = read_memory_integer (pc, 2);
|
||||||
}
|
}
|
||||||
else
|
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);
|
sh_set_processor_type_command (strsave (DEFAULT_SH_TYPE), 0);
|
||||||
|
|
||||||
add_com ("regs", class_vars, sh_show_regs, "Print all registers");
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue