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:
Michael Snyder
1998-03-20 23:33:28 +00:00
parent 25957cb064
commit d1732185ee
4 changed files with 282 additions and 107 deletions

View File

@ -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
View 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

View File

@ -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, &registers[REGISTER_BYTE (regno)]); sim_fetch_register (gdbsim_desc, regno, &registers[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, &registers[REGISTER_BYTE (regno)]); sim_store_register (gdbsim_desc, regno, &registers[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;

View File

@ -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 (&registers[REGISTER_BYTE (regno)], buf, 4); convert_int_to_ascii (&registers[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;