* remote.c (getpkt): Error if input exceeds buffer size.
authorJohn Gilmore <gnu@cygnus>
Fri, 19 Jun 1992 21:09:54 +0000 (21:09 +0000)
committerJohn Gilmore <gnu@cygnus>
Fri, 19 Jun 1992 21:09:54 +0000 (21:09 +0000)
(_initialize_remote):  `set remotedebug' enables packet trace.

* dbxread.c (process_one_symbol:N_FUN):  GCC now produces relative
N_SLINE's, etc, just like Sun cc on Solaris2.

* am29k-tdep.c (read_register_stack, write_register_stack):
Change RSTACK_HIGH_ADDR to rstack_high_address, a user-settable
variable.  Add `set' and `show' commands for it.
* doc/gdb.texinfo:  Document it.

* eval.c:  Avoid residue-by-zero when evaluating without side effects.
(Bug and fix found by Pierre Willard.)

* sparc-tdep.c:  Clean up slightly for Solaris2.

gdb/ChangeLog
gdb/am29k-tdep.c
gdb/dbxread.c
gdb/eval.c
gdb/remote.c
gdb/sparc-tdep.c

index a2ea8340b977e43c0f48612addd8cbf486ab2f19..4bee5943c60b0761314ed4cda3fd2dcc1cfc3450 100644 (file)
@@ -1,3 +1,16 @@
+Fri Jun 19 10:28:05 1992  John Gilmore  (gnu at cygnus.com)
+
+       * remote.c (getpkt):  Error if input exceeds buffer size.
+       (_initialize_remote):  `set remotedebug' enables packet trace.
+
+       * dbxread.c (process_one_symbol:N_FUN):  GCC now produces relative
+       N_SLINE's, etc, just like Sun cc on Solaris2.   
+
+       * am29k-tdep.c (read_register_stack, write_register_stack):
+       Change RSTACK_HIGH_ADDR to rstack_high_address, a user-settable
+       variable.  Add `set' and `show' commands for it.
+       * doc/gdb.texinfo:  Document it.
+
 Thu Jun 18 19:35:22 1992  Fred Fish  (fnf@cygnus.com)
 
        * valprint.c (type_print_1):  Plug memory leak.  Print all
@@ -6,6 +19,11 @@ Thu Jun 18 19:35:22 1992  Fred Fish  (fnf@cygnus.com)
        type, do a lookup of signed char, not plain char.  Plain char's
        still get looked up as plain char's elsewhere.
 
+Thu Jun 18 18:59:04 1992  John Gilmore  (gnu at cygnus.com)
+
+       * eval.c:  Avoid residue-by-zero when evaluating without side effects.
+       (Bug and fix found by Pierre Willard.)
+
 Wed Jun 17 13:08:33 1992  Stu Grossman  (grossman at cygnus.com)
 
        * xm-rs6000.h:  Fix decls for malloc, realloc, and free.
@@ -82,6 +100,8 @@ Mon Jun 15 07:21:00 1992  Fred Fish  (fnf@cygnus.com)
 
 Mon Jun 15 01:45:48 1992  John Gilmore  (gnu at cygnus.com)
 
+       * sparc-tdep.c:  Clean up slightly for Solaris2.
+
        * buildsym.c (define_symbol):  Nameless types are now on several
        platforms; generalize them and un-ifdef them to make Solaris 2
        work.
index f76d02e88cfb2f0d73e0e7c42fcba5519f6c96c2..03c07c504a53f8bced4629664edbe6922c3f1276 100644 (file)
@@ -26,9 +26,16 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 /*#include <sys/param.h> */
 #include "symtab.h"
 #include "inferior.h"
+#include "gdbcmd.h"
 
 extern CORE_ADDR text_start;   /* FIXME, kludge... */
 
