more fixes
This commit is contained in:
parent
c33f7cbe76
commit
7e58923415
|
@ -45,7 +45,7 @@ static struct langdep c = {
|
|||
"0x%lX",
|
||||
"%lu",
|
||||
"0x%lX",
|
||||
"%g",
|
||||
"%.14g",
|
||||
|
||||
"{",
|
||||
"}",
|
||||
|
|
|
@ -49,16 +49,15 @@ commands
|
|||
| %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;
|
||||
|
@ -67,6 +66,7 @@ commands
|
|||
com != run_command &&
|
||||
com != print_command) {
|
||||
freenode(com);
|
||||
com = 0;
|
||||
}
|
||||
}
|
||||
} else if (lastcom && ! errorgiven) {
|
||||
|
@ -98,7 +98,7 @@ command_line(p_tree *p;)
|
|||
| 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)
|
||||
|
@ -112,14 +112,14 @@ command_line(p_tree *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;)
|
||||
|
@ -153,9 +153,9 @@ file_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); }
|
||||
]
|
||||
;
|
||||
|
||||
|
@ -210,7 +210,9 @@ when_command(p_tree *p;)
|
|||
:
|
||||
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) {
|
||||
|
@ -223,46 +225,34 @@ when_command(p_tree *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;)
|
||||
|
@ -323,13 +313,13 @@ able_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])
|
||||
]*
|
||||
;
|
||||
|
@ -341,7 +331,8 @@ condition(p_tree *p;)
|
|||
|
||||
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)
|
||||
;
|
||||
|
|
|
@ -65,8 +65,12 @@ debugger_string
|
|||
}
|
||||
| /* 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(); }
|
||||
|
@ -105,6 +109,7 @@ debugger_string
|
|||
{ 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)
|
||||
|
@ -224,25 +229,21 @@ string_const
|
|||
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;
|
||||
}
|
||||
;
|
||||
|
@ -261,33 +262,6 @@ type_index(int *type_index;)
|
|||
}
|
||||
;
|
||||
|
||||
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();
|
||||
|
@ -335,14 +309,14 @@ routine(p_symbol p;)
|
|||
;
|
||||
|
||||
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
|
||||
|
@ -362,13 +336,14 @@ type(p_type *ptp; int *type_index; p_symbol sy;)
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
||||
|
@ -388,7 +363,8 @@ type(p_type *ptp; int *type_index; p_symbol sy;)
|
|||
[ '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,
|
||||
|
@ -399,28 +375,30 @@ type(p_type *ptp; int *type_index; p_symbol sy;)
|
|||
* 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)
|
||||
|
@ -432,14 +410,14 @@ type(p_type *ptp; int *type_index; p_symbol sy;)
|
|||
*/
|
||||
|
|
||||
/* 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;
|
||||
}
|
||||
|
@ -449,7 +427,7 @@ type(p_type *ptp; int *type_index; p_symbol sy;)
|
|||
/* 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)) ';'
|
||||
|
@ -459,19 +437,23 @@ type(p_type *ptp; int *type_index; p_symbol sy;)
|
|||
]
|
||||
|
|
||||
/* 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;)
|
||||
|
@ -676,6 +658,7 @@ get_field_space(tp, s)
|
|||
}
|
||||
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;
|
||||
|
|
|
@ -188,6 +188,7 @@ DbxRead(f)
|
|||
}
|
||||
close_scope();
|
||||
add_position_addr((char *) 0, (struct outname *) 0);
|
||||
clean_tp_tab();
|
||||
rd_close();
|
||||
return (h.oh_magic == O_CONVERTED);
|
||||
}
|
||||
|
|
|
@ -16,8 +16,11 @@ extern p_tree get_from_item_list();
|
|||
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)
|
||||
|
@ -36,6 +39,8 @@ 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.
|
||||
|
@ -45,16 +50,22 @@ do_restore(p)
|
|||
{
|
||||
struct dump *d;
|
||||
|
||||
p = get_from_item_list((int) p->t_ival);
|
||||
if (!p || p->t_oper != OP_DUMP) {
|
||||
error("no such dump");
|
||||
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;
|
||||
|
||||
if (! d) {
|
||||
error("no dumps");
|
||||
return;
|
||||
}
|
||||
|
||||
d = (struct dump *) p->t_args[0];
|
||||
|
||||
if (! put_dump(&d->mglobal, d->globals, &d->mstack, d->stack)) {
|
||||
error("no debuggee");
|
||||
}
|
||||
do_items();
|
||||
}
|
||||
|
@ -66,5 +77,12 @@ free_dump(p)
|
|||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -65,8 +65,9 @@ long
|
|||
get_int(buf, size, class)
|
||||
char *buf;
|
||||
long size;
|
||||
int class;
|
||||
{
|
||||
long l;
|
||||
register long l;
|
||||
|
||||
switch((int)size) {
|
||||
case sizeof(char):
|
||||
|
@ -140,8 +141,8 @@ int
|
|||
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
|
||||
|
@ -318,7 +319,6 @@ do_deref(p, pbuf, psize, ptp)
|
|||
*pbuf = malloc((unsigned) *psize);
|
||||
malloc_succeeded(*pbuf);
|
||||
if (! get_bytes(*psize, addr, *pbuf)) {
|
||||
error("could not get value");
|
||||
free(*pbuf);
|
||||
*pbuf = 0;
|
||||
return 0;
|
||||
|
@ -918,7 +918,6 @@ array_addr(p, paddr, psize, ptp)
|
|||
}
|
||||
if ((*ptp)->ty_class == T_POINTER) {
|
||||
if (! get_bytes(pointer_size, *paddr, (char *) paddr)) {
|
||||
error("could not get value");
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1021,7 +1020,6 @@ do_select(p, pbuf, psize, ptp)
|
|||
*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;
|
||||
|
@ -1105,8 +1103,6 @@ eval_expr(p, pbuf, psize, ptp)
|
|||
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;
|
||||
|
@ -1180,8 +1176,6 @@ eval_desig(p, paddr, psize, ptp)
|
|||
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;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
extern FILE *db_out;
|
||||
extern int db_ss;
|
||||
int stop_reason;
|
||||
|
||||
typedef struct item {
|
||||
struct item *i_next;
|
||||
|
@ -51,8 +52,10 @@ pr_item(i)
|
|||
}
|
||||
|
||||
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.
|
||||
|
@ -60,20 +63,46 @@ item_addr_actions(a, mess_type)
|
|||
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_TRACE:
|
||||
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;
|
||||
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:
|
||||
case OP_DUMP:
|
||||
case OP_DISPLAY:
|
||||
break;
|
||||
|
@ -81,7 +110,6 @@ item_addr_actions(a, mess_type)
|
|||
assert(0);
|
||||
}
|
||||
}
|
||||
i = i->i_next;
|
||||
}
|
||||
return stopping;
|
||||
}
|
||||
|
@ -107,8 +135,8 @@ add_to_item_list(p)
|
|||
|
||||
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;
|
||||
}
|
||||
|
@ -140,8 +168,8 @@ remove_from_item_list(n)
|
|||
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;
|
||||
|
@ -179,8 +207,8 @@ able_item(n, kind)
|
|||
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;
|
||||
|
|
|
@ -19,6 +19,7 @@ int debug;
|
|||
extern struct tokenname tkidf[];
|
||||
extern char *strindex();
|
||||
extern int eof_seen;
|
||||
extern int interrupted;
|
||||
|
||||
static struct tokenname shorts[] = {
|
||||
{LIST, "l"},
|
||||
|
@ -113,14 +114,16 @@ error(va_alist)
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ static struct langdep m2 = {
|
|||
"%lXH",
|
||||
"%lu",
|
||||
"%lXH",
|
||||
"%G",
|
||||
"%.14G",
|
||||
|
||||
"[",
|
||||
"]",
|
||||
|
|
|
@ -9,22 +9,22 @@ OP_REAL 0 0
|
|||
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
|
||||
|
|
|
@ -187,6 +187,13 @@ print_val(tp, tp_sz, addr, compressed, indent, format)
|
|||
|
||||
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;
|
||||
|
|
266
util/grind/run.c
266
util/grind/run.c
|
@ -30,6 +30,8 @@ extern long pointer_size;
|
|||
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 */
|
||||
|
@ -39,7 +41,6 @@ static int fild1[2], fild2[2]; /* pipe file descriptors */
|
|||
int disable_intr = 1;
|
||||
|
||||
int db_ss;
|
||||
t_lineno currline;
|
||||
|
||||
static int catch_sigpipe();
|
||||
static int stopped();
|
||||
|
@ -64,6 +65,7 @@ init_run()
|
|||
from_child = fild2[0];
|
||||
child_pid = 0;
|
||||
if (currfile) CurrentScope = currfile->sy_file->f_scope;
|
||||
currline = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -191,7 +193,7 @@ start_child(p)
|
|||
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) {
|
||||
|
@ -225,13 +227,19 @@ ureceive(p, c)
|
|||
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;
|
||||
|
@ -240,13 +248,16 @@ ureceive(p, c)
|
|||
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
|
||||
|
@ -256,16 +267,25 @@ usend(p, c)
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
@ -307,11 +327,15 @@ stopped(s, a)
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -322,82 +346,84 @@ could_send(m, stop_message)
|
|||
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*/
|
||||
}
|
||||
|
@ -415,17 +441,22 @@ getbytes(size, from, to, kind)
|
|||
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
|
||||
|
@ -449,7 +480,6 @@ get_string(size, from, to)
|
|||
return retval;
|
||||
}
|
||||
|
||||
int
|
||||
set_bytes(size, from, to)
|
||||
long size;
|
||||
char *from;
|
||||
|
@ -461,9 +491,21 @@ set_bytes(size, from, to)
|
|||
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
|
||||
|
@ -475,16 +517,25 @@ get_dump(globmessage, globbuf, stackmessage, stackbuf)
|
|||
|
||||
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);
|
||||
|
@ -492,7 +543,6 @@ get_dump(globmessage, globbuf, stackmessage, stackbuf)
|
|||
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,
|
||||
|
@ -537,10 +587,20 @@ get_EM_regs(level)
|
|||
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);
|
||||
|
@ -558,7 +618,20 @@ set_pc(PC)
|
|||
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
|
||||
|
@ -569,7 +642,7 @@ send_cont(stop_message)
|
|||
|
||||
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
|
||||
|
@ -582,9 +655,7 @@ do_single_step(type, count)
|
|||
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;
|
||||
}
|
||||
|
@ -596,12 +667,10 @@ set_or_clear_breakpoint(a, type)
|
|||
{
|
||||
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;
|
||||
|
@ -618,7 +687,8 @@ set_or_clear_trace(start, end, type)
|
|||
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;
|
||||
|
|
|
@ -129,3 +129,19 @@ base_scope(sc)
|
|||
}
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -52,3 +52,8 @@ extern p_scope get_next_scope_from_addr();
|
|||
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();
|
||||
|
|
|
@ -221,14 +221,13 @@ identify(p, class_set)
|
|||
|
||||
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.
|
||||
*/
|
||||
|
@ -382,3 +381,20 @@ do_which(p)
|
|||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,11 +19,12 @@
|
|||
#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;
|
||||
|
||||
|
@ -59,11 +60,6 @@ mknode(va_alist)
|
|||
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:
|
||||
|
@ -120,6 +116,25 @@ get_addr_from_node(p)
|
|||
|
||||
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;
|
||||
|
||||
|
@ -209,13 +224,16 @@ print_node(p, top_level)
|
|||
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);
|
||||
|
@ -225,15 +243,16 @@ print_node(p, top_level)
|
|||
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);
|
||||
|
@ -258,7 +277,7 @@ print_node(p, top_level)
|
|||
}
|
||||
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];
|
||||
|
@ -299,6 +318,8 @@ print_node(p, top_level)
|
|||
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);
|
||||
|
@ -326,6 +347,8 @@ print_node(p, top_level)
|
|||
case OP_BINOP:
|
||||
(*currlang->printop)(p);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
if (top_level) fputs("\n", db_out);
|
||||
}
|
||||
|
@ -342,7 +365,8 @@ repeatable(com)
|
|||
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]);
|
||||
|
@ -428,7 +452,14 @@ do_list(p)
|
|||
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);
|
||||
|
@ -461,7 +492,6 @@ setstop(p, kind)
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
@ -496,11 +526,7 @@ settrace(p, kind)
|
|||
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)
|
||||
|
@ -518,6 +544,15 @@ able(p, kind)
|
|||
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);
|
||||
|
@ -526,6 +561,8 @@ able(p, kind)
|
|||
case OP_INTEGER:
|
||||
able_item((int)p->t_ival, kind);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -545,7 +582,6 @@ do_continue(p)
|
|||
p_tree p;
|
||||
{
|
||||
int count;
|
||||
int first_time = 1;
|
||||
|
||||
if (p) {
|
||||
count = p->t_args[0]->t_ival;
|
||||
|
@ -553,38 +589,41 @@ do_continue(p)
|
|||
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)) {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -594,10 +633,11 @@ do_regs(p)
|
|||
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);
|
||||
|
@ -615,12 +655,13 @@ do_where(p)
|
|||
{
|
||||
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;
|
||||
|
@ -634,6 +675,7 @@ do_where(p)
|
|||
i -= maxcnt;
|
||||
if (i < 0) i = 0;
|
||||
}
|
||||
else if (p) maxcnt = p->t_ival;
|
||||
for (cnt = maxcnt; cnt != 0; cnt--) {
|
||||
t_addr AB;
|
||||
|
||||
|
@ -659,7 +701,16 @@ do_delete(p)
|
|||
{
|
||||
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]);
|
||||
|
@ -681,6 +732,8 @@ do_delete(p)
|
|||
}
|
||||
freenode(p);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -702,7 +755,7 @@ do_print(p)
|
|||
}
|
||||
}
|
||||
else if (p != print_command) {
|
||||
freenode(print_command);
|
||||
/* freenode(print_command); No, could be in when-list */
|
||||
print_command = p;
|
||||
}
|
||||
/* fall through */
|
||||
|
@ -746,9 +799,7 @@ do_set(p)
|
|||
free(buf);
|
||||
return;
|
||||
}
|
||||
if (! set_bytes(size, buf, a)) {
|
||||
error("could not handle this SET request");
|
||||
}
|
||||
set_bytes(size, buf, a);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
|
@ -760,13 +811,13 @@ perform(p, a)
|
|||
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) {
|
||||
|
|
|
@ -13,7 +13,6 @@ typedef struct tree {
|
|||
struct {
|
||||
struct idf *tt_idf;
|
||||
char *tt_str;
|
||||
struct scope *tt_scope;
|
||||
} tt_x;
|
||||
struct tree *tt_args[MAXARGS];
|
||||
t_position tt_pos;
|
||||
|
@ -23,7 +22,6 @@ typedef struct tree {
|
|||
#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
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
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;
|
||||
|
||||
|
@ -257,7 +257,6 @@ init_types()
|
|||
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);
|
||||
|
||||
|
@ -324,7 +323,7 @@ clean_tp_tab()
|
|||
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]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,8 +44,8 @@ typedef struct type {
|
|||
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;
|
||||
|
@ -117,6 +117,6 @@ extern long
|
|||
|
||||
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;
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "position.h"
|
||||
#include "scope.h"
|
||||
#include "idf.h"
|
||||
#include "symbol.h"
|
||||
#include "type.h"
|
||||
#include "message.h"
|
||||
|
@ -38,7 +39,6 @@ get_addr(sym, psize)
|
|||
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 */
|
||||
|
@ -51,23 +51,21 @@ get_addr(sym, psize)
|
|||
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] +
|
||||
|
@ -101,6 +99,7 @@ get_addr(sym, psize)
|
|||
return a;
|
||||
}
|
||||
default:
|
||||
error("%s is not a variable", sym->sy_idf->id_text);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
@ -162,7 +161,7 @@ get_value(sym, buf, psize)
|
|||
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)) {
|
||||
|
|
Loading…
Reference in a new issue