"0x%lX",
"%lu",
"0x%lX",
- "%g",
+ "%.14g",
"{",
"}",
| %default ';' { give_prompt = 0; }
]
{ if (com) {
- if (errorgiven) {
- freenode(com);
- com = 0;
- }
if (lastcom) {
freenode(lastcom);
lastcom = 0;
}
-
- if (com) {
+ if (errorgiven) {
+ freenode(com);
+ com = 0;
+ }
+ else {
eval(com);
if (repeatable(com)) {
lastcom = com;
com != run_command &&
com != print_command) {
freenode(com);
+ com = 0;
}
}
} else if (lastcom && ! errorgiven) {
| where_command(p)
| STATUS { *p = mknode(OP_STATUS); }
| DUMP { *p = mknode(OP_DUMP); }
-| RESTORE INTEGER { *p = mknode(OP_RESTORE, tok.ival); }
+| RESTORE count(p)? { *p = mknode(OP_RESTORE, *p); }
| delete_command(p)
| print_command(p)
| display_command(p)
]
;
+
where_command(p_tree *p;)
- { long l; }
:
- WHERE
- [ INTEGER { l = tok.ival; }
- | '-' INTEGER { l = - tok.ival; }
- | { l = 0x7fffffff; }
- ] { *p = mknode(OP_WHERE, l); }
+ WHERE { *p = mknode(OP_WHERE, (p_tree) 0); }
+ [ count(&(*p)->t_args[0])?
+ | '-' count(&(*p)->t_args[0])
+ { (*p)->t_args[0]->t_ival = - (*p)->t_args[0]->t_ival; }
+ ]
;
list_command(p_tree *p;)
help_command(p_tree *p;)
:
[ HELP | '?' ]
- [ { *p = mknode(OP_HELP, (struct idf *) 0, (char *) 0); }
- | name(p) { (*p)->t_oper = OP_HELP; }
- | '?' { *p = mknode(OP_HELP, str2idf("help",0), (char *) 0); }
+ { *p = mknode(OP_HELP, (p_tree) 0); }
+ [ name(&(*p)->t_args[0])?
+ | '?' { (*p)->t_args[0] = mknode(OP_NAME, str2idf("help",0), (char *) 0); }
]
;
:
WHEN
where(&whr)?
- condition(&cond)?
+ condition(&cond)? { *p = mknode(OP_WHEN, whr, cond, (p_tree) 0);
+ p = &(*p)->t_args[2];
+ }
'{'
command_line(p)
[ ';' { if (*p) {
'}'
{ if (! whr && ! cond) {
error("no position or condition");
- freenode(*p);
- *p = 0;
}
else if (! *p) {
error("no commands given");
}
- else *p = mknode(OP_WHEN, whr, cond, *p);
}
;
step_command(p_tree *p;)
- { long l; }
:
- STEP
- [ INTEGER { l = tok.ival; }
- | { l = 1; }
- ] { *p = mknode(OP_STEP, l); }
+ STEP { *p = mknode(OP_STEP, (p_tree) 0); }
+ count(&(*p)->t_args[0])?
;
next_command(p_tree *p;)
- { long l; }
:
- NEXT
- [ INTEGER { l = tok.ival; }
- | { l = 1; }
- ] { *p = mknode(OP_NEXT, l); }
+ NEXT { *p = mknode(OP_NEXT, (p_tree) 0); }
+ count(&(*p)->t_args[0])?
;
regs_command(p_tree *p;)
- { long l; }
:
- REGS
- [ INTEGER { l = tok.ival; }
- | { l = 0; }
- ] { *p = mknode(OP_REGS, l); }
+ REGS { *p = mknode(OP_REGS, (p_tree) 0); }
+ count(&(*p)->t_args[0])?
;
delete_command(p_tree *p;)
:
- DELETE count_list(p) { *p = mknode(OP_DELETE, *p); }
+ DELETE count_list(p)? { *p = mknode(OP_DELETE, *p); }
;
print_command(p_tree *p;)
[ ENABLE { *p = mknode(OP_ENABLE, (p_tree) 0); }
| DISABLE { *p = mknode(OP_DISABLE, (p_tree) 0); }
]
- count_list(&(*p)->t_args[0])
+ count_list(&(*p)->t_args[0])?
;
count_list(p_tree *p;)
:
count(p)
- [ ',' { *p = mknode(OP_LIST, *p, (p_tree) 0); }
+ [ ',' { *p = mknode(OP_LINK, *p, (p_tree) 0); }
count(&(*p)->t_args[1])
]*
;
where(p_tree *p;)
:
- IN qualified_name(p) { *p = mknode(OP_IN, *p); }
+ IN qualified_name(p) { *p = mknode(OP_IN, *p, (p_tree) 0); }
+ position(&((*p)->t_args[1]))?
|
position(p)
;
}
| /* tag name (only C?) */
{ s = NewSymbol(str, CurrentScope, TAG, currnam); }
- 'T' tag_name(s)
-
+ 'T' type_name(&(s->sy_type), s)
+ { if (! s->sy_type->ty_sym) s->sy_type->ty_sym = s;
+ if (s->sy_type->ty_class != T_CROSS) {
+ resolve_cross(s->sy_type);
+ }
+ }
| /* end scope */
'E' INTEGER
{ close_scope(); }
{ s = Lookup(findidf(str), FileScope, VAR);
if (s) {
tmp = s->sy_type;
+ s->sy_type = 0;
} else s = NewSymbol(str, FileScope, VAR, currnam);
}
'G' type(&(s->sy_type), (int *) 0, s)
type_name(p_type *t; p_symbol sy;)
{ int type_index[2]; p_type *p; }
:
- type_index(type_index)
+ type_index(type_index) { p = tp_lookup(type_index); }
[
- '='
- type(t, type_index, sy)
- { p = tp_lookup(type_index);
- if (*p && *p != incomplete_type) {
- if ((*p)->ty_class != T_CROSS)
- error("Redefining (%d,%d) %d",
- type_index[0],
- type_index[1],
- (*p)->ty_class);
- if (*t && *p != *t) free_type(*p);
+ { if (*p && (*p)->ty_class != 0 &&
+ (*p)->ty_class != T_CROSS) {
+ error("Redefining (%d,%d) %d",
+ type_index[0],
+ type_index[1],
+ (*p)->ty_class);
}
- if (*t) *p = *t;
}
+ '='
+ type(p, type_index, sy)
|
- { p = tp_lookup(type_index); }
]
- { if (*p == 0) *p = incomplete_type;
+ { if (*p == 0) *p = new_type();
*t = *p;
}
;
}
;
-tag_name(p_symbol t;)
- { int type_index[2]; p_type *p; }
-:
- type_index(type_index)
- '='
- type(&(t->sy_type), type_index, t)
- { p = tp_lookup(type_index);
- if (*p && *p != incomplete_type) {
- if ((*p)->ty_class != T_CROSS)
- error("Redefining (%d,%d) %d",
- type_index[0],
- type_index[1],
- (*p)->ty_class);
- if (t->sy_type && *p != t->sy_type) {
- free_type(*p);
- }
- }
- if (t->sy_type) *p = t->sy_type;
- if (*p == 0) *p = incomplete_type;
- if (t->sy_type &&
- t->sy_type->ty_class == T_ENUM &&
- currnam->on_desc != 0) {
- t->sy_type->ty_size = currnam->on_desc;
- }
- }
-;
-
function(p_symbol p;)
:
{ p->sy_type = new_type();
;
type(p_type *ptp; int *type_index; p_symbol sy;)
- { register p_type tp = 0;
- p_type t1, t2;
+ { register p_type tp = *ptp ? *ptp : new_type();
+ p_type t1 = 0, t2 = 0;
long ic1, ic2;
int A_used = 0;
int tclass;
char *str;
}
-: { *ptp = 0; }
+:
[
/* type cross reference */
/* these are used in C for references to a struct, union or
if (sy &&
(sy->sy_type->ty_class == tclass ||
sy->sy_type->ty_class == T_CROSS)) {
+ if (tp != *ptp) free_type(tp);
tp = sy->sy_type;
}
else {
- tp = new_type();
tp->ty_class = T_CROSS;
- tp->ty_tag = str;
+ tp->ty_size = tclass;
sy = NewSymbol(str, CurrentScope, TAG, (struct outname *) 0);
+ sy->sy_type = tp;
}
}
|
[ 'A' integer_const(&ic2) { A_used |= 2; }
| integer_const(&ic2)
]
- { *ptp = subrange_type(A_used,
+ { if (tp != *ptp) free_type(tp);
+ tp = subrange_type(A_used,
last_index,
ic1,
ic2,
* is element type
*/
'a' type(&t1, (int *) 0, (p_symbol) 0) ';' type(&t2, (int *) 0, (p_symbol) 0)
- { *ptp = array_type(t1, t2); }
+ { if (tp != *ptp) free_type(tp);
+ tp = array_type(t1, t2);
+ }
|
/* structure type */
- 's' { tp = new_type(); tp->ty_class = T_STRUCT; }
+ 's' { tp->ty_class = T_STRUCT; }
structure_type(tp, sy)
|
/* union type */
- 'u' { tp = new_type(); tp->ty_class = T_UNION; }
+ 'u' { tp->ty_class = T_UNION; }
structure_type(tp, sy)
|
/* enumeration type */
- 'e' { tp = new_type(); tp->ty_class = T_ENUM; }
+ 'e' { tp->ty_class = T_ENUM; }
enum_type(tp)
|
/* pointer type */
- '*' { tp = new_type(); tp->ty_class =T_POINTER;
+ '*' { tp->ty_class = T_POINTER;
tp->ty_size = pointer_size;
}
type(&(tp->ty_ptrto), (int *) 0, (p_symbol) 0)
|
/* function type */
- 'f' { tp = new_type(); tp->ty_class = T_PROCEDURE;
+ 'f' { tp->ty_class = T_PROCEDURE;
tp->ty_size = pointer_size;
}
type(&(tp->ty_retval), (int *) 0, (p_symbol) 0)
*/
|
/* procedure type */
- 'Q' { tp = new_type(); tp->ty_class = T_PROCEDURE;
+ 'Q' { tp->ty_class = T_PROCEDURE;
tp->ty_size = pointer_size;
}
type(&(tp->ty_retval), (int *) 0, (p_symbol) 0)
',' param_list(tp)
|
/* another procedure type */
- 'p' { tp = new_type(); tp->ty_class = T_PROCEDURE;
+ 'p' { tp->ty_class = T_PROCEDURE;
tp->ty_size = pointer_size;
tp->ty_retval = void_type;
}
/* the first integer_const represents the size in bytes,
* the second one represents the low bound
*/
- 'S' { tp = new_type(); tp->ty_class = T_SET; }
+ 'S' { tp->ty_class = T_SET; }
type(&(tp->ty_setbase), (int *) 0, (p_symbol) 0) ';'
[
integer_const(&(tp->ty_size)) ';'
]
|
/* file type of Pascal */
- 'L' { tp = new_type(); tp->ty_class = T_FILE; }
+ 'L' { tp->ty_class = T_FILE; }
type(&(tp->ty_fileof), (int *) 0, (p_symbol) 0)
|
type_name(ptp, (p_symbol) 0)
{ if (type_index &&
- *ptp == incomplete_type &&
+ (*ptp)->ty_class == 0 &&
type_index[0] == last_index[0] &&
type_index[1] == last_index[1]) {
- *ptp = void_type;
+ **ptp = *void_type;
+ if (*ptp != tp) free_type(tp);
}
+ tp = *ptp;
}
]
- { if (! *ptp) *ptp = tp; }
+ { if (*ptp && *ptp != tp) **ptp = *tp;
+ else *ptp = tp;
+ }
;
structure_type(register p_type tp; p_symbol sy;)
}
p = &tp->ty_fields[tp->ty_nfields++];
p->fld_name = s;
+ p->fld_type = 0;
sy = NewSymbol(s, CurrentScope, FIELD, currnam);
sy->sy_field = p;
return p;
}
close_scope();
add_position_addr((char *) 0, (struct outname *) 0);
+ clean_tp_tab();
rd_close();
return (h.oh_magic == O_CONVERTED);
}
struct dump {
char *globals, *stack;
struct message_hdr mglobal, mstack;
+ struct dump *next;
};
+static struct dump *last_dump;
+
/* dumping and restoring of child process.
*/
do_dump(p)
p->t_args[0] = (struct tree *) d;
p->t_address = (t_addr) get_int(d->mglobal.m_buf+PC_OFF*pointer_size, pointer_size, T_UNSIGNED);
add_to_item_list(p);
+ d->next = last_dump;
+ last_dump = d;
}
/* dumping and restoring of child process.
{
struct dump *d;
- p = get_from_item_list((int) p->t_ival);
- if (!p || p->t_oper != OP_DUMP) {
- error("no such dump");
- return;
+ if (p->t_args[0]) {
+ p = get_from_item_list((int) p->t_args[0]->t_ival);
+ if (!p || p->t_oper != OP_DUMP) {
+ error("no such dump");
+ return;
+ }
+ d = (struct dump *) p->t_args[0];
}
+ else d = last_dump;
- d = (struct dump *) p->t_args[0];
+ if (! d) {
+ error("no dumps");
+ return;
+ }
if (! put_dump(&d->mglobal, d->globals, &d->mstack, d->stack)) {
- error("no debuggee");
}
do_items();
}
free(d->globals);
free(d->stack);
+ if (d == last_dump) last_dump = d->next;
+ else {
+ register struct dump *d1 = last_dump;
+
+ while (d1->next != d) d1 = d1->next;
+ d1->next = d->next;
+ }
free((char *) d);
}
get_int(buf, size, class)
char *buf;
long size;
+ int class;
{
- long l;
+ register long l;
switch((int)size) {
case sizeof(char):
convert(pbuf, psize, ptp, tp, size)
char **pbuf;
long *psize;
- p_type *ptp;
- p_type tp;
+ register p_type *ptp;
+ register p_type tp;
long size;
{
/* Convert the value in pbuf, of size psize and type ptp, to type
*pbuf = malloc((unsigned) *psize);
malloc_succeeded(*pbuf);
if (! get_bytes(*psize, addr, *pbuf)) {
- error("could not get value");
free(*pbuf);
*pbuf = 0;
return 0;
}
if ((*ptp)->ty_class == T_POINTER) {
if (! get_bytes(pointer_size, *paddr, (char *) paddr)) {
- error("could not get value");
free(buf);
return 0;
}
*pbuf = malloc((unsigned int) *psize);
malloc_succeeded(*pbuf);
if (! get_bytes(*psize, a, *pbuf)) {
- error("could not get value");
free(*pbuf);
*pbuf = 0;
return 0;
sym = identify(p, VAR|REGVAR|LOCVAR|VARPAR|CONST);
if (! sym) return 0;
if (! get_value(sym, pbuf, psize)) {
- print_node(p, 0);
- fputs(" currently not available\n", db_out);
break;
}
*ptp = sym->sy_type;
sym = identify(p, VAR|REGVAR|LOCVAR|VARPAR);
if (! sym) return 0;
if (! (a = get_addr(sym, psize))) {
- print_node(p, 0);
- fputs(" currently not available\n", db_out);
break;
}
*paddr = a;
extern FILE *db_out;
extern int db_ss;
+int stop_reason;
typedef struct item {
struct item *i_next;
}
int
-item_addr_actions(a, mess_type)
+item_addr_actions(a, mess_type, may_stop)
t_addr a;
+ int mess_type;
+ int may_stop;
{
/* Perform actions associated with position 'a', and return 1 if we must stop
there, and 0 if not.
register p_item i = item_list.il_first;
int stopping = 0;
- while (i) {
+ stop_reason = 0;
+ for (i = item_list.il_first; i != 0; i = i->i_next) {
register p_tree p = i->i_node;
- if (! i->i_disabled && (p->t_address == a || p->t_address == NO_ADDR)) {
+ if (! i->i_disabled
+ && (p->t_address == a || p->t_address == NO_ADDR)) {
switch(p->t_oper) {
+ case OP_STOP:
+ if (mess_type != DB_SS && mess_type != OK) break;
+ if (! p->t_args[1] || eval_cond(p->t_args[1])) {
+ if (! stop_reason) stop_reason = i->i_itemno;
+ stopping = 1;
+ }
+ break;
case OP_TRACE:
+ case OP_WHEN:
+ case OP_DUMP:
+ case OP_DISPLAY:
+ break;
+ default:
+ assert(0);
+ }
+ }
+ }
+ for (i = item_list.il_first; i != 0; i = i->i_next) {
+ register p_tree p = i->i_node;
+
+ if (! i->i_disabled
+ && (p->t_address == a || p->t_address == NO_ADDR)) {
+ switch(p->t_oper) {
+ case OP_TRACE:
+ if ((! stopping && mess_type != END_SS)
+ || p->t_args[2] || ! may_stop) {
+ perform(p, a);
+ }
+ break;
case OP_WHEN:
perform(p, a);
break;
case OP_STOP:
- if (mess_type != DB_SS && mess_type != OK) break;
- if (! p->t_args[1] ||
- eval_cond(p->t_args[1])) stopping = 1;
- break;
case OP_DUMP:
case OP_DISPLAY:
break;
assert(0);
}
}
- i = i->i_next;
}
return stopping;
}
i = new_item();
i->i_node = p;
- if (p->t_address == NO_ADDR &&
- (p->t_oper != OP_TRACE || ! p->t_args[0])) db_ss++;
+ if (p->t_address == NO_ADDR
+ && (p->t_oper != OP_TRACE || ! p->t_args[0])) db_ss++;
if (item_list.il_first == 0) {
item_list.il_first = i;
}
else item_list.il_first = i->i_next;
if (i == item_list.il_last) item_list.il_last = prev;
p = i->i_node;
- if (p->t_address == NO_ADDR &&
- (p->t_oper != OP_TRACE || ! p->t_args[0])) db_ss--;
+ if (p->t_address == NO_ADDR
+ && (p->t_oper != OP_TRACE || ! p->t_args[0])) db_ss--;
free_item(i);
}
return p;
warning("item %d already %sabled", n, kind ? "dis" : "en");
return;
}
- if (p->t_address == NO_ADDR &&
- (p->t_oper != OP_TRACE || ! p->t_args[0])) {
+ if (p->t_address == NO_ADDR
+ && (p->t_oper != OP_TRACE || ! p->t_args[0])) {
db_ss += kind == 1 ? (-1) : 1;
}
i->i_disabled = kind;
extern struct tokenname tkidf[];
extern char *strindex();
extern int eof_seen;
+extern int interrupted;
static struct tokenname shorts[] = {
{LIST, "l"},
va_list ap;
char *fmt;
- va_start(ap);
- {
- fmt = va_arg(ap, char *);
- fprintf(db_out, "%s: ", progname);
- vfprintf(db_out, fmt, ap);
- fprintf(db_out, "\n");
+ if (! interrupted) {
+ va_start(ap);
+ {
+ fmt = va_arg(ap, char *);
+ fprintf(db_out, "%s: ", progname);
+ vfprintf(db_out, fmt, ap);
+ fprintf(db_out, "\n");
+ }
+ va_end(ap);
}
- va_end(ap);
errorgiven = 1;
}
"%lXH",
"%lu",
"%lXH",
- "%G",
+ "%.14G",
"[",
"]",
OP_STRING 0 0
OP_NAME 0 0
OP_AT 0 0
-OP_IN 1 0
-OP_HELP 0 do_help
+OP_IN 2 0
+OP_HELP 1 do_help
OP_STOP 2 do_stop
OP_WHEN 3 do_stop
OP_CONT 2 do_continue
-OP_STEP 0 do_step
-OP_NEXT 0 do_next
-OP_REGS 0 do_regs
-OP_WHERE 0 do_where
+OP_STEP 1 do_step
+OP_NEXT 1 do_next
+OP_REGS 1 do_regs
+OP_WHERE 1 do_where
OP_STATUS 0 print_items
OP_DELETE 1 do_delete
OP_SELECT 2 0
OP_SET 2 do_set
OP_PRINT 1 do_print
OP_DUMP 0 do_dump
-OP_RESTORE 0 do_restore
+OP_RESTORE 1 do_restore
OP_TRACE 3 do_trace
OP_FIND 1 do_find
OP_DISPLAY 1 add_to_item_list
if (indent == 0) indent = 4;
switch(tp->ty_class) {
+ case T_CROSS:
+ if (! tp->ty_cross) {
+ error("unknown type");
+ break;
+ }
+ print_val(tp->ty_cross, tp_sz, addr, compressed, indent, format);
+ break;
case T_SUBRANGE:
print_val(tp->ty_base, tp_sz, addr, compressed, indent, format);
break;
extern char *progname;
extern int child_interrupted;
extern int interrupted;
+extern int stop_reason;
+extern t_lineno currline;
static int child_pid; /* process id of child */
static int to_child, from_child; /* file descriptors for communication */
int disable_intr = 1;
int db_ss;
-t_lineno currline;
static int catch_sigpipe();
static int stopped();
from_child = fild2[0];
child_pid = 0;
if (currfile) CurrentScope = currfile->sy_file->f_scope;
+ currline = 0;
return 1;
}
CurrentScope = get_scope_from_addr(curr_stop);
}
do_items();
- if (! restoring && ! item_addr_actions(curr_stop, OK)) {
+ if (! restoring && ! item_addr_actions(curr_stop, OK, 1)) {
send_cont(1);
}
else if (! restoring) {
int i;
char buf[0x1000];
- if (! child_pid) return 0;
+ if (! child_pid) {
+ error("no process");
+ return 0;
+ }
if (! p) p = buf;
while (c >= 0x1000) {
i = read(from_child, p, 0x1000);
if (i <= 0) {
- if (i == 0) child_pid = 0;
+ if (i == 0) {
+ child_pid = 0;
+ }
+ else error("read failed");
return 0;
}
if (p != buf) p += i;
while (c > 0) {
i = read(from_child, p, (int)c);
if (i <= 0) {
- if (i == 0) child_pid = 0;
+ if (i == 0) {
+ child_pid = 0;
+ }
+ else error("read failed");
return 0;
}
p += i;
c -= i;
}
- return c == 0;
+ return 1;
}
static int
{
int i;
- if (! child_pid) return 0;
+ if (! child_pid) {
+ error("no process");
+ return 0;
+ }
while (c >= 0x1000) {
i = write(to_child, p, 0x1000);
- if (i < 0) return 0;
+ if (i < 0) {
+ if (child_pid) error("write failed");
+ return 0;
+ }
p += i;
c -= i;
}
while (c > 0) {
i = write(to_child, p, (int)c);
- if (i < 0) return 0;
+ if (i < 0) {
+ if (child_pid) error("write failed");
+ return 0;
+ }
p += i;
c -= i;
}
if (s && a) {
fprintf(db_out, "%s ", s);
pos = print_position(a, 1);
+ if (stop_reason) {
+ fprintf(db_out, " (status entry %d)", stop_reason);
+ }
fputs("\n", db_out);
list_position(pos);
handle_displays();
}
curr_stop = a;
+ CurrentScope = get_scope_from_addr(a);
return 1;
}
int type;
t_addr a;
static int level = 0;
+ int child_dead = 0;
level++;
for (;;) {
- if (child_pid) {
- int child_dead = 0;
- if (m->m_type & DB_RUN) disable_intr = 0;
- if (!child_interrupted && (! uputm(m) || ! ugetm(&answer))) {
- child_dead = 1;
- }
- disable_intr = 1;
- if ((interrupted || child_interrupted) && ! child_dead) {
- while (child_interrupted && answer.m_type != INTR) {
- if (! ugetm(&answer)) {
- child_dead = 1;
- break;
- }
- }
- if (interrupted && ! child_dead) {
- level--;
- if (! level) {
- child_interrupted = 0;
- CurrentScope = get_scope_from_addr((t_addr) answer.m_size);
- interrupted = 0;
- stopped("interrupted", (t_addr) answer.m_size);
- }
- return 1;
+ if (! child_pid) {
+ error("no process");
+ return 0;
+ }
+ if (m->m_type & DB_RUN) {
+ disable_intr = 0;
+ stop_reason = 0;
+ }
+ if (!child_interrupted && (! uputm(m) || ! ugetm(&answer))) {
+ child_dead = 1;
+ }
+ disable_intr = 1;
+ if ((interrupted || child_interrupted) && ! child_dead) {
+ while (child_interrupted && answer.m_type != INTR) {
+ if (! ugetm(&answer)) {
+ child_dead = 1;
+ break;
}
}
- if (child_dead) {
- wait(&child_status);
- if (child_status & 0177) {
- fprintf(db_out,
- "child died with signal %d\n",
- child_status & 0177);
- }
- else {
- fprintf(db_out,
- "child terminated, exit status %d\n",
- child_status >> 8);
- }
- init_run();
+ if (interrupted && ! child_dead) {
level--;
+ if (! level) {
+ child_interrupted = 0;
+ interrupted = 0;
+ stopped("interrupted", (t_addr) answer.m_size);
+ }
return 1;
}
- a = answer.m_size;
- type = answer.m_type;
- if (m->m_type & DB_RUN) {
- /* run command */
- CurrentScope = get_scope_from_addr((t_addr) a);
- if (! item_addr_actions(a, type) &&
- ( type == DB_SS || type == OK)) {
- /* no explicit breakpoints at this position.
- Also, child did not stop because of
- SETSS or SETSSF, otherwise we would
- have gotten END_SS.
- So, continue.
- */
- if ((m->m_type & ~ DB_SS) != CONT) {
- m->m_type = CONT | (m->m_type & DB_SS);
- }
- continue;
- }
- if (type != END_SS && single_stepping) {
- m->m_type = CLRSS;
- uputm(m) && ugetm(&answer);
- }
- single_stepping = 0;
+ }
+ if (child_dead) {
+ wait(&child_status);
+ if (child_status & 0177) {
+ fprintf(db_out,
+ "child died with signal %d\n",
+ child_status & 0177);
}
- if (stop_message) {
- stopped("stopped", a);
+ else {
+ fprintf(db_out,
+ "child terminated, exit status %d\n",
+ child_status >> 8);
}
+ init_run();
level--;
- return type;
+ return 1;
+ }
+ a = answer.m_size;
+ type = answer.m_type;
+ if (m->m_type & DB_RUN) {
+ /* run command */
+ CurrentScope = get_scope_from_addr((t_addr) a);
+ if (! item_addr_actions(a, type, stop_message) &&
+ ( type == DB_SS || type == OK)) {
+ /* no explicit breakpoints at this position.
+ Also, child did not stop because of
+ SETSS or SETSSF, otherwise we would
+ have gotten END_SS.
+ So, continue.
+ */
+ if ((m->m_type & ~ DB_SS) != CONT) {
+ m->m_type = CONT | (m->m_type & DB_SS);
+ }
+ continue;
+ }
+ if (type != END_SS && single_stepping) {
+ m->m_type = CLRSS;
+ if (! uputm(m) || ! ugetm(&answer)) return 0;
+ }
+ single_stepping = 0;
+ }
+ if (stop_message) {
+ stopped("stopped", a);
}
level--;
- return 0;
+ return 1;
}
/*NOTREACHED*/
}
put_int(m.m_buf, pointer_size, (long)from);
if (! could_send(&m, 0)) {
- error("no process");
return 0;
}
- if (answer.m_type == FAIL || answer.m_type == INTR) {
+ switch(answer.m_type) {
+ case FAIL:
+ error("could not get value");
return 0;
+ case INTR:
+ error("interrupted");
+ return 0;
+ case DATA:
+ return ureceive(to, answer.m_size);
+ default:
+ assert(0);
}
-
- assert(answer.m_type == DATA);
-
- return ureceive(to, answer.m_size);
+ /*NOTREACHED*/
}
int
return retval;
}
-int
set_bytes(size, from, to)
long size;
char *from;
m.m_size = size;
put_int(m.m_buf, pointer_size, (long) to);
- return uputm(&m) && usend(from, size)
- && ugetm(&m)
- && m.m_type != FAIL;
+ if (! uputm(&m) || ! usend(from, size) || ! ugetm(&m)) {
+ return;
+ }
+ switch(answer.m_type) {
+ case FAIL:
+ error("could not handle this SET request");
+ break;
+ case INTR:
+ error("interrupted");
+ break;
+ case OK:
+ break;
+ default:
+ assert(0);
+ }
}
int
m.m_type = DUMP;
if (! could_send(&m, 0)) {
- error("no process");
return 0;
}
- if (answer.m_type == FAIL || answer.m_type == INTR) return 0;
- assert(answer.m_type == DGLOB);
+ switch(answer.m_type) {
+ case FAIL:
+ error("request for DUMP failed");
+ return 0;
+ case INTR:
+ error("interrupted");
+ return 0;
+ case DGLOB:
+ break;
+ default:
+ assert(0);
+ }
+
*globmessage = answer;
*globbuf = malloc((unsigned) answer.m_size);
if (! ureceive(*globbuf, answer.m_size) || ! ugetm(stackmessage)) {
if (*globbuf) free(*globbuf);
- error("no process");
return 0;
}
assert(stackmessage->m_type == DSTACK);
if (! ureceive(*stackbuf, stackmessage->m_size)) {
if (*globbuf) free(*globbuf);
if (*stackbuf) free(*stackbuf);
- error("no process");
return 0;
}
put_int(globmessage->m_buf+SP_OFF*pointer_size, pointer_size,
m.m_size = level;
if (! could_send(&m, 0)) {
- error("no process");
return 0;
}
- if (answer.m_type == FAIL || answer.m_type == INTR) return 0;
+ switch(answer.m_type) {
+ case FAIL:
+ error("request for registers failed");
+ return 0;
+ case INTR:
+ error("interrupted");
+ return 0;
+ case GETEMREGS:
+ break;
+ default:
+ assert(0);
+ }
*to++ = (t_addr) get_int(answer.m_buf, pointer_size, T_UNSIGNED);
*to++ = (t_addr) get_int(answer.m_buf+pointer_size, pointer_size, T_UNSIGNED);
*to++ = (t_addr) get_int(answer.m_buf+2*pointer_size, pointer_size, T_UNSIGNED);
m.m_type = SETEMREGS;
m.m_size = 0;
put_int(m.m_buf+PC_OFF*pointer_size, pointer_size, (long)PC);
- return could_send(&m, 0) && answer.m_type != FAIL && answer.m_type != INTR;
+ if (! could_send(&m, 0)) return 0;
+ switch(answer.m_type) {
+ case FAIL:
+ error("could not set PC to %lx", (long) PC);
+ return 0;
+ case INTR:
+ error("interrupted");
+ return 0;
+ case OK:
+ return 1;
+ default:
+ assert(0);
+ }
+ /*NOTREACHED*/
}
int
m.m_type = (CONT | (db_ss ? DB_SS : 0));
m.m_size = 0;
- return could_send(&m, stop_message) && answer.m_type != FAIL;
+ return could_send(&m, stop_message) && child_pid;
}
int
m.m_type = type | (db_ss ? DB_SS : 0);
m.m_size = count;
single_stepping = 1;
- if (could_send(&m, 1) && answer.m_type != FAIL && answer.m_type != INTR) {
- return 1;
- }
+ if (could_send(&m, 1) && child_pid) return 1;
single_stepping = 0;
return 0;
}
{
struct message_hdr m;
- if (a == ILL_ADDR || a == NO_ADDR) return 0;
-
m.m_type = type;
m.m_size = a;
if (debug) printf("%s breakpoint at 0x%lx\n", type == SETBP ? "setting" : "clearing", (long) a);
- if (! could_send(&m, 0)) {
+ if (child_pid && ! could_send(&m, 0)) {
}
return 1;
put_int(m.m_buf, pointer_size, (long)start);
put_int(m.m_buf+pointer_size, pointer_size, (long)end);
if (debug) printf("%s trace at [0x%lx,0x%lx]\n", type == SETTRACE ? "setting" : "clearing", (long) start, (long) end);
- if (! could_send(&m, 0)) {
+ if (child_pid && ! could_send(&m, 0)) {
+ return 0;
}
return 1;
}
return sc;
}
+
+/* extern int scope_encloses(p_scope scope, from_scope);
+ Returns 1 if scope encloses from from_scope, 0 otherwise.
+*/
+int
+scope_encloses(scope, from_scope)
+ p_scope scope, from_scope;
+{
+ register p_scope sc = from_scope;
+
+ while (sc) {
+ if (sc == scope) return 1;
+ sc = sc->sc_static_encl;
+ }
+ return 0;
+}
Returns the closest enclosing scope of 'sc' that has an activation record.
*/
extern p_scope base_scope();
+
+/* extern int scope_encloses(p_scope scope, from_scope);
+ Returns 1 if scope encloses from from_scope, 0 otherwise.
+*/
+extern int scope_encloses();
switch(p->t_oper) {
case OP_NAME:
- if (! p->t_sc) p->t_sc = CurrentScope;
- sym = Lookfromscope(p->t_idf, class_set, p->t_sc);
+ sym = Lookfromscope(p->t_idf, class_set, CurrentScope);
if (sym) {
/* Found it. */
break;
}
- /* We could not find it using scope p->t_sc; now we try to identify
+ /* We could not find it using the current scope; now we try to identify
it using class_set. If this results in only one definition, we
take this one.
*/
if ( sym) pr_sym(sym);
}
+
+resolve_cross(tp)
+ p_type tp;
+{
+ register p_symbol sym = tp->ty_sym->sy_idf->id_def;
+
+ while (sym) {
+ if (sym->sy_class == TAG &&
+ sym->sy_type->ty_class == T_CROSS &&
+ sym->sy_type->ty_cross == (p_type) 0 &&
+ sym->sy_type->ty_size == tp->ty_class &&
+ scope_encloses(tp->ty_sym->sy_scope, sym->sy_scope)) {
+ sym->sy_type->ty_cross = tp;
+ }
+ sym = sym->sy_next;
+ }
+}
#include "expr.h"
extern FILE *db_out;
-extern t_lineno currline;
+t_lineno currline;
static t_lineno listline;
extern long pointer_size;
extern char *strrindex();
extern int interrupted;
+extern int stop_reason;
p_tree print_command;
p->t_filename = va_arg(ap, char *);
break;
case OP_INTEGER:
- case OP_NEXT:
- case OP_STEP:
- case OP_REGS:
- case OP_RESTORE:
- case OP_WHERE:
p->t_ival = va_arg(ap, long);
break;
default:
case OP_IN:
a = get_addr_from_node(p->t_args[0]);
+
+ if (p->t_args[1]) {
+ p_scope sc;
+
+ a = get_addr_from_node(p->t_args[1]);
+ sc = base_scope(get_scope_from_addr(a));
+ sym = identify(p->t_args[0], FUNCTION|PROC|MODULE);
+ if (! sym->sy_name.nm_scope ||
+ ! sym->sy_name.nm_scope->sc_bp_opp) {
+ error("could not determine address of \"%s\"", p->t_str);
+ a = ILL_ADDR;
+ break;
+ }
+ if (sc->sc_definedby != sym) {
+ error("inconsistent address");
+ a = ILL_ADDR;
+ break;
+ }
+ }
p->t_address = a;
break;
print_node(p->t_args[0], 0);
break;
case OP_REGS:
- fprintf(db_out, "regs %ld", p->t_ival);
+ fputs("regs ", db_out);
+ print_node(p->t_args[0], 0);
break;
case OP_NEXT:
- fprintf(db_out, "next %ld", p->t_ival);
+ fputs("next ", db_out);
+ print_node(p->t_args[0], 0);
break;
case OP_STEP:
- fprintf(db_out, "step %ld", p->t_ival);
+ fputs("step ", db_out);
+ print_node(p->t_args[0], 0);
break;
case OP_STATUS:
fputs("status", db_out);
print_position(p->t_address, 1);
break;
case OP_RESTORE:
- fprintf(db_out, "restore %ld", p->t_ival);
+ fputs("restore ", db_out);
+ print_node(p->t_args[0], 0);
break;
case OP_WHERE:
- fputs("where", db_out);
- if (p->t_ival != 0x7fffffff) fprintf(db_out, " %ld", p->t_ival);
+ fputs("where ", db_out);
+ print_node(p->t_args[0], 0);
break;
case OP_HELP:
- fputs("help", db_out);
- if (p->t_str != 0) fprintf(db_out, " %s", p->t_str);
+ fputs("help ", db_out);
+ print_node(p->t_args[0], 0);
break;
case OP_CONT:
fputs("cont", db_out);
}
p = p->t_args[2];
fputs(" { ", db_out);
- while (p->t_oper == OP_LINK) {
+ while (p && p->t_oper == OP_LINK) {
print_node(p->t_args[0], 0);
fputs("; ", db_out);
p = p->t_args[1];
case OP_IN:
fputs("in ", db_out);
print_node(p->t_args[0], 0);
+ fputs(" ", db_out);
+ print_node(p->t_args[1], 0);
break;
case OP_SELECT:
print_node(p->t_args[0], 0);
case OP_BINOP:
(*currlang->printop)(p);
break;
+ default:
+ assert(0);
}
if (top_level) fputs("\n", db_out);
}
return 1;
case OP_NEXT:
case OP_STEP:
- com->t_ival = 1;
+ freenode(com->t_args[0]);
+ com->t_args[0] = 0;
return 1;
case OP_LIST:
freenode(com->t_args[0]);
do_file(p)
p_tree p;
{
+ FILE *f;
+
if (p->t_args[0]) {
+ if ((f = fopen(p->t_args[0]->t_str, "r")) == NULL) {
+ error("could not open %s", p->t_args[0]->t_str);
+ return;
+ }
+ fclose(f);
newfile(p->t_args[0]->t_idf);
}
else if (listfile) fprintf(db_out, "%s\n", listfile->sy_idf->id_text);
p->t_address = a;
if (a != NO_ADDR) {
if (! set_or_clear_breakpoint(a, kind)) {
- error("could not %s breakpoint", kind == SETBP ? "set" : "clear");
return 0;
}
}
if (sc) e = sc->sc_start - 1;
else e = 0xffffffff;
}
- if (! set_or_clear_trace(a, e, kind)) {
- error("could not %s trace", kind == SETTRACE ? "set" : "clear");
- return 0;
- }
- return 1;
+ return set_or_clear_trace(a, e, kind);
}
do_trace(p)
p_tree p;
int kind;
{
+ if (!p) {
+ if (stop_reason) {
+ able_item(stop_reason, kind);
+ }
+ else {
+ error("no current stopping point");
+ }
+ return;
+ }
switch(p->t_oper) {
case OP_LINK:
able(p->t_args[0], kind);
case OP_INTEGER:
able_item((int)p->t_ival, kind);
break;
+ default:
+ assert(0);
}
}
p_tree p;
{
int count;
- int first_time = 1;
if (p) {
count = p->t_args[0]->t_ival;
t_addr a = get_addr_from_position(&(p->t_args[1]->t_pos));
p_scope sc = get_scope_from_addr(a);
- if (a == ILL_ADDR || base_scope(sc) != base_scope(CurrentScope) ||
- ! set_pc(a)) {
+ if (a == ILL_ADDR || base_scope(sc) != base_scope(CurrentScope)) {
error("cannot continue at line %d",
p->t_args[1]->t_lino);
return;
}
+ if (! set_pc(a)) {
+ return;
+ }
}
}
else count = 1;
while (count--) {
if (! send_cont(count==0)) {
- if (first_time) error("no process");
break;
}
- first_time = 0;
+ }
+ if (count > 0) {
+ fprintf(db_out, "Only %d breakpoints skipped\n",
+ p->t_args[0]->t_ival - count);
}
}
do_step(p)
p_tree p;
{
- if (! do_single_step(SETSS, p->t_ival)) {
- if (! interrupted) error("no process");
+ p = p->t_args[0];
+ if (! do_single_step(SETSS, p ? p->t_ival : 1L)) {
}
}
do_next(p)
p_tree p;
{
-
- if (! do_single_step(SETSSF, p->t_ival)) {
- if (! interrupted) error("no process");
+ p = p->t_args[0];
+ if (! do_single_step(SETSSF, p? p->t_ival : 1L)) {
}
}
p_tree p;
{
t_addr *buf;
- int n = p->t_ival;
+ int n = 0;
+ p = p->t_args[0];
+ if (p) n = p->t_ival;
if (! (buf = get_EM_regs(n))) {
- if (! interrupted) error("no process");
return;
}
fprintf(db_out, "EM registers %d levels back:\n", n);
{
int i = 0;
unsigned int cnt;
- unsigned int maxcnt = p->t_ival;
+ unsigned int maxcnt = 0xffff;
p_scope sc;
t_addr *buf;
t_addr PC;
- if (p->t_ival < 0) {
+ p = p->t_args[0];
+ if (p && p->t_ival < 0) {
for (;;) {
buf = get_EM_regs(i++);
if (! buf || ! buf[AB_OFF]) break;
i -= maxcnt;
if (i < 0) i = 0;
}
+ else if (p) maxcnt = p->t_ival;
for (cnt = maxcnt; cnt != 0; cnt--) {
t_addr AB;
{
switch(p->t_oper) {
case OP_DELETE:
- do_delete(p->t_args[0]);
+ if (! p->t_args[0]) {
+ if (stop_reason) {
+ remove_from_item_list(stop_reason);
+ stop_reason = 0;
+ }
+ else {
+ error("no current stopping point");
+ }
+ }
+ else do_delete(p->t_args[0]);
break;
case OP_LINK:
do_delete(p->t_args[0]);
}
freenode(p);
break;
+ default:
+ assert(0);
}
}
}
}
else if (p != print_command) {
- freenode(print_command);
+ /* freenode(print_command); No, could be in when-list */
print_command = p;
}
/* fall through */
free(buf);
return;
}
- if (! set_bytes(size, buf, a)) {
- error("could not handle this SET request");
- }
+ set_bytes(size, buf, a);
free(buf);
}
case OP_WHEN:
if (p->t_args[1] && ! eval_cond(p->t_args[1])) break;
p = p->t_args[2];
- while (p->t_oper == OP_LINK) {
+ while (p && p->t_oper == OP_LINK) {
if (interrupted) return;
- eval(p->t_args[0]);
+ if (p->t_args[0]) eval(p->t_args[0]);
p = p->t_args[1];
}
if (interrupted) return;
- eval(p);
+ if (p) eval(p);
break;
case OP_TRACE:
if (p->t_args[0] && p->t_args[0]->t_oper == OP_IN) {
struct {
struct idf *tt_idf;
char *tt_str;
- struct scope *tt_scope;
} tt_x;
struct tree *tt_args[MAXARGS];
t_position tt_pos;
#define t_fval t_xxxx.tt_fval
#define t_idf t_xxxx.tt_x.tt_idf
#define t_str t_xxxx.tt_x.tt_str
-#define t_sc t_xxxx.tt_x.tt_scope
#define t_args t_xxxx.tt_args
#define t_lino t_xxxx.tt_pos.lineno
#define t_filename t_xxxx.tt_pos.filename
p_type int_type, char_type, short_type, long_type, bool_type;
p_type uint_type, uchar_type, ushort_type, ulong_type;
-p_type void_type, incomplete_type;
+p_type void_type;
p_type float_type, double_type;
p_type string_type, address_type;
string_type = basic_type(T_STRING, 0L);
address_type = basic_type(T_POINTER, pointer_size);
void_type = basic_type(T_VOID, 0L);
- incomplete_type = basic_type(T_INCOMPLETE, 0L);
float_type = basic_type(T_REAL, float_size);
double_type = basic_type(T_REAL, double_size);
if (j) {
while (--j > 0) {
p_type p = list_row[i].row[j];
- if (p == incomplete_type) {
+ if (p && p->ty_class == 0) {
error("incomplete type (%d,%d) 0x%x", i, j, &list_row[i].row[j]);
}
}
struct symbol *ty_sym;
union {
/* cross references */
- char *typ_tag;
-#define ty_tag ty_v.typ_tag
+ struct type *typ_cross;
+#define ty_cross ty_v.typ_cross
/* procedures/functions: */
struct {
int typ_nparams;
extern p_type char_type, uchar_type, bool_type, int_type,
long_type, double_type, string_type, address_type;
-extern p_type void_type, incomplete_type;
+extern p_type void_type;
extern long int_size, pointer_size, long_size, double_size;
#include "position.h"
#include "scope.h"
+#include "idf.h"
#include "symbol.h"
#include "type.h"
#include "message.h"
case VAR:
/* exists if child exists; nm_value contains addres */
return (t_addr) sym->sy_name.nm_value;
- break;
case VARPAR:
case LOCVAR:
/* first find the stack frame in which it resides */
for (;;) {
sc = 0;
if (! (EM_regs = get_EM_regs(i++))) {
- /* no child? */
- break;
+ return 0;
}
if (! EM_regs[AB_OFF]) {
- /* no more frames */
- break;
+ error("%s not available", sym->sy_idf->id_text);
+ return 0;
}
sc = base_scope(get_scope_from_addr(EM_regs[PC_OFF]));
if (! sc || sc->sc_start > EM_regs[PC_OFF]) {
+ error("%s not available", sym->sy_idf->id_text);
sc = 0;
- break;
+ return 0;
}
if (sc == symsc) break; /* found it */
}
- if (! sc) break; /* not found */
-
if (sym->sy_class == LOCVAR) {
/* Either local variable or value parameter */
return EM_regs[sym->sy_name.nm_value < 0 ? LB_OFF : AB_OFF] +
return a;
}
default:
+ error("%s is not a variable", sym->sy_idf->id_text);
break;
}
return 0;
size = *psize;
*buf = malloc((unsigned) size);
if (! *buf) {
- error("Could not allocate enough memory");
+ error("could not allocate enough memory");
break;
}
if (get_bytes(size, a, *buf)) {