+/* The user-settable top of the register stack in virtual memory.  We
+   won't attempt to access any stored registers above this address, if set
+   nonzero.  */
+
+static CORE_ADDR rstack_high_address = UINT_MAX;
+
 /* Structure to hold cached info about function prologues.  */
 struct prologue_info
 {
@@ -504,9 +511,8 @@ read_register_stack (memaddr, myaddr, actual_mem_addr, lval)
   long rfb = read_register (RFB_REGNUM);
   long rsp = read_register (RSP_REGNUM);
 
-#ifdef RSTACK_HIGH_ADDR        /* Highest allowed address in register stack */
   /* If we don't do this 'info register' stops in the middle. */
-  if (memaddr >= RSTACK_HIGH_ADDR
+  if (memaddr >= rstack_high_address
     {
       int val=-1;                      /* a bogus value */
       /* It's in a local register, but off the end of the stack.  */
@@ -519,9 +525,7 @@ read_register_stack (memaddr, myaddr, actual_mem_addr, lval)
       if (actual_mem_addr != NULL)
        *actual_mem_addr = REGISTER_BYTE (regnum);
     }
-  else
-#endif /* RSTACK_HIGH_ADDR */
-  if (memaddr < rfb)
+  else if (memaddr < rfb)
     {
       /* It's in a register.  */
       int regnum = (memaddr - rsp) / 4 + LR0_REGNUM;
@@ -570,17 +574,14 @@ write_register_stack (memaddr, myaddr, actual_mem_addr)
 {
   long rfb = read_register (RFB_REGNUM);
   long rsp = read_register (RSP_REGNUM);
-#ifdef RSTACK_HIGH_ADDR        /* Highest allowed address in register stack */
   /* If we don't do this 'info register' stops in the middle. */
-  if (memaddr >= RSTACK_HIGH_ADDR
+  if (memaddr >= rstack_high_address
     {
       /* It's in a register, but off the end of the stack.  */
       if (actual_mem_addr != NULL)
        *actual_mem_addr = NULL; 
     }
-  else
-#endif /* RSTACK_HIGH_ADDR */
-  if (memaddr < rfb)
+  else if (memaddr < rfb)
     {
       /* It's in a register.  */
       int regnum = (memaddr - rsp) / 4 + LR0_REGNUM;
@@ -812,5 +813,13 @@ _initialize_29k()
 {
   add_com ("reginv ", class_obscure, reginv_com, 
         "Invalidate gdb's internal register cache.");
-}
 
+  /* FIXME, there should be a way to make a CORE_ADDR variable settable. */
+  add_show_from_set
+    (add_set_cmd ("rstack_high_address", class_support, var_uinteger,
+                 (char *)&rstack_high_address,
+                 "Set top address in memory of the register stack.\n\
+Attempts to access registers saved above this address will be ignored\n\
+or will produce the value -1.", &setlist),
+     &showlist);
+}
index f437935d73f7c8ac8499f8a9678f7a87d2f2bc3f..add45a9bc924597efeb0be616a413b51da2f6147 100644 (file)
@@ -33,7 +33,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include "defs.h"
 #include <string.h>
-#include <strings.h>
 
 #if defined(USG) || defined(__CYGNUSCLIB__)
 #include <sys/types.h>
@@ -1473,10 +1472,7 @@ process_one_symbol (type, desc, valu, name, offset, objfile)
         and when using gcc on Solaris 2.0, these addresses are just
         absolute, or relative to the N_SO, depending on
         BLOCK_ADDRESS_ABSOLUTE.  */
-      if (processing_gcc_compilation)  /* FIXME, gcc should prob. conform */
-       function_start_offset = offset;
-      else
-        function_start_offset = valu;  
+      function_start_offset = valu;    
 #else
       function_start_offset = offset;  /* Default on ordinary systems */
 #endif
index c4ba5abb4345718686e694052b95efcd41b77374..9aa3f61fd3385cb71714bb185e81c221fc8c8f39 100644 (file)
@@ -178,6 +178,7 @@ evaluate_subexp (expect_type, exp, pos, noside)
       (*pos) += 3 + ((tem + sizeof (union exp_element))
                     / sizeof (union exp_element));
       arg1 = value_struct_elt_for_reference (exp->elts[pc + 1].type,
+                                            0,
                                             exp->elts[pc + 1].type,
                                             &exp->elts[pc + 2].string,
                                             expect_type);
@@ -552,7 +553,7 @@ evaluate_subexp (expect_type, exp, pos, noside)
        return value_x_binop (arg1, arg2, op, OP_NULL);
       else
        if (noside == EVAL_AVOID_SIDE_EFFECTS
-           && op == BINOP_DIV)
+           && (op == BINOP_DIV || op == BINOP_REM))
          return value_zero (VALUE_TYPE (arg1), not_lval);
       else
        return value_binop (arg1, arg2, op);
@@ -694,8 +695,8 @@ evaluate_subexp (expect_type, exp, pos, noside)
        }
       else
        {
-         tem = value_less (arg1, arg2);
-         return value_from_longest (builtin_type_int, (LONGEST) tem);
+         tem = value_less (arg2, arg1) || value_equal (arg1, arg2);
+         return value_from_longest (builtin_type_int, (LONGEST) tem);
        }
 
     case BINOP_LEQ:
@@ -709,8 +710,8 @@ evaluate_subexp (expect_type, exp, pos, noside)
        }
       else 
        {
-         tem = value_less (arg2, arg1);
-         return value_from_longest (builtin_type_int, (LONGEST) tem);
+         tem = value_less (arg1, arg2) || value_equal (arg1, arg2);
+         return value_from_longest (builtin_type_int, (LONGEST) tem);
        }
 
     case BINOP_REPEAT:
index 49cdcfec11c14680117eb14c58e9a9ebc7c19535..681a3145305c6bcbf7ff11ba917aa9c3cc7efc53 100644 (file)
@@ -63,6 +63,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
        The reply comes when the machine stops.
        It is           SAA             AA is the "signal number"
 
+       or...           TAAPPPPPPPPFFFFFFFF
+                                       where AA is the signal number,
+                                       PPPPPPPP is the PC (PC_REGNUM), and
+                                       FFFFFFFF is the frame ptr (FP_REGNUM).
+
        kill req        k
 */
 
@@ -74,7 +79,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "target.h"
 #include "wait.h"
 #include "terminal.h"
+#include "gdbcmd.h"
 
+#if !defined(DONT_USE_REMOTE)
 #ifdef USG
 #include <sys/types.h>
 #endif
@@ -140,7 +147,7 @@ remote_detach PARAMS ((char *, int));
 
 extern struct target_ops remote_ops;   /* Forward decl */
 
-static int kiodebug;
+static int kiodebug = 0;
 static int timeout = 5;
 
 #if 0
@@ -198,6 +205,8 @@ remote_close (quitting)
 #define B38400 EXTB
 #endif
 
+
+
 static struct {int rate, damn_b;} baudtab[] = {
        {0, B0},
        {50, B50},
@@ -238,7 +247,7 @@ remote_open (name, from_tty)
      int from_tty;
 {
   TERMINAL sg;
-  int a_rate, b_rate;
+  int a_rate, b_rate = 0;
   int baudrate_set = 0;
 
   if (name == 0)
@@ -304,7 +313,7 @@ device is attached to the remote system (e.g. /dev/ttya).");
 #endif
 
   /* Ack any packet which the remote side has already sent.  */
-  write (remote_desc, "+", 1);
+  write (remote_desc, "+\r", 2);
   putpkt ("?");                        /* initiate a query from remote machine */
 
   start_remote ();             /* Initialize gdb process mechanisms */
@@ -367,7 +376,8 @@ remote_resume (step, siggnal)
   char buf[PBUFSIZ];
 
   if (siggnal)
-    error ("Can't send signals to a remote system.");
+    error ("Can't send signals to a remote system.  Try `handle %d ignore'.",
+          siggnal);
 
 #if 0
   dcache_flush ();
@@ -383,6 +393,10 @@ remote_resume (step, siggnal)
 
 void remote_interrupt()
 {
+  
+  if (kiodebug)
+    printf ("remote_interrupt called\n");
+
   write (remote_desc, "\003", 1);      /* Send a ^C */
 }
 
@@ -398,7 +412,10 @@ remote_wait (status)
 {
   unsigned char buf[PBUFSIZ];
   void (*ofunc)();
-  
+  unsigned char *p;
+  int i;
+  char regs[REGISTER_RAW_SIZE (PC_REGNUM) + REGISTER_RAW_SIZE (FP_REGNUM)];
+
   WSETEXIT ((*status), 0);
 
   ofunc = signal (SIGINT, remote_interrupt);
@@ -407,14 +424,29 @@ remote_wait (status)
 
   if (buf[0] == 'E')
     error ("Remote failure reply: %s", buf);
-  if (buf[0] != 'S')
+  if (buf[0] == 'T')
+    {
+      /* Expedited reply, containing Signal, PC, and FP.  */
+      p = &buf[3];             /* after Txx */
+      for (i = 0; i < sizeof (regs); i++)
+       {
+         if (p[0] == 0 || p[1] == 0)
+           error ("Remote reply is too short: %s", buf);
+         regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
+         p += 2;
+       }
+      supply_register (PC_REGNUM, &regs[0]);
+      supply_register (FP_REGNUM, &regs[REGISTER_RAW_SIZE (PC_REGNUM)]);
+    }
+  else if (buf[0] != 'S')
     error ("Invalid remote reply: %s", buf);
+
   WSETSTOP ((*status), (((fromhex (buf[1])) << 4) + (fromhex (buf[2]))));
+
   return 0;
 }
 
 /* Read the remote registers into the block REGS.  */
-
 /* Currently we just read all the registers, so we don't use regno.  */
 /* ARGSUSED */
 static void
@@ -620,10 +652,10 @@ remote_xfer_memory(memaddr, myaddr, len, should_write, target)
 }
 
 static void
-remote_files_info (target)
-struct target_ops *target;
+remote_files_info (ignore)
+struct target_ops *ignore;
 {
-  printf ("remote files info missing here.  FIXME.\n");
+  printf ("Debugging a target over a serial line.\n");
 }
 \f
 /*
@@ -653,7 +685,6 @@ Receiver responds with:
 static int
 readchar ()
 {
-  char buf;
   static int inbuf_index, inbuf_count;
 #define        INBUFSIZE       PBUFSIZ
   static char inbuf[INBUFSIZE];
@@ -732,19 +763,25 @@ putpkt (buf)
     if (kiodebug)
       {
        *p = '\0';
-       printf ("Sending packet: %s (%s)\n", buf2, buf);
+       printf ("Sending packet: %s...", buf2);  fflush(stdout);
       }
     write (remote_desc, buf2, p - buf2);
 
     /* read until either a timeout occurs (\0) or '+' is read */
     do {
       ch = readchar ();
+      if (kiodebug) {
+       if (ch == '+')
+         printf("Ack\n");
+       else
+         printf ("%02X%c ", ch&0xFF, ch);
+      }
     } while ((ch != '+') && (ch != '\0'));
   } while (ch != '+');
 }
 
 /* Read a packet from the remote machine, with error checking,
-   and store it in BUF.  */
+   and store it in BUF.  BUF is expected to be of size PBUFSIZ.  */
 
 static void
 getpkt (buf)
@@ -783,6 +820,12 @@ getpkt (buf)
          c = readchar ();
          if (c == '#')
            break;
+         if (bp >= buf+PBUFSIZ-1)
+         {
+           *bp = '\0';
+           printf_filtered ("Remote packet too long: %s\n", buf);
+           goto whole;
+         }
          *bp++ = c;
          csum += c;
        }
@@ -792,8 +835,10 @@ getpkt (buf)
       c2 = fromhex (readchar ());
       if ((csum & 0xff) == (c1 << 4) + c2)
        break;
-      printf ("Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
+      printf_filtered ("Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
              (c1 << 4) + c2, csum & 0xff, buf);
+      /* Try the whole thing again.  */
+whole:
       write (remote_desc, "-", 1);
     }
 
@@ -804,7 +849,7 @@ getpkt (buf)
   write (remote_desc, "+", 1);
 
   if (kiodebug)
-    fprintf (stderr,"Packet received :%s\n", buf);
+    fprintf (stderr,"Packet received%s\n", buf);
 }
 \f
 /* The data cache leads to incorrect results because it doesn't know about
@@ -1008,4 +1053,13 @@ void
 _initialize_remote ()
 {
   add_target (&remote_ops);
+
+  add_show_from_set (
+    add_set_cmd ("remotedebug", no_class, var_boolean, (char *)&kiodebug,
+                  "Set debugging of remote serial I/O.\n\
+When enabled, each packet sent or received with the remote target\n\
+is displayed.", &setlist),
+       &showlist);
 }
+
+#endif
index 8e332fcc33d10f2445a5db4d16611f4320528586..eb25d4e26d65557c229a6c523ac487d458326d89 100644 (file)
@@ -21,11 +21,14 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "frame.h"
 #include "inferior.h"
 #include "obstack.h"
-#include "signame.h"
 #include "target.h"
 #include "ieee-float.h"
 
+#ifdef USE_PROC_FS
+#include <sys/procfs.h>
+#else
 #include <sys/ptrace.h>
+#endif
 
 #include "gdbcore.h"
 
@@ -63,8 +66,8 @@ int one_stepped;
    set up a simulated single-step, we undo our damage.  */
 
 void
-single_step (pid)
-     int pid; /* ignored */
+single_step (ignore)
+     int ignore; /* pid, but we don't need it */
 {
   branch_type br, isannulled();
   CORE_ADDR pc;
@@ -641,6 +644,161 @@ const struct ext_format ext_format_sparc = {
 /* tot sbyte smask expbyte manbyte */
    16, 0,    0x80, 0,1,           4,8,         /* sparc */
 };
+\f
+#ifdef USE_PROC_FS     /* Target dependent support for /proc */
+
+/*  The /proc interface divides the target machine's register set up into
+    two different sets, the general register set (gregset) and the floating
+    point register set (fpregset).  For each set, there is an ioctl to get
+    the current register set and another ioctl to set the current values.
+
+    The actual structure passed through the ioctl interface is, of course,
+    naturally machine dependent, and is different for each set of registers.
+    For the sparc for example, the general register set is typically defined
+    by:
+
+       typedef int gregset_t[38];
+
+       #define R_G0    0
+       ...
+       #define R_TBR   37
+
+    and the floating point set by:
+
+       typedef struct prfpregset {
+               union { 
+                       u_long  pr_regs[32]; 
+                       double  pr_dregs[16];
+               } pr_fr;
+               void *  pr_filler;
+               u_long  pr_fsr;
+               u_char  pr_qcnt;
+               u_char  pr_q_entrysize;
+               u_char  pr_en;
+               u_long  pr_q[64];
+       } prfpregset_t;
+
+    These routines provide the packing and unpacking of gregset_t and
+    fpregset_t formatted data.
+
+ */
+
+
+/*  Given a pointer to a general register set in /proc format (gregset_t *),
+    unpack the register contents and supply them as gdb's idea of the current
+    register values. */
+
+void
+supply_gregset (gregsetp)
+prgregset_t *gregsetp;
+{
+  register int regno;
+  register prgreg_t *regp = (prgreg_t *) gregsetp;
+
+  /* GDB register numbers for Gn, On, Ln, In all match /proc reg numbers.  */
+  for (regno = G0_REGNUM ; regno <= I7_REGNUM ; regno++)
+    {
+      supply_register (regno, (char *) (regp + regno));
+    }
+
+  /* These require a bit more care.  */
+  supply_register (PS_REGNUM, (char *) (regp + R_PS));
+  supply_register (PC_REGNUM, (char *) (regp + R_PC));
+  supply_register (NPC_REGNUM,(char *) (regp + R_nPC));
+  supply_register (Y_REGNUM,  (char *) (regp + R_Y));
+}
+
+void
+fill_gregset (gregsetp, regno)
+prgregset_t *gregsetp;
+int regno;
+{
+  int regi;
+  register prgreg_t *regp = (prgreg_t *) gregsetp;
+  extern char registers[];
+
+  for (regi = 0 ; regi <= R_I7 ; regi++)
+    {
+      if ((regno == -1) || (regno == regi))
+       {
+         *(regp + regno) = *(int *) &registers[REGISTER_BYTE (regi)];
+       }
+    }
+  if ((regno == -1) || (regno == PS_REGNUM))
+    {
+      *(regp + R_PS) = *(int *) &registers[REGISTER_BYTE (PS_REGNUM)];
+    }
+  if ((regno == -1) || (regno == PC_REGNUM))
+    {
+      *(regp + R_PC) = *(int *) &registers[REGISTER_BYTE (PC_REGNUM)];
+    }
+  if ((regno == -1) || (regno == NPC_REGNUM))
+    {
+      *(regp + R_nPC) = *(int *) &registers[REGISTER_BYTE (NPC_REGNUM)];
+    }
+  if ((regno == -1) || (regno == Y_REGNUM))
+    {
+      *(regp + R_Y) = *(int *) &registers[REGISTER_BYTE (Y_REGNUM)];
+    }
+}
+
+#if defined (FP0_REGNUM)
+
+/*  Given a pointer to a floating point register set in /proc format
+    (fpregset_t *), unpack the register contents and supply them as gdb's
+    idea of the current floating point register values. */
+
+void 
+supply_fpregset (fpregsetp)
+prfpregset_t *fpregsetp;
+{
+  register int regi;
+  char *from;
+  
+  for (regi = FP0_REGNUM ; regi < FP0_REGNUM+32 ; regi++)
+    {
+      from = (char *) &fpregsetp->pr_fr.pr_regs[regi-FP0_REGNUM];
+      supply_register (regi, from);
+    }
+  supply_register (FPS_REGNUM, (char *) &(fpregsetp->pr_fsr));
+}
+
+/*  Given a pointer to a floating point register set in /proc format
+    (fpregset_t *), update the register specified by REGNO from gdb's idea
+    of the current floating point register set.  If REGNO is -1, update
+    them all. */
+
+void
+fill_fpregset (fpregsetp, regno)
+prfpregset_t *fpregsetp;
+int regno;
+{
+  int regi;
+  char *to;
+  char *from;
+  extern char registers[];
+
+  for (regi = FP0_REGNUM ; regi < FP0_REGNUM+32 ; regi++)
+    {
+      if ((regno == -1) || (regno == regi))
+       {
+         from = (char *) &registers[REGISTER_BYTE (regi)];
+         to = (char *) &fpregsetp->pr_fr.pr_regs[regi-FP0_REGNUM];
+         bcopy (from, to, REGISTER_RAW_SIZE (regno));
+       }
+    }
+  if ((regno == -1) || (regno == FPS_REGNUM))
+    {
+      fpregsetp->pr_fsr = *(int *) &registers[REGISTER_BYTE (FPS_REGNUM)];
+    }
+}
+
+#endif /* defined (FP0_REGNUM) */
+
+#endif  /* USE_PROC_FS */
+
+
+#ifdef GET_LONGJMP_TARGET
 
 /* Figure out where the longjmp will land.  We expect that we have just entered
    longjmp and haven't yet setup the stack frame, so the args are still in the
@@ -664,3 +822,4 @@ get_longjmp_target(pc)
 
   return 1;
 }
+#endif /* GET_LONGJMP_TARGET */