From 8f86a4e465a079a54776a83bef69bfcfa0f6014c Mon Sep 17 00:00:00 2001 From: John Gilmore Date: Fri, 19 Jun 1992 21:09:54 +0000 Subject: [PATCH] * 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. --- gdb/ChangeLog | 20 ++++++ gdb/am29k-tdep.c | 31 +++++---- gdb/dbxread.c | 6 +- gdb/eval.c | 11 ++-- gdb/remote.c | 84 +++++++++++++++++++----- gdb/sparc-tdep.c | 165 ++++++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 278 insertions(+), 39 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index a2ea8340b97..4bee5943c60 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 f76d02e88cf..03c07c504a5 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 */ #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 f437935d73f..add45a9bc92 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 -#include #if defined(USG) || defined(__CYGNUSCLIB__) #include @@ -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 c4ba5abb434..9aa3f61fd33 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 49cdcfec11c..681a3145305 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 #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, ®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 @@ -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 8e332fcc33d..eb25d4e26d6 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 +#else #include +#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 *) ®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 @@ -664,3 +822,4 @@ get_longjmp_target(pc) return 1; } +#endif /* GET_LONGJMP_TARGET */ -- 2.30.2