brunner@bullhead.uucp (10/21/89)
Subject: Fix for dbx (part 4) Index: /usr/src/ucb/dbx IBM/4.3 Description: Several problems (too numerous to mention) exist with the December release of dbx. This is part 1 of a 5 part patch installation kit. The contents of the kit are: part 1 shar file containing help.c part 2 patchs to the following files: dbx/ibmrt/{coredump.c,decode.c,frame.c,procinfo.c} part 3 patchs to the following files: dbx/{object.c,eval.c,commands.y,c.c,tree.c} part 4 patchs to the following files: dbx/{runtime.c,symbols.c,execute.c,events.c,mappings.c} part 5 patches to the following files: dbx/{stabstring.c,printsym.c,operators.c,process.c, keywords.c,pascal.c,fortran.c,main.c,Makefile, examine.c,scanner.c,source.c,library.c} Fix: Change directories to /usr/src/ucb/dbx and apply this patch file, e.g., patch < this_file Proceede to the next part of the kit. Inconsistencies between the several compilers (hc, pp, f77) and the loader exist, stabs in particular. These will be corrected in a following patch to dbx, or in corrective releases of the compilers, or both. *** /usr/src/ucb/dbx/runtime.c Fri Dec 9 11:57:34 1988 --- runtime.c Thu Oct 12 14:37:24 1989 *************** *** 1,9 **** ! /* $Header:runtime.c 12.0$ */ ! /* $ACIS:runtime.c 12.0$ */ ! /* $Source: /ibm/acis/usr/src/ucb/dbx/RCS/runtime.c,v $ */ #ifndef lint ! static char *rcsid = "$Header:runtime.c 12.0$"; #endif --- 1,8 ---- ! /* $Header: runtime.c,v 12.1 89/10/12 17:37:23 brunner Locked $ */ ! /* $Source: /fish/dbx/RCS/runtime.c,v $ */ #ifndef lint ! static char *rcsid = "$Header: runtime.c,v 12.1 89/10/12 17:37:23 brunner Locked $"; #endif *************** *** 49,55 **** * associated function in the given value-result parameter. */ ! private getcurfunc (frp, fp) Frame frp; Symbol *fp; { --- 48,54 ---- * associated function in the given value-result parameter. */ ! getcurfunc (frp, fp) Frame frp; Symbol *fp; { *************** *** 94,101 **** * * Static allocation for the frame. */ ! ! public Frame findframe (f) Symbol f; { register Frame frp; --- 93,99 ---- * * Static allocation for the frame. */ ! public Frame findframe(f) Symbol f; { register Frame frp; *************** *** 102,130 **** static struct Frame frame; Symbol p; frp = &frame; ! getcurframe(frp); ! if (f != nil) { ! if (f == curfunc and curframe != nil) { ! *frp = *curframe; ! } else { ! p = whatblock(savepc(frp)); ! for (;;) { ! if (p == f) { ! break; ! } else if (p == program) { ! frp = nil; ! break; ! } else { ! frp = nextfunc(frp, &p); ! if (frp == nil) { ! break; ! } ! } ! } ! } } ! return frp; } /* --- 100,130 ---- static struct Frame frame; Symbol p; + if ( !f ) + return nil; + frp = &frame; ! if ( getcurfunc(frp,&p) < 0 ){ ! return nil; } ! if (f == curfunc && curframe ){ ! *frp = *curframe; ! return frp; ! } ! if ( p == f ) ! return frp; ! ! for (;;) { ! ! frp = nextfunc(frp, &p); ! ! if ( p == program ) ! frp = nil; ! ! if ( p == f || !frp ) ! return frp; ! } ! /*NOTREACHED*/ } /* *************** *** 137,142 **** --- 137,149 ---- Address addr; struct Frame frame; + /* + * curblock = whatblock(pc) -- get current block + * if in prologue, use reg 15, it contains the return address. + * else get the return address out of the current frame save area + * for reg 15. + */ + frp = &frame; getcurframe(frp); frp = nextframe(frp); *************** *** 478,492 **** { Boolean b; ! if (isfinished(process)) { b = false; ! } else { ! if (walkingstack or f == program or f == nil or ! (ismodule(f) and isactive(container(f)))) { b = true; ! } else { b = (Boolean) (findframe(f) != nil); - } } return b; } --- 485,499 ---- { Boolean b; ! if (isfinished(process) || notstarted(process) ) { b = false; ! } ! else { ! if (walkingstack || f == program || f == nil || ! ((isinline(f) || ismodule(f)) && isactive(container(f)))) b = true; ! else b = (Boolean) (findframe(f) != nil); } return b; } *************** *** 501,510 **** { Node procnode, arglist; Symbol proc; ! integer argc; procnode = exprnode->value.arg[0]; arglist = exprnode->value.arg[1]; if (procnode->op != O_SYM) { beginerrmsg(); fprintf(stderr, "can't call \""); --- 508,518 ---- { Node procnode, arglist; Symbol proc; ! Word call_pc, call_sp; procnode = exprnode->value.arg[0]; arglist = exprnode->value.arg[1]; + if (procnode->op != O_SYM) { beginerrmsg(); fprintf(stderr, "can't call \""); *************** *** 521,545 **** endproc.callnode = exprnode; endproc.cmdnode = topnode; pushenv(); pc = codeloc(proc); ! argc = pushargs(proc, arglist); ! beginproc(proc, argc); ! event_once( ! build(O_EQ, build(O_SYM, pcsym), build(O_SYM, retaddrsym)), ! buildcmdlist(build(O_PROCRTN, proc)) ); isstopped = false; if (not bpact()) { isstopped = true; cont(0); } - /* - * bpact() won't return true, it will call printstatus() and go back - * to command input if a breakpoint is found. - */ - /* NOTREACHED */ } /* * Check to see if an expression is correct for a given parameter. * If the given parameter is false, don't worry about type inconsistencies. --- 529,619 ---- endproc.callnode = exprnode; endproc.cmdnode = topnode; pushenv(); + + call_pc = reg(PROGCTR); pc = codeloc(proc); ! pushargs(proc, arglist); ! call_sp = reg(1); ! beginproc(proc); ! ! push(Word,call_pc); ! push(Word,call_sp); ! ! event_alloc(true, ! build(O_EQ, ! build(O_SYM, pcsym), ! build(O_LCON,call_pc) ! ), ! buildcmdlist(build(O_PROCRTN, proc)) ); + isstopped = false; if (not bpact()) { isstopped = true; cont(0); } } + public procreturn (f) + Symbol f; + { + int r; + Node tmp; + char *copy; + Word call_sp, call_pc; + + /* if SP < call_sp we are in a recursive call, continue */ + + call_sp = pop(Word); + call_pc = pop(Word); + + if ( reg(1) < call_sp ){ + push(Word,call_pc); + push(Word,call_sp); + event_alloc(true, + build(O_EQ, + build(O_SYM, pcsym), + build(O_LCON,call_pc) + ), + buildcmdlist(build(O_PROCRTN, f))); + return; + } + + /* grab the endproc struct early */ + + endproc = pop(CallEnv); + push(CallEnv,endproc); + flushoutput(); + + if ( endproc.isfunc ){ + + pushretval(f->type); + + r = size(f->type); + if ( r > sizeof(long) ){ + copy = newarr(char, r); + popn(r,copy); + tmp = build(O_SCON, copy); + } + else + tmp = build(O_LCON, (long) popsmall(f->type)); + + tmp->nodetype = f->type; + + /**** tfree(endproc.callnode); ***/ + + *(endproc.callnode) = *tmp; + dispose(tmp); + eval(endproc.cmdnode); + } + else { + printf("%s returns successfully\n", symname(f)); + } + popenv(); + getsrcpos(); + erecover(); /* blast out, kills pending events */ + } + /* * Check to see if an expression is correct for a given parameter. * If the given parameter is false, don't worry about type inconsistencies. *************** *** 653,692 **** return count; } - public procreturn (f) - Symbol f; - { - int r; - Node n; - char *data; - - popenv(); - if (endproc.isfunc) { - r = size(f->type); - if (r > sizeof(long)) { - pushretval(r, true); - data = newarr(char, r); - popn(r, data); - n = build(O_SCON, data); - } else { - pushretval(r, false); - n = build(O_LCON, (long) popsmall(f->type)); - } - flushoutput(); - n->nodetype = f->type; - tfree(endproc.callnode); - *endproc.callnode = *n; - dispose(n); - eval(endproc.cmdnode); - } else { - flushoutput(); - putchar('\n'); - printname(stdout, f); - printf(" returns successfully\n", symname(f)); - } - erecover(); - } - /* * Push the current environment. */ --- 727,732 ---- *************** *** 693,698 **** --- 733,769 ---- public pushenv () { + Word framebase[4]; + + push(Word,reg(0)); + push(Word,reg(1)); + push(Word,reg(2)); + push(Word,reg(3)); + push(Word,reg(4)); + push(Word,reg(5)); + push(Word,reg(6)); + push(Word,reg(7)); + push(Word,reg(8)); + push(Word,reg(9)); + push(Word,reg(10)); + push(Word,reg(11)); + push(Word,reg(12)); + push(Word,reg(13)); + push(Word,reg(14)); + push(Word,reg(15)); + + dread(framebase,reg(1),sizeof(framebase)); + push(Word,framebase[0]); + push(Word,framebase[1]); + push(Word,framebase[2]); + push(Word,framebase[3]); + + push(Word,reg(1)); + push(Word, reg(PROGCTR)); + push(int, (int) isstopped); + push(CallEnv, endproc); + + /***** push(Address, pc); push(Lineno, curline); push(String, cursource); *************** *** 704,709 **** --- 775,781 ---- push(Word, reg(PROGCTR)); push(Word, reg(STKP)); push(Word, reg(FRP)); + *****/ } /* *************** *** 712,717 **** --- 784,821 ---- public popenv () { + Word framebase[4]; + + endproc = pop(CallEnv); + isstopped = (Boolean) pop(int); + + setreg(PROGCTR, pop(Word)); + setreg(1,pop(Word)); + + framebase[3] = pop(Word); + framebase[2] = pop(Word); + framebase[1] = pop(Word); + framebase[0] = pop(Word); + dwrite(framebase,reg(1),sizeof(framebase)); + + setreg(15,pop(Word)); + setreg(14,pop(Word)); + setreg(13,pop(Word)); + setreg(12,pop(Word)); + setreg(11,pop(Word)); + setreg(10,pop(Word)); + setreg(9,pop(Word)); + setreg(8,pop(Word)); + setreg(7,pop(Word)); + setreg(6,pop(Word)); + setreg(5,pop(Word)); + setreg(4,pop(Word)); + setreg(3,pop(Word)); + setreg(2,pop(Word)); + setreg(1,pop(Word)); + setreg(0,pop(Word)); + + /**** String filename; setreg(FRP, pop(Word)); *************** *** 726,729 **** --- 830,868 ---- curline = pop(Lineno); pc = pop(Address); setsource(filename); + ****/ } + /* + * Flush the debuggee's standard output. + * + * This is VERY dependent on the use of stdio. + */ + + public flushoutput() + { + Address addr; + Symbol p, iob; + + p = lookup(identname("fflush", true)); + while (p != nil and not isblock(p)) { + p = p->next_sym; + } + if (p != nil) { + iob = lookup(identname("_iob", true)); + if (iob != nil) { + pushenv(); + pc = codeloc(p); + setreg(2, address(iob, nil) + sizeof(*stdout)); + beginproc(p); + stepto(reg(15)); + /* + addr = reg(15); + setbp(addr); + resume(-1, addr); + unsetbp(addr); + */ + popenv(); + } + } + } + *** /usr/src/ucb/dbx/symbols.c Fri Dec 9 11:57:47 1988 --- symbols.c Thu Oct 12 14:37:30 1989 *************** *** 1,9 **** ! /* $Header:symbols.c 12.0$ */ ! /* $ACIS:symbols.c 12.0$ */ ! /* $Source: /ibm/acis/usr/src/ucb/dbx/RCS/symbols.c,v $ */ #ifndef lint ! static char *rcsid = "$Header:symbols.c 12.0$"; #endif /* Copyright (c) 1982 Regents of the University of California */ --- 1,8 ---- ! /* $Header: symbols.c,v 12.1 89/10/12 17:37:28 brunner Locked $ */ ! /* $Source: /fish/dbx/RCS/symbols.c,v $ */ #ifndef lint ! static char *rcsid = "$Header: symbols.c,v 12.1 89/10/12 17:37:28 brunner Locked $"; #endif /* Copyright (c) 1982 Regents of the University of California */ *************** *** 35,40 **** --- 34,40 ---- #include "languages.h" #include "tree.h" + /* * Symbol classes */ *************** *** 90,95 **** --- 90,96 ---- Boolean intern : 1; /* internal calling sequence */ int unused : 13; Address beginaddr; /* address of function code */ + Address dataaddr; /* function data address */ } funcv; struct { /* variant record info */ int size; *************** *** 121,126 **** --- 122,128 ---- #define symname(s) ident(s->name) #define codeloc(f) ((f)->symvalue.funcv.beginaddr) + #define dataloc(f) ((f)->symvalue.funcv.dataaddr) #define isblock(s) (Boolean) ( \ s->class == FUNC || s->class == PROC || \ s->class == MODULE || s->class == PROG \ *************** *** 563,568 **** --- 565,571 ---- * locals - take offset from locals base * arguments - take offset from argument base * register - offset is register number + * functions/procedures - return the DATA address */ public Address address (s, frame) *************** *** 576,617 **** checkref(s); addr = s->symvalue.offset; ! if (!isactive(s->block)) { error("\"%s\" is not currently defined", symname(s)); ! } else if (s->storage != EXT) { ! frp = frame; ! if (frp == nil) { ! cur = s->block; ! while (cur != nil && cur->class == MODULE) { ! cur = cur->block; ! } ! if (cur == nil) { ! frp = nil; ! } else { ! frp = findframe(cur); ! if (frp == nil) { ! error("[internal error: unexpected nil frame for \"%s\"]", ! symname(s) ! ); ! } ! } ! } ! if (s->param) { ! r = preg(s, frp); ! if (r != -1) { ! addr = r; ! } else if (s->storage == STK) { ! addr += args_base(frp); ! if (multiword(s->block)) { ! addr += sizeof(Word); ! } ! } ! } else if (s->storage == STK) { ! addr += locals_base(frp); ! } else if (s->storage != INREG) { ! panic("address: bad symbol \"%s\"", symname(s)); ! } } return addr; } --- 579,625 ---- checkref(s); addr = s->symvalue.offset; ! ! if ( s->class == FUNC || s->class == PROC && !isinline(s) ) ! return dataloc(s); ! ! if ( s->storage == EXT ) ! return addr; ! ! if ( s->block == nil && s->storage == INREG ) ! return addr; ! ! if ( !isactive(s->block) ){ error("\"%s\" is not currently defined", symname(s)); ! } ! ! frp = frame; ! if ( !frp ){ ! for ( cur = s->block; ( cur && (ismodule(cur) || isinline(cur)) ); ! cur = cur->block ) ! ; ! frp = ( cur ) ? findframe(cur) : nil; } + if ( !frp ){ + error("[internal error: unexpected nil frame for \"%s\"]", + symname(s)); + } + + if ( isparam(s) ){ + r = preg(s, frp); + if ( r != NOADDR ) + addr = r; + else if ( s->storage == STK ) + addr += args_base(frp); + else { + panic("address: invalid symbol \"%s\"", symname(s)); + } + } + else if ( s->storage == STK ) + addr += locals_base(frp); + else if ( s->storage != INREG ) + panic("address: invalid symbol \"%s\"", symname(s)); + return addr; } *************** *** 649,660 **** s->language = t_addr->language; s->class = VAR; s->storage = INREG; ! s->level = 3; s->type = t_addr; s->symvalue.offset = r; } /* * Resolve an "abstract" type reference. * * It is possible in C to define a pointer to a type, but never define --- 657,693 ---- s->language = t_addr->language; s->class = VAR; s->storage = INREG; ! s->block = nil; ! s->level = 1; s->type = t_addr; s->symvalue.offset = r; } + /* + * Define a symbol used to access floating point register values. + */ + + public deffregname (n, regno, rsize) + Name n; + int regno, rsize; + { + Symbol s; + + s = insert(n); + s->language = t_real->language; + s->class = VAR; + s->storage = INREG; + s->level = 1; + s->block = nil; + if ( rsize == 4 ) + s->type = t_real; + else + s->type = t_real; + s->symvalue.offset = regno; + } + + /* * Resolve an "abstract" type reference. * * It is possible in C to define a pointer to a type, but never define *************** *** 759,764 **** --- 792,800 ---- if (t->class == TYPEREF) { resolveRef(t); } + + r = 0; + switch (t->class) { case RANGE: lower = t->symvalue.rangev.lower; *************** *** 826,832 **** findtype(t); } # endif ! r = size(t->type); break; case FIELD: --- 862,871 ---- findtype(t); } # endif ! if( t->type == t) ! r = 0; ! else ! r = size(t->type); break; case FIELD: *************** *** 1221,1227 **** p1 = p->value.arg[0]; p->nodetype = p1->nodetype; if (p1->op == O_SYM) { ! if (p1->nodetype->class == PROC || p->nodetype->class == FUNC) { p->op = p1->op; p->value.sym = p1->value.sym; p->nodetype = p1->nodetype; --- 1260,1268 ---- p1 = p->value.arg[0]; p->nodetype = p1->nodetype; if (p1->op == O_SYM) { ! if (p1->nodetype->class == PROC || ! p1->nodetype->class == FUNC || ! p1->nodetype->class == MODULE) { p->op = p1->op; p->value.sym = p1->value.sym; p->nodetype = p1->nodetype; *************** *** 1522,1527 **** --- 1563,1569 ---- dispose(s->chain); } + #ifdef 0 /* * Figure out the "current" variable or function being referred to * by the name n. *************** *** 1631,1637 **** } return b; } ! /* * Find the symbol that has the same name and scope as the * given symbol but is of the given field. Return nil if there is none. --- 1673,1679 ---- } return b; } ! #endif /* * Find the symbol that has the same name and scope as the * given symbol but is of the given field. Return nil if there is none. *************** *** 1683,1686 **** --- 1725,1902 ---- } dread(valp, addr, sizeof(long)); return true; + } + + + boolean Search_block(var_s,f) + Symbol *var_s, f; + { + Name n; + Symbol s; + + s = *var_s; + n = s->name; + + for ( ; s; s = s->next_sym ){ + if ( s->name == n ){ + if ( s->class == FIELD || s->class == TAG ) + continue; + if ( f == s->block || f == s ){ + *var_s = s; + return true; + } + } + } + return false; + } + + boolean Search_active_blocks(var_s) + Symbol *var_s; + { + Symbol f; /* iteration variable for active functions */ + Frame frp; /* frame associated with stack walk */ + struct Frame frame; + + frp = &frame; + if ( getcurfunc(frp,&f) < 0 ) + return false; + + for ( ; frp; frp = nextfunc(frp,&f) ){ + if ( f == program ) + break; + if ( Search_block(var_s,f) ) + return true; + } + return false; + } + + + boolean Search_globals(var_s) + Symbol *var_s; + { + Name n; + Symbol s; + boolean found; + + n = (*var_s)->name; + found = false; + + for ( s = *var_s; s; s = s->next_sym ){ + if ( s->name == n && + (s->block == nil || + (ismodule(s->block) || s->block->class == PROG)) ){ + if ( !found ){ + *var_s = s; + found = true; + } + else if ( priority(s) > priority(*var_s) ) + *var_s = s; + } + } + return found; + } + + /* + * Return the priority associated with a symbol class + */ + + priority(s) + Symbol s; + { + + switch (s->class) + { + case PROC: + case FUNC: + return(7); + + case VAR: + case ARRAY: + case OPENARRAY: + case DYNARRAY: + case SUBARRAY: + return(6); + + case COMMON: + return(5); + + case PROG: + case MODULE: + return(4); + + case CONST: + case PTRFILE: + case FILET: + case SET: + case LABEL: + case WITHPTR: + case SCAL: + case STR: + case EXTREF: + case TYPE: + case TYPEREF: + return(3); + + case RECORD: + case FIELD: + case FVAR: + case REF: + case PTR: + case RANGE: + case VARNT: + case FPROC: + case FFUNC: + case TAG: + return(2); + + case IMPROPER: + case BADUSE: + default: + return(1); + } + } + + /* + * Figure out the "current" variable or function being referred to + * by the name n. + */ + + public Symbol which (n) + Name n; + { + Symbol s; + + s = lookup(n); + if (s == nil) { + error("\"%s\" is not defined", ident(n)); + } + + if (!isactive(program) || !Search_block(&s,curfunc) ) { + if(isactive(program) && Search_active_blocks(&s) ) + { + if(isambiguous(s)) + { + printf("[using "); + printwhich(stdout, s); + printf("]\n"); + } + } + else if( Search_globals(&s) ) + { + if(isambiguous(s)) + { + printf("[using "); + printwhich(stdout, s); + printf("]\n"); + } + } + else + { + printf("[inactive "); + printwhich(stdout, s); + printf("]\n"); + } + } + + return s; } *** /usr/src/ucb/dbx/execute.c Fri Dec 9 11:56:54 1988 --- execute.c Thu Oct 12 14:37:02 1989 *************** *** 1,9 **** ! /* $Header:execute.c 12.0$ */ ! /* $ACIS:execute.c 12.0$ */ ! /* $Source: /ibm/acis/usr/src/ucb/dbx/RCS/execute.c,v $ */ #ifndef lint ! static char *rcsid = "$Header:execute.c 12.0$"; #endif /* Copyright (c) 1982 Regents of the University of California */ --- 1,8 ---- ! /* $Header: execute.c,v 12.1 89/10/12 17:37:01 brunner Locked $ */ ! /* $Source: /fish/dbx/RCS/execute.c,v $ */ #ifndef lint ! static char *rcsid = "$Header: execute.c,v 12.1 89/10/12 17:37:01 brunner Locked $"; #endif /* Copyright (c) 1982 Regents of the University of California */ *************** *** 26,31 **** --- 25,31 ---- #include "mappings.h" #include "coredump.h" #include "runtime.h" + #include "frame.h" #include <signal.h> #include <errno.h> #include <sys/types.h> *************** *** 32,40 **** #include <sys/stat.h> #ifndef public - #define DEFSIG -1 - #endif #define MAXNCMDARGS 1000 /* maximum number of arguments to RUN */ --- 32,38 ---- *************** *** 60,70 **** String pargv[4]; Node cond; ! if (coredump) { ! coredump = false; ! fclose(corefile); coredump_close(); ! } if (argv == nil) { argv = pargv; pargv[0] = objname; --- 58,66 ---- String pargv[4]; Node cond; ! if (coredump) coredump_close(); ! if (argv == nil) { argv = pargv; pargv[0] = objname; *************** *** 205,214 **** printnews(); } else { setallbps(); ! resume(s); unsetallbps(); s = DEFSIG; ! if (not isbperr() or not bpact()) { printstatus(); } } --- 201,210 ---- printnews(); } else { setallbps(); ! resume(s, 0); unsetallbps(); s = DEFSIG; ! if ( !isbperr() || !bpact()) { printstatus(); } } *************** *** 222,235 **** * but actually in the debugger. Could happen, for example, while * processing breakpoints. * ! * We basically just want to keep going; the assumption is ! * that when the process resumes it will get the interrupt, ! * which will then be handled. */ private intr () { ! signal(SIGINT, intr); } public fixintr () --- 218,229 ---- * but actually in the debugger. Could happen, for example, while * processing breakpoints. * ! * To avoid HANGING, just stop. */ private intr () { ! isstopped = true; } public fixintr () *************** *** 241,263 **** * Resume execution. */ ! public resume (signo) int signo; { register Process p; p = process; pcont(p, signo); pc = reg(PROGCTR); ! if (p->status != STOPPED) { ! if (p->signo != 0) { error("program terminated by signal %d", p->signo); ! } else if (not runfirst) { ! if (p->exitval == 0) { error("program exited"); ! } else { error("program exited with code %d", p->exitval); - } } } } --- 235,274 ---- * Resume execution. */ ! public resume (signo, last_bp) int signo; + Address last_bp; { register Process p; p = process; pcont(p, signo); + pc = reg(PROGCTR); ! ! if (p->status != STOPPED) ! { ! /* ! * Must unset all the breakpoints here since we won't be going ! * back to continue from here. First we set status to STOPPED ! * so that we can unset all the breakpoints, once we return we ! * set it back so that we represent our true condition. ! */ ! p->status = STOPPED; ! if (last_bp > 0) ! unsetbp(last_bp); ! else ! unsetallbps(); ! p->status = FINISHED; ! ! if (p->signo != 0) error("program terminated by signal %d", p->signo); ! else if ( !runfirst) ! { ! if (p->exitval == 0) error("program exited"); ! else error("program exited with code %d", p->exitval); } } } *************** *** 295,337 **** isstopped = true; } /* ! * Continue execution until the current function returns, or, ! * if the given argument is non-nil, until execution returns to ! * somewhere within the given function. ! */ ! ! public rtnfunc (f) ! Symbol f; { ! Address addr; ! Symbol t; ! if (not isstopped) { ! error("can't continue execution"); ! } else if (f != nil and not isactive(f)) { ! error("%s is not active", symname(f)); ! } else { ! addr = return_addr(); ! if (addr == nil) { ! error("no place to return to"); ! } else { ! isstopped = false; ! contto(addr); ! if (f != nil) { ! for (;;) { ! t = whatblock(pc); ! addr = return_addr(); ! if (t == f or addr == nil) break; ! contto(addr); ! } ! } ! if (not bpact()) { ! isstopped = true; ! printstatus(); ! } ! } ! } } /* --- 306,424 ---- isstopped = true; } + rtnfunc(f) /* ! This routine returns from the current function if f == NULL ! or to the function named by f, provided it is on the ! stack. If there is source info, it steps ahead to stop ! at the next source line in the same manner as dostep. ! Note: in routines with no source, this code will give ! incorrect results in the prolog and in the epilog because ! the current frame hasn't been set up or the registers have ! be changed, respectively. Fixup for entry point done though. ! */ ! Symbol f; { ! Address of, nf, addr; ! int line; ! Symbol s, g; ! struct Frame frame; ! Frame frp = &frame; ! if (!isstopped) error("can't continue execution"); ! ! isstopped = false; ! ! of = reg(1); ! nf = reg(1); ! ! if(!f) ! { ! /* if at entry point, do something special */ ! if(isprolog(reg(PROGCTR))) ! { ! of = reg(1); ! addr = reg(15); ! } ! else ! { ! getcurfunc(frp,&g); ! of = frp->reg[1]; ! addr = frp->reg[15]; ! ! /* find the function to return to, if there */ ! for(; g && g != program && isinline(g) ; ) ! { ! frp = nextfunc(frp,&g); ! of = frp->reg[1]; ! addr = frp->reg[15]; ! } ! } ! } ! else ! { ! /* if at entry point, do something special */ ! if(isprolog(reg(PROGCTR))) ! { ! addr = reg(15); ! of = reg(1); ! g = whatblock(addr); ! if(f == g) goto foundit; ! else getcurfunc(frp,&g); ! } ! else ! { ! /* get the current function info */ ! getcurfunc(frp,&g); ! addr = frp->reg[15]; ! of = frp->reg[1]; ! } ! ! /* find the function to return to, if there */ ! for(; g && g != program && g != f; ) ! { ! frp = nextfunc(frp,&g); ! of = frp->reg[1]; ! addr = frp->reg[15]; ! } ! } ! ! /* C doesn't have a break from an if so we need a goto to here */ ! foundit: ! ! if(f && f != g || !of) ! { ! error("can't return to function"); ! isstopped = true; ! return; ! } ! ! /* crank until we get to the right stack level */ ! do ! { ! /* continue to that address */ ! xto(addr,true); ! ! pc = reg(PROGCTR); ! nf = reg(1); ! } ! while ( nf < of && nf != 0 ); ! ! /* did we stop at a line with line info ? */ ! line = linelookup(addr); ! ! /* crank ahead until we find an addr with a line or no source info */ ! while (line == 0 && (s = whatblock(addr)) && (isinline(s) || !nosource(s))) ! { ! addr = nextaddr(addr, false); ! line = linelookup(addr); ! xto(addr,false); ! } ! ! isstopped = true; ! ! if(s = whatblock(addr)) useInstLoc = (Boolean) nosource(s); ! printnews(); } /* *************** *** 374,380 **** xto(addr, false); } ! private contto (addr) Address addr; { xto(addr, true); --- 461,467 ---- xto(addr, false); } ! public contto (addr) Address addr; { xto(addr, true); *************** *** 398,409 **** setallbps(); } setbp(addr); ! resume(DEFSIG); unsetbp(addr); if (catchbps) { unsetallbps(); } ! if (not isbperr()) { printstatus(); } } --- 485,496 ---- setallbps(); } setbp(addr); ! resume(DEFSIG, addr); unsetbp(addr); if (catchbps) { unsetallbps(); } ! if ( !isbperr() ) { printstatus(); } } *************** *** 565,571 **** if (coredump) { coredump_readtext(buff, addr, nbytes); } else { ! pio(process, PREAD, TEXTSEG, buff, addr, nbytes); } onsyserr(EIO, f); } --- 652,658 ---- if (coredump) { coredump_readtext(buff, addr, nbytes); } else { ! pio(process, PREAD, buff, addr, nbytes); } onsyserr(EIO, f); } *************** *** 587,593 **** } f = onsyserr(EIO, write_err); badaddr = addr; ! pio(process, PWRITE, TEXTSEG, buff, addr, nbytes); onsyserr(EIO, f); } --- 674,680 ---- } f = onsyserr(EIO, write_err); badaddr = addr; ! pio(process, PWRITE, buff, addr, nbytes); onsyserr(EIO, f); } *************** *** 609,615 **** onsyserr(EFAULT, f); } else { f = onsyserr(EIO, read_err); ! pio(process, PREAD, DATASEG, buff, addr, nbytes); onsyserr(EIO, f); } } --- 696,702 ---- onsyserr(EFAULT, f); } else { f = onsyserr(EIO, read_err); ! pio(process, PREAD, buff, addr, nbytes); onsyserr(EIO, f); } } *************** *** 630,636 **** } f = onsyserr(EIO, write_err); badaddr = addr; ! pio(process, PWRITE, DATASEG, buff, addr, nbytes); onsyserr(EIO, f); } --- 717,723 ---- } f = onsyserr(EIO, write_err); badaddr = addr; ! pio(process, PWRITE, buff, addr, nbytes); onsyserr(EIO, f); } *** /usr/src/ucb/dbx/events.c Fri Dec 9 11:56:50 1988 --- events.c Thu Oct 12 14:36:59 1989 *************** *** 1,9 **** ! /* $Header:events.c 12.0$ */ ! /* $ACIS:events.c 12.0$ */ ! /* $Source: /ibm/acis/usr/src/ucb/dbx/RCS/events.c,v $ */ #ifndef lint ! static char *rcsid = "$Header:events.c 12.0$"; #endif /* Copyright (c) 1982 Regents of the University of California */ --- 1,8 ---- ! /* $Header: events.c,v 12.1 89/10/12 17:36:58 brunner Locked $ */ ! /* $Source: /fish/dbx/RCS/events.c,v $ */ #ifndef lint ! static char *rcsid = "$Header: events.c,v 12.1 89/10/12 17:36:58 brunner Locked $"; #endif /* Copyright (c) 1982 Regents of the University of California */ *************** *** 48,53 **** --- 47,53 ---- public boolean inst_tracing; public boolean single_stepping; public boolean isstopped; + public boolean hexaddr = false; public Symbol linesym; public Symbol procsym; *************** *** 229,235 **** --- 229,263 ---- line = pop(long); addr = objaddr(line, cursource); } + + /* + * Scan ahead, see if there is a decent line + * around. + */ + + if ( addr == NOADDR ) + { + addr = nearobjaddr(line, cursource); + if ( addr != NOADDR ) + { + fprintf(stderr, "no executable code at line "); + prtree(stderr, place); + line = srcline(addr); + fprintf(stderr,"; using line %d instead.\n",line); + if ( place->op == O_QLINE ) + { + (place->value.arg[1])->value.lcon = line; + (place->value.arg[1])->op = O_LCON; + } + } + } + + /* + * Nope, delete the event + */ + if (addr == NOADDR) { + if (not delevent(e->id)) { printf("!! dbx.translate: can't undo event %d?\n", e->id); *************** *** 371,376 **** --- 399,464 ---- endfor } + /* + * Delete all of the breakpoints. + */ + + public deleteall() + { + Event e; + + foreach (Event, e, eventlist) + if (not e->temporary) { + delevent(e->id); + } + endfor + } + + + /* + * Delete all of the breakpoints at a given line. + */ + + public clearbps (place) + Node place; + { + Breakpoint bp; + Lineno line; + Address addr; + + line = place->value.arg[1]->value.lcon; + addr = objaddr(line, place->value.arg[0]->value.scon); + if ( addr == NOADDR ) + return; + + foreach (Breakpoint, bp, bplist) + if ( !bp->temporary ){ + if ( bp->bpaddr == addr ) + delevent(bp->event->id); + } + endfor + } + + /* + * Delete all of the breakpoints at a given address. + */ + + public clearbps_i (place) + Node place; + { + Breakpoint bp; + Address addr; + + eval(place->value.arg[0]); + addr = pop(long); + foreach (Breakpoint, bp, bplist) + if (not bp->temporary) { + if (bp->bpaddr == addr) + delevent(bp->event->id); + } + endfor + } + public printevent (e) Event e; { *************** *** 430,436 **** --- 518,526 ---- prtree(stdout, place); } else if (s == pcsym or s == retaddrsym) { printf("i at "); + hexaddr = true; prtree(stdout, place); + hexaddr = false; } else { printf(" when "); prtree(stdout, cond); *************** *** 645,651 **** --- 735,746 ---- public printnews () { register Trcmd t; + Symbol s; + /* skip over initialization and exit code */ + s = whatblock(reg(PROGCTR)); + if(!s || !strcmp(symname(s),"") || !strcmp(symname(s),"_exit")) return; + foreach (Trcmd, t, eachline) evalcmdlist(t->cmdlist); endfor *************** *** 749,756 **** * last time we checked. */ ! public printifchanged (p) Node p; { register Trinfo tp; register int n; --- 844,852 ---- * last time we checked. */ ! public printifchanged (p, trace) Node p; + Boolean trace; { register Trinfo tp; register int n; *************** *** 758,763 **** --- 854,860 ---- Filename curfile; static Lineno prevline; static Filename prevfile; + static Address prevaddr; tp = findtrinfo(p); n = size(p->nodetype); *************** *** 767,773 **** if (tp->trvalue == nil) { tp->trvalue = newarr(char, n); mov(v, tp->trvalue, n); ! printf("initially (at line %d in \"%s\"):\t", curline, curfile); prtree(stdout, p); printf(" = "); printval(p->nodetype); --- 864,872 ---- if (tp->trvalue == nil) { tp->trvalue = newarr(char, n); mov(v, tp->trvalue, n); ! if(!trace || nosource(whatblock(reg(PROGCTR)))) ! printf("initially (at address 0x%x in \"%s\"):\t", reg(PROGCTR), curfile); ! else printf("initially (at line %d in \"%s\"):\t", srcline(reg(PROGCTR)), curfile); prtree(stdout, p); printf(" = "); printval(p->nodetype); *************** *** 774,786 **** putchar('\n'); } else if (cmp(tp->trvalue, v, n) != 0) { mov(v, tp->trvalue, n); ! printf("after line %d in \"%s\":\t", prevline, prevfile); prtree(stdout, p); printf(" = "); printval(p->nodetype); putchar('\n'); } ! prevline = curline; prevfile = curfile; } --- 873,889 ---- putchar('\n'); } else if (cmp(tp->trvalue, v, n) != 0) { mov(v, tp->trvalue, n); ! if(!trace || !prevline) ! printf("after address 0x%x in \"%s\":\t", prevaddr, prevfile); ! else printf("after line %d in \"%s\":\t", prevline, prevfile); prtree(stdout, p); printf(" = "); printval(p->nodetype); putchar('\n'); } ! prevaddr = reg(PROGCTR); ! if(nosource(whatblock(reg(PROGCTR)))) prevline = 0; ! else prevline = srcline(reg(PROGCTR)); prevfile = curfile; } *************** *** 788,800 **** * Stop if the value of the given expression has changed. */ ! public stopifchanged (p) Node p; { register Trinfo tp; register int n; char *v; static Lineno prevline; tp = findtrinfo(p); n = size(p->nodetype); --- 891,905 ---- * Stop if the value of the given expression has changed. */ ! public stopifchanged (p, stop) Node p; + Boolean stop; { register Trinfo tp; register int n; char *v; static Lineno prevline; + static Address prevaddr; tp = findtrinfo(p); n = size(p->nodetype); *************** *** 803,819 **** if (tp->trvalue == nil) { tp->trvalue = newarr(char, n); mov(v, tp->trvalue, n); ! sp = v; } else if (cmp(tp->trvalue, v, n) != 0) { mov(v, tp->trvalue, n); ! printf("after line %d:\t", prevline); prtree(stdout, p); printf(" = "); printval(p->nodetype); putchar('\n'); isstopped = true; } ! prevline = curline; } /* --- 908,936 ---- if (tp->trvalue == nil) { tp->trvalue = newarr(char, n); mov(v, tp->trvalue, n); ! printf("initially:\t"); ! prtree(stdout, p); ! printf(" = "); ! printval(p->nodetype); ! putchar('\n'); ! if(!stop || nosource(whatblock(reg(PROGCTR)))) useInstLoc = true; ! else useInstLoc = false; ! isstopped = true; } else if (cmp(tp->trvalue, v, n) != 0) { mov(v, tp->trvalue, n); ! if(!stop || !prevline) printf("after address 0x%x:\t", prevaddr); ! else printf("after line %d:\t", prevline); prtree(stdout, p); printf(" = "); printval(p->nodetype); putchar('\n'); + if(!stop || nosource(whatblock(reg(PROGCTR)))) useInstLoc = true; + else useInstLoc = false; isstopped = true; } ! prevaddr = reg(PROGCTR); ! if(nosource(whatblock(reg(PROGCTR)))) prevline = 0; ! else prevline = srcline(reg(PROGCTR)); } /* *** /usr/src/ucb/dbx/mappings.c Fri Dec 9 11:57:11 1988 --- mappings.c Thu Oct 12 14:37:13 1989 *************** *** 1,9 **** ! /* $Header:mappings.c 12.0$ */ ! /* $ACIS:mappings.c 12.0$ */ ! /* $Source: /ibm/acis/usr/src/ucb/dbx/RCS/mappings.c,v $ */ #ifndef lint ! static char *rcsid = "$Header:mappings.c 12.0$"; #endif /* Copyright (c) 1982 Regents of the University of California */ --- 1,8 ---- ! /* $Header: mappings.c,v 12.1 89/10/12 17:37:12 brunner Locked $ */ ! /* $Source: /fish/dbx/RCS/mappings.c,v $ */ #ifndef lint ! static char *rcsid = "$Header: mappings.c,v 12.1 89/10/12 17:37:12 brunner Locked $"; #endif /* Copyright (c) 1982 Regents of the University of California */ *************** *** 38,47 **** --- 37,56 ---- Filetab *filetab; Linetab *linetab; + #define nearobjaddr(l,f) findobjaddr(l,f,false) + #define objaddr(l,f) findobjaddr(l,f,true) #define NOADDR ((Address) -1) /* no address for line or procedure */ + /* if <values.h> exists, then these are not needed */ + #ifndef _h_VALUES + #define BITSPERBYTE 8 + #define BITS(type) (BITSPERBYTE * (int)sizeof(type)) + #define HIBITI (1 << (BITS(int) - 1)) + #define MAXINT (~HIBITI) #endif + #endif + /* * Get the source file name associated with a given address. */ *************** *** 213,218 **** --- 222,305 ---- * more than once in the file table (caused by includes). */ + public Address findobjaddr(line, name, exact) + Lineno line; + String name; + boolean exact; + { + register Filetab *ftp; + register Lineno i, j; + Boolean foundfile; + int current, prev, follow, follow_i, prev_i; + + + if ( nlhdr.nlines == 0 || line <= 0 ) + return NOADDR; + + if ( !name ) + name = cursource; + + foundfile = false; + prev = 0; + follow = MAXINT; + + /* + * try for an exact match first, but remember closest prev and + * closest follow in case exact fails. + */ + + for ( ftp = filetab; ftp <= &filetab[nlhdr.nfiles]; ftp++ ){ + if ( !streq(ftp->filename, name) ) + continue; + + foundfile = true; + i = ftp->lineindex; + j = ( ftp == &filetab[nlhdr.nfiles-1] ) + ? nlhdr.nlines + : (ftp + 1)->lineindex; + + for ( ; i < j; i++ ){ + + if ( linetab[i].line == line ) + return linetab[i].addr; + + if ( !exact ){ + current = linetab[i].line; + + if ( current < line && current > 0 && prev < current ){ + prev = current; + prev_i = i; + } + + if ( current > line && current > 0 && current < follow ){ + follow = current; + follow_i = i; + } + } + } + } + + if ( !foundfile ){ + error("source file \"%s\" not compiled with -g", name); + return NOADDR; + } + + /* + * Check for nearest line, if non-exact search requested. + */ + + if ( !exact ){ + if ( follow != MAXINT ){ + return linetab[follow_i].addr; + } + else if ( prev ){ + return linetab[prev_i].addr; + } + } + return NOADDR; + } + + #ifdef TEST public Address objaddr(line, name) Lineno line; String name; *************** *** 250,256 **** } return NOADDR; } ! /* * Table for going from object addresses to the functions in which they belong. */ --- 337,343 ---- } return NOADDR; } ! #endif /* * Table for going from object addresses to the functions in which they belong. */ *************** *** 277,282 **** --- 364,370 ---- register AddrOfFunc *af; AddrOfFunc *newfunctab; + if (nfuncs >= functablesize) { if (functablesize == 0) { functab = newarr(AddrOfFunc, NFUNCS); *************** *** 296,305 **** } /* ! * Return the function that begins at the given address. */ ! public Symbol whatblock(addr) Address addr; { register int i, j, k; --- 384,393 ---- } /* ! * func_index: return the index of a function in the function table. */ ! private int func_index(addr) Address addr; { register int i, j, k; *************** *** 307,324 **** i = 0; j = nfuncs - 1; ! if (addr < functab[i].addr) { ! return program; ! } else if (addr == functab[i].addr) { ! return functab[i].func; } else if (addr >= functab[j].addr) { ! return functab[j].func; } while (i <= j) { k = (i + j) / 2; a = functab[k].addr; if (a == addr) { ! return functab[k].func; } else if (addr > a) { i = k+1; } else { --- 395,410 ---- i = 0; j = nfuncs - 1; ! if (addr <= functab[i].addr) { ! return i; } else if (addr >= functab[j].addr) { ! return j; } while (i <= j) { k = (i + j) / 2; a = functab[k].addr; if (a == addr) { ! return k; } else if (addr > a) { i = k+1; } else { *************** *** 325,336 **** j = k-1; } } ! if (addr > functab[i].addr) { ! return functab[i].func; ! } else { ! return functab[i-1].func; ! } ! /* NOTREACHED */ } /* --- 411,465 ---- j = k-1; } } ! if (addr > functab[i].addr) ! return i; ! else ! return i-1; ! } ! ! /* ! * Return the function that begins at the given address. ! */ ! ! public Symbol whatblock(addr) ! Address addr; ! { ! int i, j; ! ! j = nfuncs - 1; ! if (addr < functab[0].addr) ! return program; ! else if (addr == functab[0].addr) ! return functab[0].func; ! else if (addr >= functab[j].addr) ! return functab[j].func; ! ! i = func_index(addr); ! return functab[i].func; ! } ! ! /* ! * tracetable_addr: ! * Return the start of the trace table for some function. ! * The trace table immediately follows the code in the function, ! * so for all functions but the last we can get the start address ! * of the next function in the table and back off by 10 bytes or so. ! * --This would have worked except the raving morons also allow random ! * data to be inserted anywhere in text, so we have to forget the whole idea. ! */ ! ! public Address tracetable_addr(addr) ! Address addr; ! { ! register int i, j, k; ! Address a; ! ! i = func_index(addr); ! return functab[i].addr; ! #ifdef LOSE ! a = ( i >= nfuncs - 1 ) ? functab[i].addr : functab[i+1].addr - 16; ! return a; ! #endif } /* Eric Brunner, IBM AWD Palo Alto inet: brunner@monet.berkeley.edu or brunner%ibmsupt@uunet.uu.net uucp: uunet!ibmsupt!brunner (415) 855-4486