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>
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 "remote-sim.h" /* GDB simulator interface */
extern int remote_debug;
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 */
@ -52,28 +54,28 @@ generic_load (loadfile_bfd)
if (size > 0)
{
char *buffer;
bfd_vma vma;
bfd_vma lma; /* use load address, not virtual address */
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
to look at during a long download. */
fprintf (stderr, "Loading section %s, size 0x%lx vma 0x%lx\n",
bfd_get_section_name (loadfile_bfd, s),
(unsigned long) size,
(unsigned long) vma); /* chops high 32 bits. FIXME!! */
printf ("Loading section %s, size 0x%lx lma 0x%lx\n",
bfd_get_section_name (loadfile_bfd, s),
(unsigned long) size,
(unsigned long) lma); /* chops high 32 bits. FIXME!! */
bfd_get_section_contents (loadfile_bfd, s, buffer, 0, size);
write_inferior_memory (vma, buffer, size);
write_inferior_memory (lma, buffer, size);
free (buffer);
}
}
}
fprintf (stderr, "Start address 0x%lx\n",
(unsigned long)loadfile_bfd->start_address);
printf ("Start address 0x%lx\n",
(unsigned long)loadfile_bfd->start_address);
/* We were doing this in remote-mips.c, I suspect it is right
for other targets too. */
@ -115,25 +117,26 @@ create_inferior (program, argv)
new_argv = alloca (sizeof (char *) * (nargs + 3)); /* allocate new args */
for (nargs = 0; argv[nargs] != NULL; nargs++) /* copy old to new */
new_argv[nargs] = argv[nargs];
new_args[nargs] = "-E";
new_args[nargs + 1] = bfd_big_endian (abfd) ? "big" : "little";
new_args[nargs + 2] = NULL;
argv = new_args;
new_argv[nargs] = "-E";
new_argv[nargs + 1] = bfd_big_endian (abfd) ? "big" : "little";
new_argv[nargs + 2] = NULL;
argv = new_argv;
#endif
/* Create an instance of the simulator. */
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)
exit (1);
/* Load the program into the simulator. */
if (sim_load (gdbsim_desc, program, NULL, 0) == SIM_RC_FAIL)
generic_load (abfd);
if (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. */
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;
}
@ -152,7 +155,8 @@ static void
fetch_register (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. */
@ -182,7 +186,8 @@ store_inferior_registers (regno)
store_inferior_registers (regno);
}
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. */
@ -206,19 +211,22 @@ mywait (status)
switch (reason)
{
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';
return sigrc;
#if 0
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';
return sigrc;
#endif
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);
*status = 'T';
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
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 <signal.h>
#include <sys/wait.h>
#include <string.h>
#include <sys/ioctl.h>
#include <a.out.h>
#include <sys/file.h>
#include <sgtty.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netdb.h>
#include <netinet/tcp.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <signal.h>
#include <fcntl.h>
extern int remote_desc;
extern int remote_debugging;
int remote_debug = 1;
void remote_open ();
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 ();
static int remote_desc;
/* Open a connection to a remote debugger.
NAME is the filename used for communication. */
void
remote_open (name, from_tty)
remote_open (name)
char *name;
int from_tty;
{
struct sgttyb sg;
remote_debugging = 0;
int save_fcntl_flags;
if (!strchr (name, ':'))
{
@ -64,9 +50,51 @@ remote_open (name, from_tty)
if (remote_desc < 0)
perror_with_name ("Could not open remote device");
ioctl (remote_desc, TIOCGETP, &sg);
sg.sg_flags = RAW;
ioctl (remote_desc, TIOCSETP, &sg);
#ifdef HAVE_TERMIOS
{
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
{
@ -74,43 +102,67 @@ remote_open (name, from_tty)
int port;
struct sockaddr_in sockaddr;
int tmp;
struct protoent *protoent;
int tmp_desc;
port_str = strchr (name, ':');
port = atoi (port_str + 1);
remote_desc = socket (PF_INET, SOCK_STREAM, 0);
if (remote_desc < 0)
tmp_desc = socket (PF_INET, SOCK_STREAM, 0);
if (tmp_desc < 0)
perror_with_name ("Can't open socket");
/* Allow rapid reuse of this port. */
tmp = 1;
setsockopt (remote_desc, SOL_SOCKET, SO_REUSEADDR, (char *)&tmp,
setsockopt (tmp_desc, SOL_SOCKET, SO_REUSEADDR, (char *)&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_port = htons(port);
sockaddr.sin_addr.s_addr = INADDR_ANY;
if (bind (remote_desc, &sockaddr, sizeof (sockaddr))
|| listen (remote_desc, 1))
if (bind (tmp_desc, (struct sockaddr *)&sockaddr, sizeof (sockaddr))
|| listen (tmp_desc, 1))
perror_with_name ("Can't bind address");
tmp = sizeof (sockaddr);
remote_desc = accept (remote_desc, &sockaddr, &tmp);
remote_desc = accept (tmp_desc, (struct sockaddr *)&sockaddr, &tmp);
if (remote_desc == -1)
perror_with_name ("Accept failed");
protoent = getprotobyname ("tcp");
if (!protoent)
perror_with_name ("getprotobyname");
/* Enable TCP keep alive process. */
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);
remote_debugging = 1;
}
void
remote_close()
{
close (remote_desc);
}
/* Convert hex digit A to a number. */
@ -139,25 +191,10 @@ tohex (nib)
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.
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)
char *buf;
{
@ -183,16 +220,76 @@ putpkt (buf)
*p++ = tohex ((csum >> 4) & 0xf);
*p++ = tohex (csum & 0xf);
*p = '\0';
/* Send it over and over until we get a positive ack. */
do
{
write (remote_desc, buf2, p - buf2);
read (remote_desc, buf3, 1);
int cc;
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] != '+');
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
readchar ()
{
@ -207,8 +304,12 @@ readchar ()
if (bufcnt <= 0)
{
perror ("readchar");
fatal ("read error, quitting");
if (bufcnt == 0)
fprintf (stderr, "readchar: Got EOF\n");
else
perror ("readchar");
return -1;
}
bufp = buf;
@ -217,9 +318,9 @@ readchar ()
}
/* 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)
char *buf;
{
@ -231,12 +332,23 @@ getpkt (buf)
{
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;
while (1)
{
c = readchar ();
if (c < 0)
return -1;
if (c == '#')
break;
*bp++ = c;
@ -246,6 +358,7 @@ getpkt (buf)
c1 = fromhex (readchar ());
c2 = fromhex (readchar ());
if (csum == (c1 << 4) + c2)
break;
@ -254,7 +367,14 @@ getpkt (buf)
write (remote_desc, "-", 1);
}
if (remote_debug)
printf ("getpkt (\"%s\"); [sending ack] \n", buf);
write (remote_desc, "+", 1);
if (remote_debug)
printf ("[sent ack]\n");
return bp - buf;
}
void
@ -262,7 +382,7 @@ write_ok (buf)
char *buf;
{
buf[0] = 'O';
buf[1] = 'k';
buf[1] = 'K';
buf[2] = '\0';
}
@ -315,49 +435,70 @@ outreg(regno, buf)
char *buf;
{
extern char registers[];
int regsize = REGISTER_RAW_SIZE (regno);
*buf++ = tohex (regno >> 4);
*buf++ = tohex (regno & 0xf);
*buf++ = ':';
convert_int_to_ascii (&registers[REGISTER_BYTE (regno)], buf, 4);
buf += 8;
convert_int_to_ascii (&registers[REGISTER_BYTE (regno)], buf, regsize);
buf += 2 * regsize;
*buf++ = ';';
return buf;
}
void
prepare_resume_reply (buf, status, signal)
char *buf, status;
unsigned char signal;
prepare_resume_reply (buf, status, signo)
char *buf;
char status;
unsigned char signo;
{
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);
nib = signal & 0x0f;
nib = signo & 0x0f;
*buf++ = tohex (nib);
buf = outreg (PC_REGNUM, buf);
buf = outreg (FP_REGNUM, buf);
buf = outreg (SP_REGNUM, buf);
if (status == 'T')
{
buf = outreg (PC_REGNUM, buf);
buf = outreg (FP_REGNUM, buf);
buf = outreg (SP_REGNUM, buf);
#ifdef NPC_REGNUM
buf = outreg (NPC_REGNUM, buf);
buf = outreg (NPC_REGNUM, buf);
#endif
#ifdef O7_REGNUM
buf = outreg (O7_REGNUM, buf);
buf = outreg (O7_REGNUM, buf);
#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;
}
void
decode_m_packet (from, mem_addr_ptr, len_ptr)
char *from;
unsigned int *mem_addr_ptr, *len_ptr;
CORE_ADDR *mem_addr_ptr;
unsigned int *len_ptr;
{
int i = 0, j = 0;
char ch;
@ -381,9 +522,10 @@ decode_m_packet (from, mem_addr_ptr, len_ptr)
void
decode_M_packet (from, mem_addr_ptr, len_ptr, 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;
*mem_addr_ptr = *len_ptr = 0;