mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-20 01:50:24 +08:00
Fri Mar 20 14:45:36 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
* gdbserver/Makefile.in: add dependency on XM_CLIBS. * gdbserver/low-sim.c (registers) force into alignment. (create_inferior): Fix typo on new_argv; add abfd arg to sim_open, sim_create_inferior. Add reg_size arg to sim_fetch_register, sim_store_register. Make simulator take a single-step to get into a known running state. * gdbserver/gdbreplay.c: include fcntl.h for def'n of F_SETFL. * gdbserver/server.c: Add remote_debug variable to control debug output. * gdbserver/server.h: Add prototypes for enable/disable_async_io. * gdbserver/remote-utils.c: add verbose debugging output controlled by "remote_debug" variable. Add call to "disable_async_io()" to avoid being killed by async SIGIO signals. * config/m32r/m32r.mt: define GDBSERVER_(LIBS and DEPFILES), so that gdbserver can be built with the m32r simulator.
This commit is contained in:
@ -1,3 +1,21 @@
|
|||||||
|
Fri Mar 20 14:45:36 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
|
||||||
|
|
||||||
|
* gdbserver/Makefile.in: add dependency on XM_CLIBS.
|
||||||
|
* gdbserver/low-sim.c (registers) force into alignment.
|
||||||
|
(create_inferior): Fix typo on new_argv; add abfd arg to
|
||||||
|
sim_open, sim_create_inferior. Add reg_size arg to
|
||||||
|
sim_fetch_register, sim_store_register. Make simulator
|
||||||
|
take a single-step to get into a known running state.
|
||||||
|
* gdbserver/gdbreplay.c: include fcntl.h for def'n of F_SETFL.
|
||||||
|
* gdbserver/server.c: Add remote_debug variable to control
|
||||||
|
debug output.
|
||||||
|
* gdbserver/server.h: Add prototypes for enable/disable_async_io.
|
||||||
|
* gdbserver/remote-utils.c: add verbose debugging output controlled
|
||||||
|
by "remote_debug" variable. Add call to "disable_async_io()"
|
||||||
|
to avoid being killed by async SIGIO signals.
|
||||||
|
* config/m32r/m32r.mt: define GDBSERVER_(LIBS and DEPFILES),
|
||||||
|
so that gdbserver can be built with the m32r simulator.
|
||||||
|
|
||||||
Fri Mar 20 09:04:06 1998 Andrew Cagney <cagney@b1.cygnus.com>
|
Fri Mar 20 09:04:06 1998 Andrew Cagney <cagney@b1.cygnus.com>
|
||||||
|
|
||||||
start-sanitize-r5900
|
start-sanitize-r5900
|
||||||
|
7
gdb/config/m32r/m32r.mt
Normal file
7
gdb/config/m32r/m32r.mt
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Target: Mitsubishi m32r processor
|
||||||
|
TDEPFILES= m32r-tdep.o monitor.o m32r-rom.o dsrec.o
|
||||||
|
TM_FILE= tm-m32r.h
|
||||||
|
SIM_OBS = remote-sim.o
|
||||||
|
SIM = ../sim/m32r/libsim.a -lm
|
||||||
|
GDBSERVER_DEPFILES= low-sim.o
|
||||||
|
GDBSERVER_LIBS = ../../sim/m32r/libsim.a ../../bfd/libbfd.a ../../libiberty/libiberty.a ../../opcodes/libopcodes.a -lm
|
@ -23,9 +23,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|||||||
#include "callback.h" /* GDB simulator callback interface */
|
#include "callback.h" /* GDB simulator callback interface */
|
||||||
#include "remote-sim.h" /* GDB simulator interface */
|
#include "remote-sim.h" /* GDB simulator interface */
|
||||||
|
|
||||||
|
extern int remote_debug;
|
||||||
|
|
||||||
extern host_callback default_callback; /* in sim/common/callback.c */
|
extern host_callback default_callback; /* in sim/common/callback.c */
|
||||||
|
|
||||||
char registers[REGISTER_BYTES];
|
char registers[REGISTER_BYTES] __attribute__ ((aligned));
|
||||||
|
|
||||||
int target_byte_order; /* used by simulator */
|
int target_byte_order; /* used by simulator */
|
||||||
|
|
||||||
@ -52,28 +54,28 @@ generic_load (loadfile_bfd)
|
|||||||
if (size > 0)
|
if (size > 0)
|
||||||
{
|
{
|
||||||
char *buffer;
|
char *buffer;
|
||||||
bfd_vma vma;
|
bfd_vma lma; /* use load address, not virtual address */
|
||||||
|
|
||||||
buffer = xmalloc (size);
|
buffer = xmalloc (size);
|
||||||
vma = bfd_get_section_vma (loadfile_bfd, s);
|
lma = s->lma;
|
||||||
|
|
||||||
/* Is this really necessary? I guess it gives the user something
|
/* Is this really necessary? I guess it gives the user something
|
||||||
to look at during a long download. */
|
to look at during a long download. */
|
||||||
fprintf (stderr, "Loading section %s, size 0x%lx vma 0x%lx\n",
|
printf ("Loading section %s, size 0x%lx lma 0x%lx\n",
|
||||||
bfd_get_section_name (loadfile_bfd, s),
|
bfd_get_section_name (loadfile_bfd, s),
|
||||||
(unsigned long) size,
|
(unsigned long) size,
|
||||||
(unsigned long) vma); /* chops high 32 bits. FIXME!! */
|
(unsigned long) lma); /* chops high 32 bits. FIXME!! */
|
||||||
|
|
||||||
bfd_get_section_contents (loadfile_bfd, s, buffer, 0, size);
|
bfd_get_section_contents (loadfile_bfd, s, buffer, 0, size);
|
||||||
|
|
||||||
write_inferior_memory (vma, buffer, size);
|
write_inferior_memory (lma, buffer, size);
|
||||||
free (buffer);
|
free (buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf (stderr, "Start address 0x%lx\n",
|
printf ("Start address 0x%lx\n",
|
||||||
(unsigned long)loadfile_bfd->start_address);
|
(unsigned long)loadfile_bfd->start_address);
|
||||||
|
|
||||||
/* We were doing this in remote-mips.c, I suspect it is right
|
/* We were doing this in remote-mips.c, I suspect it is right
|
||||||
for other targets too. */
|
for other targets too. */
|
||||||
@ -115,25 +117,26 @@ create_inferior (program, argv)
|
|||||||
new_argv = alloca (sizeof (char *) * (nargs + 3)); /* allocate new args */
|
new_argv = alloca (sizeof (char *) * (nargs + 3)); /* allocate new args */
|
||||||
for (nargs = 0; argv[nargs] != NULL; nargs++) /* copy old to new */
|
for (nargs = 0; argv[nargs] != NULL; nargs++) /* copy old to new */
|
||||||
new_argv[nargs] = argv[nargs];
|
new_argv[nargs] = argv[nargs];
|
||||||
new_args[nargs] = "-E";
|
new_argv[nargs] = "-E";
|
||||||
new_args[nargs + 1] = bfd_big_endian (abfd) ? "big" : "little";
|
new_argv[nargs + 1] = bfd_big_endian (abfd) ? "big" : "little";
|
||||||
new_args[nargs + 2] = NULL;
|
new_argv[nargs + 2] = NULL;
|
||||||
argv = new_args;
|
argv = new_argv;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Create an instance of the simulator. */
|
/* Create an instance of the simulator. */
|
||||||
default_callback.init (&default_callback);
|
default_callback.init (&default_callback);
|
||||||
gdbsim_desc = sim_open (SIM_OPEN_STANDALONE, &default_callback, argv);
|
gdbsim_desc = sim_open (SIM_OPEN_STANDALONE, &default_callback, abfd, argv);
|
||||||
if (gdbsim_desc == 0)
|
if (gdbsim_desc == 0)
|
||||||
exit (1);
|
exit (1);
|
||||||
|
|
||||||
/* Load the program into the simulator. */
|
/* Load the program into the simulator. */
|
||||||
if (sim_load (gdbsim_desc, program, NULL, 0) == SIM_RC_FAIL)
|
if (abfd)
|
||||||
generic_load (abfd);
|
if (sim_load (gdbsim_desc, program, NULL, 0) == SIM_RC_FAIL)
|
||||||
|
generic_load (abfd);
|
||||||
|
|
||||||
/* Create an inferior process in the simulator. This initializes SP. */
|
/* Create an inferior process in the simulator. This initializes SP. */
|
||||||
sim_create_inferior (gdbsim_desc, argv, /* env */ NULL);
|
sim_create_inferior (gdbsim_desc, abfd, argv, /* env */ NULL);
|
||||||
|
sim_resume (gdbsim_desc, 1, 0); /* execute one instr */
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +155,8 @@ static void
|
|||||||
fetch_register (regno)
|
fetch_register (regno)
|
||||||
int regno;
|
int regno;
|
||||||
{
|
{
|
||||||
sim_fetch_register (gdbsim_desc, regno, ®isters[REGISTER_BYTE (regno)]);
|
sim_fetch_register (gdbsim_desc, regno, ®isters[REGISTER_BYTE (regno)],
|
||||||
|
REGISTER_RAW_SIZE (regno));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fetch all registers, or just one, from the child process. */
|
/* Fetch all registers, or just one, from the child process. */
|
||||||
@ -182,7 +186,8 @@ store_inferior_registers (regno)
|
|||||||
store_inferior_registers (regno);
|
store_inferior_registers (regno);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
sim_store_register (gdbsim_desc, regno, ®isters[REGISTER_BYTE (regno)]);
|
sim_store_register (gdbsim_desc, regno, ®isters[REGISTER_BYTE (regno)],
|
||||||
|
REGISTER_RAW_SIZE (regno));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return nonzero if the given thread is still alive. */
|
/* Return nonzero if the given thread is still alive. */
|
||||||
@ -206,19 +211,22 @@ mywait (status)
|
|||||||
switch (reason)
|
switch (reason)
|
||||||
{
|
{
|
||||||
case sim_exited:
|
case sim_exited:
|
||||||
fprintf (stderr, "\nChild exited with retcode = %x \n", sigrc);
|
if (remote_debug)
|
||||||
|
printf ("\nChild exited with retcode = %x \n", sigrc);
|
||||||
*status = 'W';
|
*status = 'W';
|
||||||
return sigrc;
|
return sigrc;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
case sim_stopped:
|
case sim_stopped:
|
||||||
fprintf (stderr, "\nChild terminated with signal = %x \n", sigrc);
|
if (remote_debug)
|
||||||
|
printf ("\nChild terminated with signal = %x \n", sigrc);
|
||||||
*status = 'X';
|
*status = 'X';
|
||||||
return sigrc;
|
return sigrc;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default: /* should this be sim_signalled or sim_stopped? FIXME!! */
|
default: /* should this be sim_signalled or sim_stopped? FIXME!! */
|
||||||
fprintf (stderr, "\nChild received signal = %x \n", sigrc);
|
if (remote_debug)
|
||||||
|
printf ("\nChild received signal = %x \n", sigrc);
|
||||||
fetch_inferior_registers (0);
|
fetch_inferior_registers (0);
|
||||||
*status = 'T';
|
*status = 'T';
|
||||||
return (unsigned char) sigrc;
|
return (unsigned char) sigrc;
|
||||||
|
@ -15,48 +15,34 @@ GNU General Public License for more details.
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||||
|
|
||||||
#include "defs.h"
|
#include "server.h"
|
||||||
|
#include "terminal.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <signal.h>
|
#include <string.h>
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <a.out.h>
|
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#include <sgtty.h>
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/types.h>
|
#include <netdb.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <sys/time.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
extern int remote_desc;
|
int remote_debug = 1;
|
||||||
extern int remote_debugging;
|
|
||||||
|
|
||||||
void remote_open ();
|
static int remote_desc;
|
||||||
void remote_send ();
|
|
||||||
void putpkt ();
|
|
||||||
void getpkt ();
|
|
||||||
|
|
||||||
void write_ok ();
|
|
||||||
void write_enn ();
|
|
||||||
void convert_ascii_to_int ();
|
|
||||||
void convert_int_to_ascii ();
|
|
||||||
void prepare_resume_reply ();
|
|
||||||
|
|
||||||
/* Open a connection to a remote debugger.
|
/* Open a connection to a remote debugger.
|
||||||
NAME is the filename used for communication. */
|
NAME is the filename used for communication. */
|
||||||
|
|
||||||
void
|
void
|
||||||
remote_open (name, from_tty)
|
remote_open (name)
|
||||||
char *name;
|
char *name;
|
||||||
int from_tty;
|
|
||||||
{
|
{
|
||||||
struct sgttyb sg;
|
int save_fcntl_flags;
|
||||||
|
|
||||||
remote_debugging = 0;
|
|
||||||
|
|
||||||
if (!strchr (name, ':'))
|
if (!strchr (name, ':'))
|
||||||
{
|
{
|
||||||
@ -64,9 +50,51 @@ remote_open (name, from_tty)
|
|||||||
if (remote_desc < 0)
|
if (remote_desc < 0)
|
||||||
perror_with_name ("Could not open remote device");
|
perror_with_name ("Could not open remote device");
|
||||||
|
|
||||||
ioctl (remote_desc, TIOCGETP, &sg);
|
#ifdef HAVE_TERMIOS
|
||||||
sg.sg_flags = RAW;
|
{
|
||||||
ioctl (remote_desc, TIOCSETP, &sg);
|
struct termios termios;
|
||||||
|
tcgetattr(remote_desc, &termios);
|
||||||
|
|
||||||
|
termios.c_iflag = 0;
|
||||||
|
termios.c_oflag = 0;
|
||||||
|
termios.c_lflag = 0;
|
||||||
|
termios.c_cflag &= ~(CSIZE|PARENB);
|
||||||
|
termios.c_cflag |= CLOCAL | CS8;
|
||||||
|
termios.c_cc[VMIN] = 0;
|
||||||
|
termios.c_cc[VTIME] = 0;
|
||||||
|
|
||||||
|
tcsetattr(remote_desc, TCSANOW, &termios);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_TERMIO
|
||||||
|
{
|
||||||
|
struct termio termio;
|
||||||
|
ioctl (remote_desc, TCGETA, &termio);
|
||||||
|
|
||||||
|
termio.c_iflag = 0;
|
||||||
|
termio.c_oflag = 0;
|
||||||
|
termio.c_lflag = 0;
|
||||||
|
termio.c_cflag &= ~(CSIZE|PARENB);
|
||||||
|
termio.c_cflag |= CLOCAL | CS8;
|
||||||
|
termio.c_cc[VMIN] = 0;
|
||||||
|
termio.c_cc[VTIME] = 0;
|
||||||
|
|
||||||
|
ioctl (remote_desc, TCSETA, &termio);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SGTTY
|
||||||
|
{
|
||||||
|
struct sgttyb sg;
|
||||||
|
|
||||||
|
ioctl (remote_desc, TIOCGETP, &sg);
|
||||||
|
sg.sg_flags = RAW;
|
||||||
|
ioctl (remote_desc, TIOCSETP, &sg);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -74,43 +102,67 @@ remote_open (name, from_tty)
|
|||||||
int port;
|
int port;
|
||||||
struct sockaddr_in sockaddr;
|
struct sockaddr_in sockaddr;
|
||||||
int tmp;
|
int tmp;
|
||||||
|
struct protoent *protoent;
|
||||||
|
int tmp_desc;
|
||||||
|
|
||||||
port_str = strchr (name, ':');
|
port_str = strchr (name, ':');
|
||||||
|
|
||||||
port = atoi (port_str + 1);
|
port = atoi (port_str + 1);
|
||||||
|
|
||||||
remote_desc = socket (PF_INET, SOCK_STREAM, 0);
|
tmp_desc = socket (PF_INET, SOCK_STREAM, 0);
|
||||||
if (remote_desc < 0)
|
if (tmp_desc < 0)
|
||||||
perror_with_name ("Can't open socket");
|
perror_with_name ("Can't open socket");
|
||||||
|
|
||||||
/* Allow rapid reuse of this port. */
|
/* Allow rapid reuse of this port. */
|
||||||
tmp = 1;
|
tmp = 1;
|
||||||
setsockopt (remote_desc, SOL_SOCKET, SO_REUSEADDR, (char *)&tmp,
|
setsockopt (tmp_desc, SOL_SOCKET, SO_REUSEADDR, (char *)&tmp,
|
||||||
sizeof(tmp));
|
sizeof(tmp));
|
||||||
|
|
||||||
/* Enable TCP keep alive process. */
|
|
||||||
tmp = 1;
|
|
||||||
setsockopt (remote_desc, SOL_SOCKET, SO_KEEPALIVE, (char *)&tmp, sizeof(tmp));
|
|
||||||
|
|
||||||
sockaddr.sin_family = PF_INET;
|
sockaddr.sin_family = PF_INET;
|
||||||
sockaddr.sin_port = htons(port);
|
sockaddr.sin_port = htons(port);
|
||||||
sockaddr.sin_addr.s_addr = INADDR_ANY;
|
sockaddr.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
|
||||||
if (bind (remote_desc, &sockaddr, sizeof (sockaddr))
|
if (bind (tmp_desc, (struct sockaddr *)&sockaddr, sizeof (sockaddr))
|
||||||
|| listen (remote_desc, 1))
|
|| listen (tmp_desc, 1))
|
||||||
perror_with_name ("Can't bind address");
|
perror_with_name ("Can't bind address");
|
||||||
|
|
||||||
tmp = sizeof (sockaddr);
|
tmp = sizeof (sockaddr);
|
||||||
remote_desc = accept (remote_desc, &sockaddr, &tmp);
|
remote_desc = accept (tmp_desc, (struct sockaddr *)&sockaddr, &tmp);
|
||||||
if (remote_desc == -1)
|
if (remote_desc == -1)
|
||||||
perror_with_name ("Accept failed");
|
perror_with_name ("Accept failed");
|
||||||
|
|
||||||
|
protoent = getprotobyname ("tcp");
|
||||||
|
if (!protoent)
|
||||||
|
perror_with_name ("getprotobyname");
|
||||||
|
|
||||||
|
/* Enable TCP keep alive process. */
|
||||||
tmp = 1;
|
tmp = 1;
|
||||||
setsockopt (remote_desc, 6, TCP_NODELAY, (char *)&tmp, sizeof(tmp));
|
setsockopt (tmp_desc, SOL_SOCKET, SO_KEEPALIVE, (char *)&tmp, sizeof(tmp));
|
||||||
|
|
||||||
|
/* Tell TCP not to delay small packets. This greatly speeds up
|
||||||
|
interactive response. */
|
||||||
|
tmp = 1;
|
||||||
|
setsockopt (remote_desc, protoent->p_proto, TCP_NODELAY,
|
||||||
|
(char *)&tmp, sizeof(tmp));
|
||||||
|
|
||||||
|
close (tmp_desc); /* No longer need this */
|
||||||
|
|
||||||
|
signal (SIGPIPE, SIG_IGN); /* If we don't do this, then gdbserver simply
|
||||||
|
exits when the remote side dies. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(F_SETFL) && defined (FASYNC)
|
||||||
|
save_fcntl_flags = fcntl (remote_desc, F_GETFL, 0);
|
||||||
|
fcntl (remote_desc, F_SETFL, save_fcntl_flags | FASYNC);
|
||||||
|
disable_async_io ();
|
||||||
|
#endif /* FASYNC */
|
||||||
fprintf (stderr, "Remote debugging using %s\n", name);
|
fprintf (stderr, "Remote debugging using %s\n", name);
|
||||||
remote_debugging = 1;
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
remote_close()
|
||||||
|
{
|
||||||
|
close (remote_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert hex digit A to a number. */
|
/* Convert hex digit A to a number. */
|
||||||
@ -139,25 +191,10 @@ tohex (nib)
|
|||||||
return 'a' + nib - 10;
|
return 'a' + nib - 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Send the command in BUF to the remote machine,
|
|
||||||
and read the reply into BUF.
|
|
||||||
Report an error if we get an error reply. */
|
|
||||||
|
|
||||||
void
|
|
||||||
remote_send (buf)
|
|
||||||
char *buf;
|
|
||||||
{
|
|
||||||
putpkt (buf);
|
|
||||||
getpkt (buf);
|
|
||||||
|
|
||||||
if (buf[0] == 'E')
|
|
||||||
error ("Remote failure reply: E");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Send a packet to the remote machine, with error checking.
|
/* Send a packet to the remote machine, with error checking.
|
||||||
The data of the packet is in BUF. */
|
The data of the packet is in BUF. Returns >= 0 on success, -1 otherwise. */
|
||||||
|
|
||||||
void
|
int
|
||||||
putpkt (buf)
|
putpkt (buf)
|
||||||
char *buf;
|
char *buf;
|
||||||
{
|
{
|
||||||
@ -183,16 +220,76 @@ putpkt (buf)
|
|||||||
*p++ = tohex ((csum >> 4) & 0xf);
|
*p++ = tohex ((csum >> 4) & 0xf);
|
||||||
*p++ = tohex (csum & 0xf);
|
*p++ = tohex (csum & 0xf);
|
||||||
|
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
/* Send it over and over until we get a positive ack. */
|
/* Send it over and over until we get a positive ack. */
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
write (remote_desc, buf2, p - buf2);
|
int cc;
|
||||||
read (remote_desc, buf3, 1);
|
|
||||||
|
if (write (remote_desc, buf2, p - buf2) != p - buf2)
|
||||||
|
{
|
||||||
|
perror ("putpkt(write)");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remote_debug)
|
||||||
|
printf ("putpkt (\"%s\"); [looking for ack]\n", buf2);
|
||||||
|
cc = read (remote_desc, buf3, 1);
|
||||||
|
if (remote_debug)
|
||||||
|
printf ("[received '%c' (0x%x)]\n", buf3[0], buf3[0]);
|
||||||
|
if (cc <= 0)
|
||||||
|
{
|
||||||
|
if (cc == 0)
|
||||||
|
fprintf (stderr, "putpkt(read): Got EOF\n");
|
||||||
|
else
|
||||||
|
perror ("putpkt(read)");
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while (buf3[0] != '+');
|
while (buf3[0] != '+');
|
||||||
|
|
||||||
|
return 1; /* Success! */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Come here when we get an input interrupt from the remote side. This
|
||||||
|
interrupt should only be active while we are waiting for the child to do
|
||||||
|
something. About the only thing that should come through is a ^C, which
|
||||||
|
will cause us to send a SIGINT to the child. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
input_interrupt()
|
||||||
|
{
|
||||||
|
int cc;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
cc = read (remote_desc, &c, 1);
|
||||||
|
|
||||||
|
if (cc != 1 || c != '\003')
|
||||||
|
{
|
||||||
|
fprintf(stderr, "input_interrupt, cc = %d c = %d\n", cc, c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
kill (inferior_pid, SIGINT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
enable_async_io()
|
||||||
|
{
|
||||||
|
signal (SIGIO, input_interrupt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
disable_async_io()
|
||||||
|
{
|
||||||
|
signal (SIGIO, SIG_IGN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns next char from remote GDB. -1 if error. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
readchar ()
|
readchar ()
|
||||||
{
|
{
|
||||||
@ -207,8 +304,12 @@ readchar ()
|
|||||||
|
|
||||||
if (bufcnt <= 0)
|
if (bufcnt <= 0)
|
||||||
{
|
{
|
||||||
perror ("readchar");
|
if (bufcnt == 0)
|
||||||
fatal ("read error, quitting");
|
fprintf (stderr, "readchar: Got EOF\n");
|
||||||
|
else
|
||||||
|
perror ("readchar");
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bufp = buf;
|
bufp = buf;
|
||||||
@ -217,9 +318,9 @@ readchar ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Read a packet from the remote machine, with error checking,
|
/* Read a packet from the remote machine, with error checking,
|
||||||
and store it in BUF. */
|
and store it in BUF. Returns length of packet, or negative if error. */
|
||||||
|
|
||||||
void
|
int
|
||||||
getpkt (buf)
|
getpkt (buf)
|
||||||
char *buf;
|
char *buf;
|
||||||
{
|
{
|
||||||
@ -231,12 +332,23 @@ getpkt (buf)
|
|||||||
{
|
{
|
||||||
csum = 0;
|
csum = 0;
|
||||||
|
|
||||||
while ((c = readchar ()) != '$');
|
while (1)
|
||||||
|
{
|
||||||
|
c = readchar ();
|
||||||
|
if (c == '$')
|
||||||
|
break;
|
||||||
|
if (remote_debug)
|
||||||
|
printf ("[getpkt: discarding char '%c']\n", c);
|
||||||
|
if (c < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
bp = buf;
|
bp = buf;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
c = readchar ();
|
c = readchar ();
|
||||||
|
if (c < 0)
|
||||||
|
return -1;
|
||||||
if (c == '#')
|
if (c == '#')
|
||||||
break;
|
break;
|
||||||
*bp++ = c;
|
*bp++ = c;
|
||||||
@ -246,6 +358,7 @@ getpkt (buf)
|
|||||||
|
|
||||||
c1 = fromhex (readchar ());
|
c1 = fromhex (readchar ());
|
||||||
c2 = fromhex (readchar ());
|
c2 = fromhex (readchar ());
|
||||||
|
|
||||||
if (csum == (c1 << 4) + c2)
|
if (csum == (c1 << 4) + c2)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -254,7 +367,14 @@ getpkt (buf)
|
|||||||
write (remote_desc, "-", 1);
|
write (remote_desc, "-", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (remote_debug)
|
||||||
|
printf ("getpkt (\"%s\"); [sending ack] \n", buf);
|
||||||
|
|
||||||
write (remote_desc, "+", 1);
|
write (remote_desc, "+", 1);
|
||||||
|
|
||||||
|
if (remote_debug)
|
||||||
|
printf ("[sent ack]\n");
|
||||||
|
return bp - buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -262,7 +382,7 @@ write_ok (buf)
|
|||||||
char *buf;
|
char *buf;
|
||||||
{
|
{
|
||||||
buf[0] = 'O';
|
buf[0] = 'O';
|
||||||
buf[1] = 'k';
|
buf[1] = 'K';
|
||||||
buf[2] = '\0';
|
buf[2] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,49 +435,70 @@ outreg(regno, buf)
|
|||||||
char *buf;
|
char *buf;
|
||||||
{
|
{
|
||||||
extern char registers[];
|
extern char registers[];
|
||||||
|
int regsize = REGISTER_RAW_SIZE (regno);
|
||||||
|
|
||||||
*buf++ = tohex (regno >> 4);
|
*buf++ = tohex (regno >> 4);
|
||||||
*buf++ = tohex (regno & 0xf);
|
*buf++ = tohex (regno & 0xf);
|
||||||
*buf++ = ':';
|
*buf++ = ':';
|
||||||
convert_int_to_ascii (®isters[REGISTER_BYTE (regno)], buf, 4);
|
convert_int_to_ascii (®isters[REGISTER_BYTE (regno)], buf, regsize);
|
||||||
buf += 8;
|
buf += 2 * regsize;
|
||||||
*buf++ = ';';
|
*buf++ = ';';
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
prepare_resume_reply (buf, status, signal)
|
prepare_resume_reply (buf, status, signo)
|
||||||
char *buf, status;
|
char *buf;
|
||||||
unsigned char signal;
|
char status;
|
||||||
|
unsigned char signo;
|
||||||
{
|
{
|
||||||
int nib;
|
int nib;
|
||||||
char ch;
|
|
||||||
|
|
||||||
*buf++ = 'T';
|
*buf++ = status;
|
||||||
|
|
||||||
nib = ((signal & 0xf0) >> 4);
|
/* FIXME! Should be converting this signal number (numbered
|
||||||
|
according to the signal numbering of the system we are running on)
|
||||||
|
to the signal numbers used by the gdb protocol (see enum target_signal
|
||||||
|
in gdb/target.h). */
|
||||||
|
nib = ((signo & 0xf0) >> 4);
|
||||||
*buf++ = tohex (nib);
|
*buf++ = tohex (nib);
|
||||||
nib = signal & 0x0f;
|
nib = signo & 0x0f;
|
||||||
*buf++ = tohex (nib);
|
*buf++ = tohex (nib);
|
||||||
|
|
||||||
buf = outreg (PC_REGNUM, buf);
|
if (status == 'T')
|
||||||
buf = outreg (FP_REGNUM, buf);
|
{
|
||||||
buf = outreg (SP_REGNUM, buf);
|
buf = outreg (PC_REGNUM, buf);
|
||||||
|
buf = outreg (FP_REGNUM, buf);
|
||||||
|
buf = outreg (SP_REGNUM, buf);
|
||||||
#ifdef NPC_REGNUM
|
#ifdef NPC_REGNUM
|
||||||
buf = outreg (NPC_REGNUM, buf);
|
buf = outreg (NPC_REGNUM, buf);
|
||||||
#endif
|
#endif
|
||||||
#ifdef O7_REGNUM
|
#ifdef O7_REGNUM
|
||||||
buf = outreg (O7_REGNUM, buf);
|
buf = outreg (O7_REGNUM, buf);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* If the debugger hasn't used any thread features, don't burden it with
|
||||||
|
threads. If we didn't check this, GDB 4.13 and older would choke. */
|
||||||
|
if (cont_thread != 0)
|
||||||
|
{
|
||||||
|
if (old_thread_from_wait != thread_from_wait)
|
||||||
|
{
|
||||||
|
sprintf (buf, "thread:%x;", thread_from_wait);
|
||||||
|
buf += strlen (buf);
|
||||||
|
old_thread_from_wait = thread_from_wait;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* For W and X, we're done. */
|
||||||
*buf++ = 0;
|
*buf++ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
decode_m_packet (from, mem_addr_ptr, len_ptr)
|
decode_m_packet (from, mem_addr_ptr, len_ptr)
|
||||||
char *from;
|
char *from;
|
||||||
unsigned int *mem_addr_ptr, *len_ptr;
|
CORE_ADDR *mem_addr_ptr;
|
||||||
|
unsigned int *len_ptr;
|
||||||
{
|
{
|
||||||
int i = 0, j = 0;
|
int i = 0, j = 0;
|
||||||
char ch;
|
char ch;
|
||||||
@ -381,9 +522,10 @@ decode_m_packet (from, mem_addr_ptr, len_ptr)
|
|||||||
void
|
void
|
||||||
decode_M_packet (from, mem_addr_ptr, len_ptr, to)
|
decode_M_packet (from, mem_addr_ptr, len_ptr, to)
|
||||||
char *from, *to;
|
char *from, *to;
|
||||||
unsigned int *mem_addr_ptr, *len_ptr;
|
CORE_ADDR *mem_addr_ptr;
|
||||||
|
unsigned int *len_ptr;
|
||||||
{
|
{
|
||||||
int i = 0, j = 0;
|
int i = 0;
|
||||||
char ch;
|
char ch;
|
||||||
*mem_addr_ptr = *len_ptr = 0;
|
*mem_addr_ptr = *len_ptr = 0;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user