Fri Mar 20 14:45:36 1998 Michael Snyder <msnyder@cleaver.cygnus.com>
authorMichael Snyder <msnyder@vmware.com>
Fri, 20 Mar 1998 23:33:28 +0000 (23:33 +0000)
committerMichael Snyder <msnyder@vmware.com>
Fri, 20 Mar 1998 23:33:28 +0000 (23:33 +0000)
        * 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.

gdb/ChangeLog
gdb/config/m32r/m32r.mt [new file with mode: 0644]
gdb/gdbserver/low-sim.c
gdb/gdbserver/remote-utils.c

index 65f4dec..003b957 100644 (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
diff --git a/gdb/config/m32r/m32r.mt b/gdb/config/m32r/m32r.mt
new file mode 100644 (file)
index 0000000..a23ba44
--- /dev/null
@@ -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
index 08d600a..8ad6e91 100644 (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;
index a16ba0a..5283404 100644 (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>
-
-extern int remote_desc;
-extern int remote_debugging;
+#include <sys/ioctl.h>
+#include <signal.h>
+#include <fcntl.h>
 
-void remote_open ();
-void remote_send ();
-void putpkt ();
-void getpkt ();
+int remote_debug = 1;
 
-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;