aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Gilmore <gnu@cygnus>1992-06-19 21:09:54 +0000
committerJohn Gilmore <gnu@cygnus>1992-06-19 21:09:54 +0000
commit8f86a4e465a079a54776a83bef69bfcfa0f6014c (patch)
treebf0fa5e50a470bece6366430275fea81fdb7c857
parent0b909fe129911866c5db3484f1b1131872ae7df4 (diff)
downloadfsf-binutils-gdb-8f86a4e465a079a54776a83bef69bfcfa0f6014c.zip
fsf-binutils-gdb-8f86a4e465a079a54776a83bef69bfcfa0f6014c.tar.gz
fsf-binutils-gdb-8f86a4e465a079a54776a83bef69bfcfa0f6014c.tar.bz2
* 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. * 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.
-rw-r--r--gdb/ChangeLog20
-rw-r--r--gdb/am29k-tdep.c31
-rw-r--r--gdb/dbxread.c6
-rw-r--r--gdb/eval.c11
-rw-r--r--gdb/remote.c84
-rw-r--r--gdb/sparc-tdep.c165
6 files changed, 278 insertions, 39 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index a2ea834..4bee594 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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.
diff --git a/gdb/am29k-tdep.c b/gdb/am29k-tdep.c
index f76d02e..03c07c5 100644
--- a/gdb/am29k-tdep.c
+++ b/gdb/am29k-tdep.c
@@ -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);
+}
diff --git a/gdb/dbxread.c b/gdb/dbxread.c
index f437935..add45a9 100644
--- a/gdb/dbxread.c
+++ b/gdb/dbxread.c
@@ -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
diff --git a/gdb/eval.c b/gdb/eval.c
index c4ba5ab..9aa3f61 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -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:
diff --git a/gdb/remote.c b/gdb/remote.c
index 49cdcfe..681a314 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -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");
}
/*
@@ -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);
}
/* 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
diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
index 8e332fc..eb25d4e 100644
--- a/gdb/sparc-tdep.c
+++ b/gdb/sparc-tdep.c
@@ -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 */
};
+
+#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 */