(_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.
+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
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.
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.
/*#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
{
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. */
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;
{
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;
{
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);
+}
#include "defs.h"
#include <string.h>
-#include <strings.h>
#if defined(USG) || defined(__CYGNUSCLIB__)
#include <sys/types.h>
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
(*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);
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);
}
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:
}
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:
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
*/
#include "target.h"
#include "wait.h"
#include "terminal.h"
+#include "gdbcmd.h"
+#if !defined(DONT_USE_REMOTE)
#ifdef USG
#include <sys/types.h>
#endif
extern struct target_ops remote_ops; /* Forward decl */
-static int kiodebug;
+static int kiodebug = 0;
static int timeout = 5;
#if 0
#define B38400 EXTB
#endif
+
+
static struct {int rate, damn_b;} baudtab[] = {
{0, B0},
{50, B50},
int from_tty;
{
TERMINAL sg;
- int a_rate, b_rate;
+ int a_rate, b_rate = 0;
int baudrate_set = 0;
if (name == 0)
#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 */
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 ();
void remote_interrupt()
{
+
+ if (kiodebug)
+ printf ("remote_interrupt called\n");
+
write (remote_desc, "\003", 1); /* Send a ^C */
}
{
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);
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, ®s[0]);
+ supply_register (FP_REGNUM, ®s[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
}
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
/*
static int
readchar ()
{
- char buf;
static int inbuf_index, inbuf_count;
#define INBUFSIZE PBUFSIZ
static char inbuf[INBUFSIZE];
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)
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;
}
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);
}
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
_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
#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"
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;
/* 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 *) ®isters[REGISTER_BYTE (regi)];
+ }
+ }
+ if ((regno == -1) || (regno == PS_REGNUM))
+ {
+ *(regp + R_PS) = *(int *) ®isters[REGISTER_BYTE (PS_REGNUM)];
+ }
+ if ((regno == -1) || (regno == PC_REGNUM))
+ {
+ *(regp + R_PC) = *(int *) ®isters[REGISTER_BYTE (PC_REGNUM)];
+ }
+ if ((regno == -1) || (regno == NPC_REGNUM))
+ {
+ *(regp + R_nPC) = *(int *) ®isters[REGISTER_BYTE (NPC_REGNUM)];
+ }
+ if ((regno == -1) || (regno == Y_REGNUM))
+ {
+ *(regp + R_Y) = *(int *) ®isters[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 *) ®isters[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 *) ®isters[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
return 1;
}
+#endif /* GET_LONGJMP_TARGET */