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