Many more changes
This commit is contained in:
parent
1ade1b814d
commit
1f408a38c2
|
@ -13,7 +13,6 @@
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
#include "rd.h"
|
#include "rd.h"
|
||||||
|
|
||||||
extern char *Malloc();
|
|
||||||
extern char *strindex();
|
extern char *strindex();
|
||||||
extern struct outname *DbxString();
|
extern struct outname *DbxString();
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include "position.h"
|
#include "position.h"
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
|
#include "type.h"
|
||||||
|
#include "expr.h"
|
||||||
|
|
||||||
extern long pointer_size;
|
extern long pointer_size;
|
||||||
extern p_tree get_from_item_list();
|
extern p_tree get_from_item_list();
|
||||||
|
@ -29,7 +31,7 @@ do_dump(p)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
p->t_args[0] = (struct tree *) d;
|
p->t_args[0] = (struct tree *) d;
|
||||||
p->t_address = (t_addr) BUFTOA(d->mglobal.m_buf+PC_OFF*pointer_size);
|
p->t_address = (t_addr) get_int(d->mglobal.m_buf+PC_OFF*pointer_size, pointer_size, T_UNSIGNED);
|
||||||
add_to_item_list(p);
|
add_to_item_list(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* $Header$ */
|
/* $Header$ */
|
||||||
|
|
||||||
/* This file contains the expression evaluator. It exports four routines:
|
/* This file contains the expression evaluator. It exports the following
|
||||||
|
routines:
|
||||||
- int eval_cond(p_tree p)
|
- int eval_cond(p_tree p)
|
||||||
This routine evaluates the conditional expression indicated by p
|
This routine evaluates the conditional expression indicated by p
|
||||||
and returns 1 if it evaluates to TRUE, or 0 if it could not be
|
and returns 1 if it evaluates to TRUE, or 0 if it could not be
|
||||||
|
@ -26,6 +27,16 @@
|
||||||
while producing an error message. Otherwise, it returns 1 and
|
while producing an error message. Otherwise, it returns 1 and
|
||||||
the resulting value, type and size are left in pbuf, ptp, and
|
the resulting value, type and size are left in pbuf, ptp, and
|
||||||
psize, respectively.
|
psize, respectively.
|
||||||
|
- long get_int(char *buf, long size, int class)
|
||||||
|
Returns the value of size 'size', residing in 'buf', of 'class'
|
||||||
|
T_INTEGER, T_UNSIGNED, or T_ENUM.
|
||||||
|
- int put_int(char *buf, long size, long value)
|
||||||
|
Stores the value 'value' of size 'size' in 'buf'.
|
||||||
|
- double get_real(char *buf, long size)
|
||||||
|
Returns the real value of size 'size', residing in 'buf'.
|
||||||
|
T_INTEGER, T_UNSIGNED, or T_ENUM.
|
||||||
|
- int put_real(char *buf, long size, double value)
|
||||||
|
Stores the value 'value' of size 'size' in 'buf'.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -41,10 +52,16 @@
|
||||||
#include "langdep.h"
|
#include "langdep.h"
|
||||||
|
|
||||||
extern FILE *db_out;
|
extern FILE *db_out;
|
||||||
|
extern char *strcpy();
|
||||||
|
|
||||||
|
#define malloc_succeeded(p) if (! (p)) {\
|
||||||
|
error("could not allocate enough memory");\
|
||||||
|
return 0;\
|
||||||
|
}
|
||||||
|
|
||||||
/* buffer to integer and vice versa routines */
|
/* buffer to integer and vice versa routines */
|
||||||
|
|
||||||
static long
|
long
|
||||||
get_int(buf, size, class)
|
get_int(buf, size, class)
|
||||||
char *buf;
|
char *buf;
|
||||||
long size;
|
long size;
|
||||||
|
@ -68,7 +85,6 @@ get_int(buf, size, class)
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
put_int(buf, size, value)
|
put_int(buf, size, value)
|
||||||
char *buf;
|
char *buf;
|
||||||
long size;
|
long size;
|
||||||
|
@ -90,7 +106,7 @@ put_int(buf, size, value)
|
||||||
|
|
||||||
/* buffer to real and vice versa routines */
|
/* buffer to real and vice versa routines */
|
||||||
|
|
||||||
static double
|
double
|
||||||
get_real(buf, size)
|
get_real(buf, size)
|
||||||
char *buf;
|
char *buf;
|
||||||
long size;
|
long size;
|
||||||
|
@ -104,7 +120,6 @@ get_real(buf, size)
|
||||||
/*NOTREACHED*/
|
/*NOTREACHED*/
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
put_real(buf, size, value)
|
put_real(buf, size, value)
|
||||||
char *buf;
|
char *buf;
|
||||||
long size;
|
long size;
|
||||||
|
@ -138,7 +153,8 @@ convert(pbuf, psize, ptp, tp, size)
|
||||||
|
|
||||||
if (*ptp == tp) return 1;
|
if (*ptp == tp) return 1;
|
||||||
if (size > *psize) {
|
if (size > *psize) {
|
||||||
*pbuf = Realloc(*pbuf, (unsigned int) size);
|
*pbuf = realloc(*pbuf, (unsigned int) size);
|
||||||
|
malloc_succeeded(*pbuf);
|
||||||
}
|
}
|
||||||
if ((*ptp)->ty_class == T_SUBRANGE) *ptp = (*ptp)->ty_base;
|
if ((*ptp)->ty_class == T_SUBRANGE) *ptp = (*ptp)->ty_base;
|
||||||
switch((*ptp)->ty_class) {
|
switch((*ptp)->ty_class) {
|
||||||
|
@ -298,7 +314,8 @@ do_deref(p, pbuf, psize, ptp)
|
||||||
t_addr addr;
|
t_addr addr;
|
||||||
|
|
||||||
if (ptr_addr(p, &addr, psize, ptp)) {
|
if (ptr_addr(p, &addr, psize, ptp)) {
|
||||||
*pbuf = Malloc((unsigned) *psize);
|
*pbuf = malloc((unsigned) *psize);
|
||||||
|
malloc_succeeded(*pbuf);
|
||||||
if (! get_bytes(*psize, addr, *pbuf)) {
|
if (! get_bytes(*psize, addr, *pbuf)) {
|
||||||
error("could not get value");
|
error("could not get value");
|
||||||
}
|
}
|
||||||
|
@ -317,7 +334,8 @@ do_addr(p, pbuf, psize, ptp)
|
||||||
t_addr addr;
|
t_addr addr;
|
||||||
|
|
||||||
if (eval_desig(p->t_args[0], &addr, psize, ptp)) {
|
if (eval_desig(p->t_args[0], &addr, psize, ptp)) {
|
||||||
*pbuf = Malloc((unsigned) pointer_size);
|
*pbuf = malloc((unsigned) pointer_size);
|
||||||
|
malloc_succeeded(*pbuf);
|
||||||
put_int(*pbuf, pointer_size, (long) addr);
|
put_int(*pbuf, pointer_size, (long) addr);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -780,8 +798,8 @@ do_cmp(p, pbuf, psize, ptp)
|
||||||
}
|
}
|
||||||
if (*psize < int_size) {
|
if (*psize < int_size) {
|
||||||
*psize = int_size;
|
*psize = int_size;
|
||||||
free(*pbuf);
|
*pbuf = realloc(*pbuf, (unsigned int) int_size);
|
||||||
*pbuf = Malloc((unsigned int) int_size);
|
malloc_succeeded(*pbuf);
|
||||||
}
|
}
|
||||||
else *psize = int_size;
|
else *psize = int_size;
|
||||||
if (currlang->has_bool_type) {
|
if (currlang->has_bool_type) {
|
||||||
|
@ -824,7 +842,8 @@ do_in(p, pbuf, psize, ptp)
|
||||||
&& l <= (size << 3)
|
&& l <= (size << 3)
|
||||||
&& (((int *) buf)[(int)(l>>sft)] & (1 << (l & ((1 << sft)-1))));
|
&& (((int *) buf)[(int)(l>>sft)] & (1 << (l & ((1 << sft)-1))));
|
||||||
free(buf);
|
free(buf);
|
||||||
*pbuf = Realloc(*pbuf, (unsigned) int_size);
|
*pbuf = realloc(*pbuf, (unsigned) int_size);
|
||||||
|
malloc_succeeded(*pbuf);
|
||||||
*psize = int_size;
|
*psize = int_size;
|
||||||
*ptp = currlang->has_bool_type ? bool_type : int_type;
|
*ptp = currlang->has_bool_type ? bool_type : int_type;
|
||||||
put_int(*pbuf, *psize, l);
|
put_int(*pbuf, *psize, l);
|
||||||
|
@ -889,7 +908,8 @@ do_array(p, pbuf, psize, ptp)
|
||||||
t_addr a;
|
t_addr a;
|
||||||
|
|
||||||
if (array_addr(p, &a, psize, ptp)) {
|
if (array_addr(p, &a, psize, ptp)) {
|
||||||
*pbuf = Malloc((unsigned int) *psize);
|
*pbuf = malloc((unsigned int) *psize);
|
||||||
|
malloc_succeeded(*pbuf);
|
||||||
if (! get_bytes(*psize, a, *pbuf)) {
|
if (! get_bytes(*psize, a, *pbuf)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -945,7 +965,8 @@ do_select(p, pbuf, psize, ptp)
|
||||||
{
|
{
|
||||||
t_addr a;
|
t_addr a;
|
||||||
if (select_addr(p, &a, psize, ptp)) {
|
if (select_addr(p, &a, psize, ptp)) {
|
||||||
*pbuf = Malloc((unsigned int) *psize);
|
*pbuf = malloc((unsigned int) *psize);
|
||||||
|
malloc_succeeded(*pbuf);
|
||||||
if (! get_bytes(*psize, a, *pbuf)) {
|
if (! get_bytes(*psize, a, *pbuf)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1011,26 +1032,29 @@ eval_expr(p, pbuf, psize, ptp)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_INTEGER:
|
case OP_INTEGER:
|
||||||
*pbuf = Malloc(sizeof(long));
|
*pbuf = malloc((unsigned int) long_size);
|
||||||
*psize = sizeof(long);
|
malloc_succeeded(*pbuf);
|
||||||
|
*psize = long_size;
|
||||||
*ptp = long_type;
|
*ptp = long_type;
|
||||||
*((long *) (*pbuf)) = p->t_ival;
|
put_int(*pbuf, long_size, p->t_ival);
|
||||||
retval = 1;
|
retval = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_REAL:
|
case OP_REAL:
|
||||||
*pbuf = Malloc(sizeof(double));
|
*pbuf = malloc((unsigned int) double_size);
|
||||||
*psize = sizeof(double);
|
malloc_succeeded(*pbuf);
|
||||||
|
*psize = double_size;
|
||||||
*ptp = double_type;
|
*ptp = double_type;
|
||||||
*((double *) (*pbuf)) = p->t_fval;
|
put_real(*pbuf, double_size, p->t_fval);
|
||||||
retval = 1;
|
retval = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_STRING:
|
case OP_STRING:
|
||||||
*pbuf = Malloc(sizeof(char *));
|
*psize = strlen(p->t_sval)+1;
|
||||||
*psize = sizeof(char *);
|
*pbuf = malloc((unsigned int)*psize);
|
||||||
|
malloc_succeeded(*pbuf);
|
||||||
*ptp = string_type;
|
*ptp = string_type;
|
||||||
*((char **) (*pbuf)) = p->t_sval;
|
strcpy(*pbuf, p->t_sval);
|
||||||
retval = 1;
|
retval = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -4,33 +4,92 @@
|
||||||
indices into arrays.
|
indices into arrays.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define E_NOT 1
|
#define E_NOT 1
|
||||||
#define E_DEREF 2
|
#define E_DEREF 2
|
||||||
#define E_AND 3
|
#define E_AND 3
|
||||||
#define E_OR 4
|
#define E_OR 4
|
||||||
#define E_DIV 5 /* equal to truncated quotient */
|
#define E_DIV 5 /* equal to truncated quotient */
|
||||||
#define E_MOD 6 /* x = (x E_DIV y) * y + x E_MOD y,
|
#define E_MOD 6 /* x = (x E_DIV y) * y + x E_MOD y,
|
||||||
0 <= (x E_MOD y) < y
|
0 <= (x E_MOD y) < y
|
||||||
*/
|
*/
|
||||||
#define E_ZDIV 7 /* quotient rounded to 0 */
|
#define E_ZDIV 7 /* quotient rounded to 0 */
|
||||||
#define E_ZMOD 8 /* remainder of E_ZDIV */
|
#define E_ZMOD 8 /* remainder of E_ZDIV */
|
||||||
#define E_IN 9 /* set membership */
|
#define E_IN 9 /* set membership */
|
||||||
#define E_ARRAY 10
|
#define E_ARRAY 10
|
||||||
#define E_PLUS 11
|
#define E_PLUS 11
|
||||||
#define E_MIN 12
|
#define E_MIN 12
|
||||||
#define E_MUL 13
|
#define E_MUL 13
|
||||||
#define E_EQUAL 14
|
#define E_EQUAL 14
|
||||||
#define E_NOTEQUAL 15
|
#define E_NOTEQUAL 15
|
||||||
#define E_LTEQUAL 16
|
#define E_LTEQUAL 16
|
||||||
#define E_GTEQUAL 17
|
#define E_GTEQUAL 17
|
||||||
#define E_LT 18
|
#define E_LT 18
|
||||||
#define E_GT 19
|
#define E_GT 19
|
||||||
#define E_SELECT 20
|
#define E_SELECT 20
|
||||||
#define E_BAND 21 /* bitwise and */
|
#define E_BAND 21 /* bitwise and */
|
||||||
#define E_BOR 22 /* bitwise or */
|
#define E_BOR 22 /* bitwise or */
|
||||||
#define E_BXOR 23
|
#define E_BXOR 23
|
||||||
#define E_BNOT 24
|
#define E_BNOT 24
|
||||||
#define E_DERSELECT 25 /* -> in C */
|
#define E_DERSELECT 25 /* -> in C */
|
||||||
#define E_LSFT 26
|
#define E_LSFT 26
|
||||||
#define E_RSFT 27
|
#define E_RSFT 27
|
||||||
#define E_ADDR 28
|
#define E_ADDR 28
|
||||||
|
|
||||||
|
/* long get_int(char *buf, long size, int class)
|
||||||
|
Returns the value of size 'size', residing in 'buf', of 'class'
|
||||||
|
T_INTEGER, T_UNSIGNED, or T_ENUM.
|
||||||
|
*/
|
||||||
|
extern long get_int();
|
||||||
|
|
||||||
|
/* int put_int(char *buf, long size, long value)
|
||||||
|
Stores the value 'value' of size 'size' in 'buf'.
|
||||||
|
*/
|
||||||
|
extern int put_int();
|
||||||
|
|
||||||
|
/* double get_real(char *buf, long size)
|
||||||
|
Returns the real value of size 'size', residing in 'buf'.
|
||||||
|
T_INTEGER, T_UNSIGNED, or T_ENUM.
|
||||||
|
*/
|
||||||
|
extern double get_real();
|
||||||
|
|
||||||
|
/* int put_real(char *buf, long size, double value)
|
||||||
|
Stores the value 'value' of size 'size' in 'buf'.
|
||||||
|
*/
|
||||||
|
extern int put_real();
|
||||||
|
|
||||||
|
/* int eval_cond(p_tree p)
|
||||||
|
This routine evaluates the conditional expression indicated by p
|
||||||
|
and returns 1 if it evaluates to TRUE, or 0 if it could not be
|
||||||
|
evaluated for some reason or if it evalutes to FALSE.
|
||||||
|
If the expression cannot be evaluated, an error message is given.
|
||||||
|
*/
|
||||||
|
extern int eval_cond();
|
||||||
|
|
||||||
|
/* int eval_desig(p_tree p, t_addr *pbuf, long **psize, p_type *ptp)
|
||||||
|
This routine evaluates the expression indicated by p, which should
|
||||||
|
result in a designator. The result of the expression is an address
|
||||||
|
which is to be found in *pbuf. *psize will contain the size of the
|
||||||
|
designated object, and *ptp its type.
|
||||||
|
If the expression cannot be evaluated or does not result in a
|
||||||
|
designator, 0 is returned and an error message is given.
|
||||||
|
Otherwise, 1 is returned.
|
||||||
|
*/
|
||||||
|
extern int eval_desig();
|
||||||
|
|
||||||
|
/* int eval_expr(p_tree p, char **pbuf, long **psize, p_type *ptp)
|
||||||
|
This routine evaluates the expression indicated by p.
|
||||||
|
The result of the expression is left in *pbuf.
|
||||||
|
*psize will contain the size of the value, and *ptp its type.
|
||||||
|
If the expression cannot be evaluated, 0 is returned and an error
|
||||||
|
message is given. Otherwise, 1 is returned.
|
||||||
|
*/
|
||||||
|
extern int eval_expr();
|
||||||
|
|
||||||
|
/* int convert(char **pbuf, long *psize, p_type *ptp, p_type tp, long size)
|
||||||
|
This routine tries to convert the value in pbuf of size psize
|
||||||
|
and type ptp to type tp with size size. It returns 0 if this fails,
|
||||||
|
while producing an error message. Otherwise, it returns 1 and
|
||||||
|
the resulting value, type and size are left in pbuf, ptp, and
|
||||||
|
psize, respectively.
|
||||||
|
*/
|
||||||
|
extern int convert();
|
||||||
|
|
|
@ -13,15 +13,15 @@ grind \- source-level debugger for ACK
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B Grind
|
.B Grind
|
||||||
is a utility for source-level debugging and execution of
|
is a utility for source-level debugging and execution of
|
||||||
programs written in C or Modula-2 (Pascal will be added later).
|
programs written in C, Modula-2, or Pascal.
|
||||||
Its operation resembles the operation of
|
Its operation resembles the operation of
|
||||||
.IR dbx ,
|
.IR dbx ,
|
||||||
a source-level debugger
|
a source-level debugger
|
||||||
available on many Unix systems. However, some
|
available on many Unix systems. However, some
|
||||||
.B Grind
|
.B grind
|
||||||
commands are not available in
|
commands are not available in
|
||||||
.IR dbx ,
|
.IR dbx ,
|
||||||
and some more
|
some more
|
||||||
.I dbx
|
.I dbx
|
||||||
commands are not available in
|
commands are not available in
|
||||||
.BR grind ,
|
.BR grind ,
|
||||||
|
@ -48,8 +48,8 @@ Some
|
||||||
.B grind
|
.B grind
|
||||||
commands take an expression argument.
|
commands take an expression argument.
|
||||||
.SS Expressions
|
.SS Expressions
|
||||||
.B Grind expressions
|
.B Grind
|
||||||
are combinations of variables, constants, and operators.
|
expressions are combinations of variables, constants, and operators.
|
||||||
The syntax and the operators depend on the source language of the program
|
The syntax and the operators depend on the source language of the program
|
||||||
being debugged. However, the type rules are probably less strict than the
|
being debugged. However, the type rules are probably less strict than the
|
||||||
rules of this language. For instance, in Modula-2 one cannot combine
|
rules of this language. For instance, in Modula-2 one cannot combine
|
||||||
|
@ -57,8 +57,6 @@ values of type INTEGER with values of type REAL in an expression without
|
||||||
using conversion routines. In
|
using conversion routines. In
|
||||||
.BR grind ,
|
.BR grind ,
|
||||||
the conversions needed are performed automatically.
|
the conversions needed are performed automatically.
|
||||||
Expressions cannot involve strings, structures, or
|
|
||||||
arrays, although elements of structures or arrays may be used.
|
|
||||||
.SS Operators
|
.SS Operators
|
||||||
.LP
|
.LP
|
||||||
.B Grind
|
.B Grind
|
||||||
|
@ -72,19 +70,19 @@ The syntax and priority of these operators depends on the source language.
|
||||||
Parentheses can be used for grouping.
|
Parentheses can be used for grouping.
|
||||||
.SS "Scope Rules"
|
.SS "Scope Rules"
|
||||||
.LP
|
.LP
|
||||||
.B dbx
|
.B Grind
|
||||||
uses the current file and function to resolve scope conflicts.
|
uses the current file and function to resolve scope conflicts.
|
||||||
Their values are updated as files and functions are entered and exited
|
Their values are updated as files and functions are entered and exited
|
||||||
during execution.
|
during execution.
|
||||||
Names can also be qualified with procedure- or module names, as in
|
Names can also be qualified with procedure- or module names, as in
|
||||||
\fImodule\fP`\fIproc\fP`\fIname\fP.
|
\fImodule\fP`\fIproc\fP`\fIname\fP.
|
||||||
.B Grind
|
.B Grind
|
||||||
tries to be intelligent about names, so qualification is only needed when
|
tries to be intelligent about names; qualification is only needed when
|
||||||
names are used for more than one object in a program and the current scope
|
names are used for more than one object in a program and the current scope
|
||||||
does not help.
|
does not help.
|
||||||
.SS "Positions"
|
.SS "Positions"
|
||||||
In general, there are two ways to specify a position; the first way is
|
In general, there are two ways to specify a position; the first way is
|
||||||
to specify filename and linenumber, in a so-called at-clause, like this:
|
to specify file name and line number, in a so-called at-clause, like this:
|
||||||
.RS
|
.RS
|
||||||
\fBat\fP [ "\fIfilename\fP": ] \fIlinenumber\fP
|
\fBat\fP [ "\fIfilename\fP": ] \fIlinenumber\fP
|
||||||
.RE
|
.RE
|
||||||
|
@ -99,7 +97,7 @@ This indicates the first statement within the named function (except for
|
||||||
the trace command discussed later).
|
the trace command discussed later).
|
||||||
.SS "Commands"
|
.SS "Commands"
|
||||||
.TP
|
.TP
|
||||||
.B \s+2^\s0C
|
.B ^C
|
||||||
Interrupt. Stop the program being debugged and enter
|
Interrupt. Stop the program being debugged and enter
|
||||||
.BR grind .
|
.BR grind .
|
||||||
.TP
|
.TP
|
||||||
|
@ -114,11 +112,18 @@ and possible redirection of standard input and/or standard output.
|
||||||
Repeats the last
|
Repeats the last
|
||||||
.B run
|
.B run
|
||||||
command.
|
command.
|
||||||
|
.TP
|
||||||
\fBcont\fP [ \fBat\fP \fIsourceline\fP ]
|
\fBcont\fP [ \fBat\fP \fIsourceline\fP ]
|
||||||
|
.ti -0.5i
|
||||||
|
\fBc\fP [ \fBat\fP \fIsourceline\fP ]
|
||||||
|
.br
|
||||||
Continue execution from where it stopped, or, if \fIsourceline\fP is
|
Continue execution from where it stopped, or, if \fIsourceline\fP is
|
||||||
given, at that source line.
|
given, at that source line.
|
||||||
.TP
|
.TP
|
||||||
\fBtrace\fP [ \fBon\fP \fIexpression\fP ] [ \fIposition\fP ] [ \fBif\fP \fIcondition\fP ]
|
\fBtrace\fP [ \fBon\fP \fIexpression\fP ] [ \fIposition\fP ] [ \fBif\fP \fIcondition\fP ]
|
||||||
|
.ti -0.5i
|
||||||
|
\fBt\fP [ \fBon\fP \fIexpression\fP ] [ \fIposition\fP ] [ \fBif\fP \fIcondition\fP ]
|
||||||
|
.br
|
||||||
Display tracing information.
|
Display tracing information.
|
||||||
If no argument is specified, each source line is displayed before
|
If no argument is specified, each source line is displayed before
|
||||||
execution.
|
execution.
|
||||||
|
@ -167,10 +172,13 @@ If no condition is given, stop when
|
||||||
is reached.
|
is reached.
|
||||||
Either a position or a condition (or both) must be given.
|
Either a position or a condition (or both) must be given.
|
||||||
.TP
|
.TP
|
||||||
\fBprint\fP \fIexpression\fP [ ',' \fIexpression\fP ] ...
|
\fBprint\fP \fIexpression\fP [ , \fIexpression\fP ] ...
|
||||||
|
.ti -0.5i
|
||||||
|
\fBp\fP \fIexpression\fP [ , \fIexpression\fP ] ...
|
||||||
|
.br
|
||||||
Print the value of each expression.
|
Print the value of each expression.
|
||||||
.TP
|
.TP
|
||||||
\fBdisplay\fP \fIexpression\fP [ ',' \fIexpression\fP ] ...
|
\fBdisplay\fP \fIexpression\fP [ , \fIexpression\fP ] ...
|
||||||
Print the value of each expression whenever the program stops.
|
Print the value of each expression whenever the program stops.
|
||||||
.TP
|
.TP
|
||||||
.B dump
|
.B dump
|
||||||
|
@ -197,11 +205,17 @@ Also display current
|
||||||
records.
|
records.
|
||||||
.TP
|
.TP
|
||||||
\fBdelete\fP \fIcommandnumber\fP
|
\fBdelete\fP \fIcommandnumber\fP
|
||||||
|
.ti -0.5i
|
||||||
|
\fBd\fP \fIcommandnumber\fP
|
||||||
|
.br
|
||||||
Remove the command corresponding to \fIcommandnumber\fP
|
Remove the command corresponding to \fIcommandnumber\fP
|
||||||
(as displayed by
|
(as displayed by
|
||||||
.BR status ).
|
.BR status ).
|
||||||
.TP
|
.TP
|
||||||
\fBrestore\fP \fIcommandnumber\fP
|
\fBrestore\fP \fIcommandnumber\fP
|
||||||
|
.ti -0.5i
|
||||||
|
\fBr\fP \fIcommandnumber\fP
|
||||||
|
.br
|
||||||
Restore the data corresponding to the dump of \fIcommandnumber\fP
|
Restore the data corresponding to the dump of \fIcommandnumber\fP
|
||||||
(as displayed by
|
(as displayed by
|
||||||
.BR status ).
|
.BR status ).
|
||||||
|
@ -215,6 +229,9 @@ Apart from this,
|
||||||
even works when the program is finished.
|
even works when the program is finished.
|
||||||
.TP
|
.TP
|
||||||
\fBstep\fP [ \fIn\fP ]
|
\fBstep\fP [ \fIn\fP ]
|
||||||
|
.ti -0.5i
|
||||||
|
\fBs\fP [ \fIn\fP ]
|
||||||
|
.br
|
||||||
Execute the next
|
Execute the next
|
||||||
.I n
|
.I n
|
||||||
source lines.
|
source lines.
|
||||||
|
@ -224,6 +241,9 @@ is taken to be 1.
|
||||||
This command steps into functions.
|
This command steps into functions.
|
||||||
.TP
|
.TP
|
||||||
\fBnext\fP [ \fIn\fP ]
|
\fBnext\fP [ \fIn\fP ]
|
||||||
|
.ti -0.5i
|
||||||
|
\fBn\fP [ \fIn\fP ]
|
||||||
|
.br
|
||||||
Execute the next
|
Execute the next
|
||||||
.I n
|
.I n
|
||||||
source lines.
|
source lines.
|
||||||
|
@ -258,12 +278,14 @@ List all, or the top
|
||||||
active functions on the stack.
|
active functions on the stack.
|
||||||
.TP
|
.TP
|
||||||
\fBfile\fP [ \fIfilename\fP ]
|
\fBfile\fP [ \fIfilename\fP ]
|
||||||
.br
|
|
||||||
Print the name of the current source file, or
|
Print the name of the current source file, or
|
||||||
change the current source file to
|
change the current source file to
|
||||||
.IR filename .
|
.IR filename .
|
||||||
.TP
|
.TP
|
||||||
\fBlist\fP [ \fIstartline\fP [ , \fIendline\fP ] | \fIfunction\fP ]
|
\fBlist\fP [ \fIstartline\fP [ , \fIendline\fP ] | \fIfunction\fP ]
|
||||||
|
.ti -0.5i
|
||||||
|
\fBl\fP [ \fIstartline\fP [ , \fIendline\fP ] | \fIfunction\fP ]
|
||||||
|
.br
|
||||||
If no arguments are given, list the next ten lines from current source file,
|
If no arguments are given, list the next ten lines from current source file,
|
||||||
if a
|
if a
|
||||||
.I startline
|
.I startline
|
||||||
|
@ -279,15 +301,20 @@ the first statement of
|
||||||
.B quit
|
.B quit
|
||||||
Exit
|
Exit
|
||||||
.BR grind .
|
.BR grind .
|
||||||
|
.LP
|
||||||
|
Some commands can be repeated by entering an empty command line: step,
|
||||||
|
next, print, list, status, cont.
|
||||||
.SH ENVIRONMENT
|
.SH ENVIRONMENT
|
||||||
P.M.
|
P.M.
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR ack (1ACK).
|
.IR ack (1ACK).
|
||||||
.BR led (6ACK).
|
.IR led (6ACK).
|
||||||
|
.SH REMARKS
|
||||||
|
.LP
|
||||||
|
.B Grind
|
||||||
|
does not understand the scope of WITH statements. The scope information needed
|
||||||
|
is not available in the symbol table.
|
||||||
.SH BUGS
|
.SH BUGS
|
||||||
.LP
|
.LP
|
||||||
.B Grind
|
.B Grind
|
||||||
does not correctly handle bit-fields.
|
does not correctly handle bit-fields.
|
||||||
.LP
|
|
||||||
.B Grind
|
|
||||||
does not understand WITH statements.
|
|
||||||
|
|
|
@ -54,18 +54,6 @@ open_file(fn, mode, ffn)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define window_size 21
|
|
||||||
/* Print a window of window_size lines around line "line" of
|
|
||||||
file "file".
|
|
||||||
*/
|
|
||||||
window(file, line)
|
|
||||||
p_file file;
|
|
||||||
int line;
|
|
||||||
{
|
|
||||||
lines(file,
|
|
||||||
line + ((window_size >> 1) - window_size), line + (window_size >> 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
lines(file, l1, l2)
|
lines(file, l1, l2)
|
||||||
register p_file file;
|
register p_file file;
|
||||||
int l1, l2;
|
int l1, l2;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "symbol.h"
|
#include "symbol.h"
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
|
#include "Lpars.h"
|
||||||
|
|
||||||
static char *usage = "Usage: %s [<ack.out>] [<a.out>]";
|
static char *usage = "Usage: %s [<ack.out>] [<a.out>]";
|
||||||
static char *progname;
|
static char *progname;
|
||||||
|
@ -18,6 +19,18 @@ int debug;
|
||||||
extern struct tokenname tkidf[];
|
extern struct tokenname tkidf[];
|
||||||
extern char *strindex();
|
extern char *strindex();
|
||||||
|
|
||||||
|
static struct tokenname shorts[] = {
|
||||||
|
{LIST, "l"},
|
||||||
|
{CONT, "c"},
|
||||||
|
{STEP, "s"},
|
||||||
|
{NEXT, "n"},
|
||||||
|
{DELETE, "d"},
|
||||||
|
{PRINT, "p"},
|
||||||
|
{RESTORE, "r"},
|
||||||
|
{TRACE, "t"},
|
||||||
|
{ 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
main(argc, argv)
|
main(argc, argv)
|
||||||
char *argv[];
|
char *argv[];
|
||||||
{
|
{
|
||||||
|
@ -52,6 +65,7 @@ main(argc, argv)
|
||||||
if (DbxRead(AckObj) && AObj == 0) AObj = AckObj;
|
if (DbxRead(AckObj) && AObj == 0) AObj = AckObj;
|
||||||
else if (AObj == 0) AObj = "a.out";
|
else if (AObj == 0) AObj = "a.out";
|
||||||
reserve(tkidf);
|
reserve(tkidf);
|
||||||
|
reserve(shorts);
|
||||||
if (currfile) CurrentScope = currfile->sy_file->f_scope;
|
if (currfile) CurrentScope = currfile->sy_file->f_scope;
|
||||||
if (! init_run()) {
|
if (! init_run()) {
|
||||||
fatal("something wrong with file descriptors");
|
fatal("something wrong with file descriptors");
|
||||||
|
|
|
@ -3,4 +3,4 @@ sed '
|
||||||
s/.*{//
|
s/.*{//
|
||||||
s/,.*//
|
s/,.*//
|
||||||
s/.*/%token &;/
|
s/.*/%token &;/
|
||||||
'
|
' | sort | uniq
|
||||||
|
|
|
@ -48,12 +48,3 @@ struct message_hdr {
|
||||||
|
|
||||||
#define IN_FD 3
|
#define IN_FD 3
|
||||||
#define OUT_FD 6
|
#define OUT_FD 6
|
||||||
|
|
||||||
#define BUFTOL(c) (*((long *) (c)))
|
|
||||||
#define LTOBUF(c,l) (*((long *) (c)) = (l))
|
|
||||||
#define BUFTOA(c) (*((char **) (c)))
|
|
||||||
#define ATOBUF(c,p) (*((char **) (c)) = (p))
|
|
||||||
#define BUFTOS(c) (*((short *) (c)))
|
|
||||||
#define BUFTOI(c) (*((int *) (c)))
|
|
||||||
#define BUFTOF(c) (*((float *) (c)))
|
|
||||||
#define BUFTOD(c) (*((double *) (c)))
|
|
||||||
|
|
|
@ -36,35 +36,6 @@ get_map_from_addr(t)
|
||||||
return oldp ? oldp : p->f_start->on_valu <= t ? p : 0;
|
return oldp ? oldp : p->f_start->on_valu <= t ? p : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* extern char *get_filename_from_addr(t_addr t);
|
|
||||||
Returns the source filename that contains the code at the address 't',
|
|
||||||
or 0 if there is no information available, or 't' represents an address
|
|
||||||
below the start address of the first file.
|
|
||||||
*/
|
|
||||||
char *
|
|
||||||
get_filename_from_addr(t)
|
|
||||||
t_addr t;
|
|
||||||
{
|
|
||||||
register p_file map = get_map_from_addr(t);
|
|
||||||
|
|
||||||
if (! map) return 0;
|
|
||||||
return map->f_sym->sy_idf->id_text;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* extern t_lineno get_lineno_from_addr(t_addr t);
|
|
||||||
Returns the source line number of the line that contains the code at address
|
|
||||||
't'. 0 is returned if no source line number could be found.
|
|
||||||
*/
|
|
||||||
t_lineno
|
|
||||||
get_lineno_from_addr(t)
|
|
||||||
t_addr t;
|
|
||||||
{
|
|
||||||
p_position p;
|
|
||||||
|
|
||||||
p = get_position_from_addr(t);
|
|
||||||
return p == 0 ? 0 : p->lineno;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* extern p_position get_position_from_addr(t_addr t);
|
/* extern p_position get_position_from_addr(t_addr t);
|
||||||
Returns a pointer to a structure containing the source position of the code
|
Returns a pointer to a structure containing the source position of the code
|
||||||
at address 't'. 0 is returned if no source position could be found.
|
at address 't'. 0 is returned if no source position could be found.
|
||||||
|
@ -161,21 +132,6 @@ add_position_addr(filename, n)
|
||||||
map->f_line_addr[HASH(n->on_desc)] = n;
|
map->f_line_addr[HASH(n->on_desc)] = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* extern struct scope *get_scope_from_position(p_position p);
|
|
||||||
Returns the scope of the code at position 'p', or 0 if it could not be found.
|
|
||||||
*/
|
|
||||||
struct scope *
|
|
||||||
get_scope_from_position(p)
|
|
||||||
p_position p;
|
|
||||||
{
|
|
||||||
t_addr a = get_addr_from_position(p);
|
|
||||||
|
|
||||||
if (a != ILL_ADDR) {
|
|
||||||
return get_scope_from_addr(a);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* extern p_position print_position(t_addr a, int print_function);
|
/* extern p_position print_position(t_addr a, int print_function);
|
||||||
Prints position 'a' and returns it. If 'print_function' is set,
|
Prints position 'a' and returns it. If 'print_function' is set,
|
||||||
an attempt is made to print the function name as well.
|
an attempt is made to print the function name as well.
|
||||||
|
|
|
@ -14,19 +14,6 @@ typedef struct pos {
|
||||||
char *filename;
|
char *filename;
|
||||||
} t_position, *p_position;
|
} t_position, *p_position;
|
||||||
|
|
||||||
/* extern char *get_filename_from_addr(t_addr t);
|
|
||||||
Returns the source filename that contains the code at the address 't',
|
|
||||||
or 0 if there is no information available, or 't' represents an address
|
|
||||||
below the start address of the first file.
|
|
||||||
*/
|
|
||||||
extern char *get_filename_from_addr();
|
|
||||||
|
|
||||||
/* extern t_lineno get_lineno_from_addr(t_addr t);
|
|
||||||
Returns the source line number of the line that contains the code at address
|
|
||||||
't'. 0 is returned if no source line number could be found.
|
|
||||||
*/
|
|
||||||
extern t_lineno get_lineno_from_addr();
|
|
||||||
|
|
||||||
/* extern p_position get_position_from_addr(t_addr t);
|
/* extern p_position get_position_from_addr(t_addr t);
|
||||||
Returns a pointer to a structure containing the source position of the code
|
Returns a pointer to a structure containing the source position of the code
|
||||||
at address 't'. 0 is returned if no source position could be found.
|
at address 't'. 0 is returned if no source position could be found.
|
||||||
|
@ -45,11 +32,6 @@ extern t_addr get_addr_from_position();
|
||||||
*/
|
*/
|
||||||
extern add_position_addr();
|
extern add_position_addr();
|
||||||
|
|
||||||
/* extern struct scope *get_scope_from_position(p_position p);
|
|
||||||
Returns the scope of the code at position 'p', or 0 if it could not be found.
|
|
||||||
*/
|
|
||||||
extern struct scope *get_scope_from_position();
|
|
||||||
|
|
||||||
/* extern p_position print_position(t_addr a, int print_function);
|
/* extern p_position print_position(t_addr a, int print_function);
|
||||||
Prints position 'a' and returns it. If 'print_function' is set,
|
Prints position 'a' and returns it. If 'print_function' is set,
|
||||||
an attempt is made to print the function name as well.
|
an attempt is made to print the function name as well.
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "symbol.h"
|
#include "symbol.h"
|
||||||
#include "position.h"
|
#include "position.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
|
#include "expr.h"
|
||||||
|
|
||||||
extern FILE *db_out;
|
extern FILE *db_out;
|
||||||
extern long float_size, pointer_size, int_size;
|
extern long float_size, pointer_size, int_size;
|
||||||
|
@ -18,7 +19,7 @@ extern long float_size, pointer_size, int_size;
|
||||||
static
|
static
|
||||||
print_literal(tp, v)
|
print_literal(tp, v)
|
||||||
p_type tp;
|
p_type tp;
|
||||||
int v;
|
long v;
|
||||||
{
|
{
|
||||||
register struct literal *lit = tp->ty_literals;
|
register struct literal *lit = tp->ty_literals;
|
||||||
register int i;
|
register int i;
|
||||||
|
@ -75,7 +76,11 @@ print_params(tp, AB, static_link)
|
||||||
par = tp->ty_params;
|
par = tp->ty_params;
|
||||||
size = tp->ty_nbparams;
|
size = tp->ty_nbparams;
|
||||||
if (static_link) size += pointer_size;
|
if (static_link) size += pointer_size;
|
||||||
param_bytes = p = Malloc((unsigned)size);
|
param_bytes = p = malloc((unsigned)size);
|
||||||
|
if (! p) {
|
||||||
|
error("could not allocate enough memory");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (static_link) p += pointer_size;
|
if (static_link) p += pointer_size;
|
||||||
if (! get_bytes(size, AB, param_bytes)) {
|
if (! get_bytes(size, AB, param_bytes)) {
|
||||||
error("no debuggee");
|
error("no debuggee");
|
||||||
|
@ -90,13 +95,19 @@ print_params(tp, AB, static_link)
|
||||||
try and get value.
|
try and get value.
|
||||||
*/
|
*/
|
||||||
char *q;
|
char *q;
|
||||||
|
t_addr addr = get_int(p, pointer_size, T_UNSIGNED);
|
||||||
|
|
||||||
if ((size = par->par_type->ty_size) == 0) {
|
if ((size = par->par_type->ty_size) == 0) {
|
||||||
size = compute_size(par->par_type, param_bytes);
|
size = compute_size(par->par_type, param_bytes);
|
||||||
}
|
}
|
||||||
q = Malloc((unsigned) size);
|
q = malloc((unsigned) size);
|
||||||
if (! get_bytes(size, (t_addr) BUFTOA(p), q)) {
|
if (! q) {
|
||||||
fprintf(db_out, currlang->addr_fmt, BUFTOA(p));
|
error("could not allocate enough memory");
|
||||||
|
free(param_bytes);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (! get_bytes(size, addr, q)) {
|
||||||
|
fprintf(db_out, currlang->addr_fmt, (long) addr);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
print_val(par->par_type, size, q, 1, 0);
|
print_val(par->par_type, size, q, 1, 0);
|
||||||
|
@ -176,7 +187,7 @@ print_val(tp, tp_sz, addr, compressed, indent)
|
||||||
for (i = tp->ty_nfields; i; i--, fld++) {
|
for (i = tp->ty_nfields; i; i--, fld++) {
|
||||||
long sz = fld->fld_type->ty_size;
|
long sz = fld->fld_type->ty_size;
|
||||||
if (! compressed) fprintf(db_out, "%s = ", fld->fld_name);
|
if (! compressed) fprintf(db_out, "%s = ", fld->fld_name);
|
||||||
if (fld->fld_bitsize < sz << 3) {
|
if (fld->fld_bitsize < (sz << 3)) {
|
||||||
/* apparently a bit field */
|
/* apparently a bit field */
|
||||||
/* ??? */
|
/* ??? */
|
||||||
fprintf(db_out, "<bitfield, %d, %ld>", fld->fld_bitsize, sz);
|
fprintf(db_out, "<bitfield, %d, %ld>", fld->fld_bitsize, sz);
|
||||||
|
@ -199,14 +210,10 @@ print_val(tp, tp_sz, addr, compressed, indent)
|
||||||
fprintf(db_out, "<union>");
|
fprintf(db_out, "<union>");
|
||||||
break;
|
break;
|
||||||
case T_ENUM:
|
case T_ENUM:
|
||||||
print_literal(tp, tp_sz == 1
|
print_literal(tp, get_int(addr, tp_sz, T_ENUM));
|
||||||
? (*addr & 0xFF)
|
|
||||||
: tp_sz == 2
|
|
||||||
? (BUFTOS(addr) & 0xFFFF)
|
|
||||||
: (int) BUFTOL(addr));
|
|
||||||
break;
|
break;
|
||||||
case T_PROCEDURE: {
|
case T_PROCEDURE: {
|
||||||
register p_scope sc = get_scope_from_addr((t_addr) BUFTOA(addr));
|
register p_scope sc = get_scope_from_addr((t_addr) get_int(addr, pointer_size, T_UNSIGNED));
|
||||||
|
|
||||||
if (sc && sc->sc_definedby) {
|
if (sc && sc->sc_definedby) {
|
||||||
fprintf(db_out, sc->sc_definedby->sy_idf->id_text);
|
fprintf(db_out, sc->sc_definedby->sy_idf->id_text);
|
||||||
|
@ -215,7 +222,7 @@ print_val(tp, tp_sz, addr, compressed, indent)
|
||||||
}
|
}
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
case T_POINTER:
|
case T_POINTER:
|
||||||
fprintf(db_out, currlang->addr_fmt, (long) BUFTOA(addr));
|
fprintf(db_out, currlang->addr_fmt, get_int(addr, pointer_size, T_UNSIGNED));
|
||||||
break;
|
break;
|
||||||
case T_FILE:
|
case T_FILE:
|
||||||
fprintf(db_out, "<file>");
|
fprintf(db_out, "<file>");
|
||||||
|
@ -226,7 +233,7 @@ print_val(tp, tp_sz, addr, compressed, indent)
|
||||||
long nelements = tp->ty_size << 3;
|
long nelements = tp->ty_size << 3;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int rsft = 3 + (int_size == 2 ? 1 : 2);
|
int rsft = 3 + (int_size == 2 ? 1 : 2);
|
||||||
long mask = int_size == 2 ? 0xFFFF : 0xFFFFFFFF;
|
long mask = int_size == 2 ? 017: 037;
|
||||||
|
|
||||||
if (base->ty_class == T_SUBRANGE) base = base->ty_base;
|
if (base->ty_class == T_SUBRANGE) base = base->ty_base;
|
||||||
if (compressed) {
|
if (compressed) {
|
||||||
|
@ -241,7 +248,7 @@ print_val(tp, tp_sz, addr, compressed, indent)
|
||||||
}
|
}
|
||||||
indent += 4;
|
indent += 4;
|
||||||
for (i = 0; i < nelements; i++) {
|
for (i = 0; i < nelements; i++) {
|
||||||
if (*((int *) addr + (i >> rsft)) & (1 << (i & mask))) {
|
if (get_int(addr + (i >> rsft), int_size, T_UNSIGNED) & (1 << (i & mask))) {
|
||||||
count++;
|
count++;
|
||||||
if (count > 1) {
|
if (count > 1) {
|
||||||
if (compressed) {
|
if (compressed) {
|
||||||
|
@ -258,7 +265,7 @@ print_val(tp, tp_sz, addr, compressed, indent)
|
||||||
print_unsigned(base, val+i);
|
print_unsigned(base, val+i);
|
||||||
break;
|
break;
|
||||||
case T_ENUM:
|
case T_ENUM:
|
||||||
print_literal(base, (int)val+i);
|
print_literal(base, val+i);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
|
@ -272,26 +279,14 @@ print_val(tp, tp_sz, addr, compressed, indent)
|
||||||
fprintf(db_out, currlang->close_set_display);
|
fprintf(db_out, currlang->close_set_display);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case T_REAL: {
|
case T_REAL:
|
||||||
double val = tp->ty_size == float_size
|
fprintf(db_out, currlang->real_fmt, get_real(addr, tp->ty_size));
|
||||||
? BUFTOF(addr)
|
|
||||||
: BUFTOD(addr);
|
|
||||||
fprintf(db_out, currlang->real_fmt, val);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case T_UNSIGNED:
|
case T_UNSIGNED:
|
||||||
print_unsigned(tp, tp_sz == 1
|
print_unsigned(tp, get_int(addr, tp_sz, T_UNSIGNED));
|
||||||
? (*addr & 0xFF)
|
|
||||||
: tp_sz == 2
|
|
||||||
? (BUFTOS(addr) & 0xFFFF)
|
|
||||||
: BUFTOL(addr));
|
|
||||||
break;
|
break;
|
||||||
case T_INTEGER:
|
case T_INTEGER:
|
||||||
print_integer(tp, tp_sz == 1
|
print_integer(tp, get_int(addr, tp_sz, T_INTEGER));
|
||||||
? *addr
|
|
||||||
: tp_sz == 2
|
|
||||||
? BUFTOS(addr)
|
|
||||||
: BUFTOL(addr));
|
|
||||||
break;
|
break;
|
||||||
case T_STRING:
|
case T_STRING:
|
||||||
(*currlang->printstring)(addr, (int) tp_sz);
|
(*currlang->printstring)(addr, (int) tp_sz);
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
#include "symbol.h"
|
#include "symbol.h"
|
||||||
#include "idf.h"
|
#include "idf.h"
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
|
#include "type.h"
|
||||||
|
#include "expr.h"
|
||||||
|
|
||||||
#define MAXARG 128
|
#define MAXARG 128
|
||||||
|
|
||||||
|
@ -126,25 +128,26 @@ start_child(p)
|
||||||
/* I/O redirection */
|
/* I/O redirection */
|
||||||
if (in_redirect) {
|
if (in_redirect) {
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
close(0);
|
close(0);
|
||||||
if ((fd = open(in_redirect, 0)) < 0) {
|
if ((fd = open(in_redirect, 0)) < 0 ||
|
||||||
|
(fd != 0 && dup2(fd, 0) < 0)) {
|
||||||
error("could not open input file");
|
error("could not open input file");
|
||||||
exit(-1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (fd != 0) {
|
if (fd != 0) {
|
||||||
dup2(fd, 0);
|
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (out_redirect) {
|
if (out_redirect) {
|
||||||
int fd;
|
int fd;
|
||||||
close(1);
|
close(1);
|
||||||
if ((fd = creat(in_redirect, 0666)) < 0) {
|
if ((fd = creat(in_redirect, 0666)) < 0 ||
|
||||||
|
(fd != 1 && dup2(fd, 1) < 0)) {
|
||||||
error("could not open output file");
|
error("could not open output file");
|
||||||
exit(-1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (fd != 1) {
|
if (fd != 1) {
|
||||||
dup2(fd, 1);
|
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,7 +155,7 @@ start_child(p)
|
||||||
/* and run process to be debugged */
|
/* and run process to be debugged */
|
||||||
execv(AObj, argp);
|
execv(AObj, argp);
|
||||||
error("could not exec %s", AObj);
|
error("could not exec %s", AObj);
|
||||||
exit(-1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* debugger */
|
/* debugger */
|
||||||
|
@ -369,7 +372,7 @@ get_bytes(size, from, to)
|
||||||
|
|
||||||
m.m_type = GETBYTES;
|
m.m_type = GETBYTES;
|
||||||
m.m_size = size;
|
m.m_size = size;
|
||||||
ATOBUF(m.m_buf, (char *) from);
|
put_int(m.m_buf, pointer_size, (long)from);
|
||||||
|
|
||||||
if (! could_send(&m, 0)) {
|
if (! could_send(&m, 0)) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -394,7 +397,7 @@ set_bytes(size, from, to)
|
||||||
|
|
||||||
m.m_type = SETBYTES;
|
m.m_type = SETBYTES;
|
||||||
m.m_size = size;
|
m.m_size = size;
|
||||||
ATOBUF(m.m_buf, (char *) to);
|
put_int(m.m_buf, pointer_size, (long) to);
|
||||||
|
|
||||||
return uputm(&m)
|
return uputm(&m)
|
||||||
&& usend(from, size)
|
&& usend(from, size)
|
||||||
|
@ -428,8 +431,8 @@ get_dump(globmessage, globbuf, stackmessage, stackbuf)
|
||||||
free(*stackbuf);
|
free(*stackbuf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ATOBUF(globmessage->m_buf+SP_OFF*pointer_size,
|
put_int(globmessage->m_buf+SP_OFF*pointer_size, pointer_size,
|
||||||
BUFTOA(stackmessage->m_buf+SP_OFF*pointer_size));
|
get_int(stackmessage->m_buf+SP_OFF*pointer_size, pointer_size, T_UNSIGNED));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,11 +470,11 @@ get_EM_regs(level)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (answer.m_type == FAIL) return 0;
|
if (answer.m_type == FAIL) return 0;
|
||||||
*to++ = (t_addr) BUFTOA(answer.m_buf);
|
*to++ = (t_addr) get_int(answer.m_buf, pointer_size, T_UNSIGNED);
|
||||||
*to++ = (t_addr) BUFTOA(answer.m_buf+pointer_size);
|
*to++ = (t_addr) get_int(answer.m_buf+pointer_size, pointer_size, T_UNSIGNED);
|
||||||
*to++ = (t_addr) BUFTOA(answer.m_buf+2*pointer_size);
|
*to++ = (t_addr) get_int(answer.m_buf+2*pointer_size, pointer_size, T_UNSIGNED);
|
||||||
*to++ = (t_addr) BUFTOA(answer.m_buf+3*pointer_size);
|
*to++ = (t_addr) get_int(answer.m_buf+3*pointer_size, pointer_size, T_UNSIGNED);
|
||||||
*to++ = (t_addr) BUFTOA(answer.m_buf+4*pointer_size);
|
*to++ = (t_addr) get_int(answer.m_buf+4*pointer_size, pointer_size, T_UNSIGNED);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,7 +486,7 @@ set_pc(PC)
|
||||||
|
|
||||||
m.m_type = SETEMREGS;
|
m.m_type = SETEMREGS;
|
||||||
m.m_size = 0;
|
m.m_size = 0;
|
||||||
ATOBUF(m.m_buf+PC_OFF*pointer_size, (char *)PC);
|
put_int(m.m_buf+PC_OFF*pointer_size, pointer_size, (long)PC);
|
||||||
return could_send(&m, 0) && answer.m_type != FAIL;
|
return could_send(&m, 0) && answer.m_type != FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -540,8 +543,8 @@ set_or_clear_trace(start, end, type)
|
||||||
struct message_hdr m;
|
struct message_hdr m;
|
||||||
|
|
||||||
m.m_type = type;
|
m.m_type = type;
|
||||||
ATOBUF(m.m_buf, (char *) start);
|
put_int(m.m_buf, pointer_size, (long)start);
|
||||||
ATOBUF(m.m_buf+pointer_size, (char *) end);
|
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 (debug) printf("%s trace at [0x%lx,0x%lx]\n", type == SETTRACE ? "setting" : "clearing", (long) start, (long) end);
|
||||||
if (! could_send(&m, 0)) { }
|
if (! could_send(&m, 0)) { }
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,6 @@ extern long pointer_size;
|
||||||
extern char *strrindex();
|
extern char *strrindex();
|
||||||
|
|
||||||
p_tree run_command;
|
p_tree run_command;
|
||||||
t_lineno list_line;
|
|
||||||
|
|
||||||
|
|
||||||
/*VARARGS1*/
|
/*VARARGS1*/
|
||||||
|
@ -107,7 +106,7 @@ freenode(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
static t_addr
|
static t_addr
|
||||||
get_addr(p)
|
get_addr_from_node(p)
|
||||||
p_tree p;
|
p_tree p;
|
||||||
{
|
{
|
||||||
t_addr a = ILL_ADDR;
|
t_addr a = ILL_ADDR;
|
||||||
|
@ -132,7 +131,7 @@ get_addr(p)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OP_IN:
|
case OP_IN:
|
||||||
a = get_addr(p->t_args[0]);
|
a = get_addr_from_node(p->t_args[0]);
|
||||||
p->t_address = a;
|
p->t_address = a;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -365,7 +364,7 @@ do_list(p)
|
||||||
l2 = p->t_args[1]->t_ival;
|
l2 = p->t_args[1]->t_ival;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
t_addr a = get_addr(p->t_args[0]);
|
t_addr a = get_addr_from_node(p->t_args[0]);
|
||||||
p_position pos;
|
p_position pos;
|
||||||
|
|
||||||
if (a == ILL_ADDR) {
|
if (a == ILL_ADDR) {
|
||||||
|
@ -414,7 +413,7 @@ newfile(id)
|
||||||
do_stop(p)
|
do_stop(p)
|
||||||
p_tree p;
|
p_tree p;
|
||||||
{
|
{
|
||||||
t_addr a = get_addr(p->t_args[0]);
|
t_addr a = get_addr_from_node(p->t_args[0]);
|
||||||
|
|
||||||
if (a == ILL_ADDR) {
|
if (a == ILL_ADDR) {
|
||||||
return;
|
return;
|
||||||
|
@ -437,7 +436,7 @@ do_trace(p)
|
||||||
|
|
||||||
p->t_address = NO_ADDR;
|
p->t_address = NO_ADDR;
|
||||||
if (p->t_args[0]) {
|
if (p->t_args[0]) {
|
||||||
a = get_addr(p->t_args[0]);
|
a = get_addr_from_node(p->t_args[0]);
|
||||||
if (a == ILL_ADDR) return;
|
if (a == ILL_ADDR) return;
|
||||||
if (p->t_args[0]->t_oper == OP_AT) {
|
if (p->t_args[0]->t_oper == OP_AT) {
|
||||||
e = a;
|
e = a;
|
||||||
|
@ -569,7 +568,7 @@ do_delete(p)
|
||||||
if (p) switch(p->t_oper) {
|
if (p) switch(p->t_oper) {
|
||||||
case OP_WHEN:
|
case OP_WHEN:
|
||||||
case OP_STOP: {
|
case OP_STOP: {
|
||||||
t_addr a = get_addr(p->t_args[0]);
|
t_addr a = get_addr_from_node(p->t_args[0]);
|
||||||
|
|
||||||
if (a != ILL_ADDR && a != NO_ADDR) {
|
if (a != ILL_ADDR && a != NO_ADDR) {
|
||||||
set_or_clear_breakpoint(a, CLRBP);
|
set_or_clear_breakpoint(a, CLRBP);
|
||||||
|
@ -577,7 +576,7 @@ do_delete(p)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OP_TRACE: {
|
case OP_TRACE: {
|
||||||
t_addr a = get_addr(p->t_args[0]);
|
t_addr a = get_addr_from_node(p->t_args[0]);
|
||||||
|
|
||||||
if (a != ILL_ADDR && a != NO_ADDR) {
|
if (a != ILL_ADDR && a != NO_ADDR) {
|
||||||
t_addr e;
|
t_addr e;
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include "langdep.h"
|
#include "langdep.h"
|
||||||
|
#include "expr.h"
|
||||||
|
|
||||||
p_type int_type, char_type, short_type, long_type, bool_type;
|
p_type int_type, char_type, short_type, long_type, bool_type;
|
||||||
p_type uint_type, uchar_type, ushort_type, ulong_type;
|
p_type uint_type, uchar_type, ushort_type, ulong_type;
|
||||||
|
@ -401,11 +402,11 @@ compute_size(tp, AB)
|
||||||
assert(tp->ty_index->ty_A != 0);
|
assert(tp->ty_index->ty_A != 0);
|
||||||
|
|
||||||
if (tp->ty_index->ty_A & 1) {
|
if (tp->ty_index->ty_A & 1) {
|
||||||
low = BUFTOI(AB+tp->ty_index->ty_low);
|
low = get_int(AB+tp->ty_index->ty_low, int_size, T_INTEGER);
|
||||||
} else low = tp->ty_index->ty_low;
|
} else low = tp->ty_index->ty_low;
|
||||||
tp->ty_lb = low;
|
tp->ty_lb = low;
|
||||||
if (tp->ty_index->ty_A & 2) {
|
if (tp->ty_index->ty_A & 2) {
|
||||||
high = BUFTOI(AB+tp->ty_index->ty_up);
|
high = get_int(AB+tp->ty_index->ty_up, int_size, T_INTEGER);
|
||||||
} else high = tp->ty_index->ty_up;
|
} else high = tp->ty_index->ty_up;
|
||||||
tp->ty_hb = high;
|
tp->ty_hb = high;
|
||||||
return (high - low + 1) * tp->ty_elements->ty_size;
|
return (high - low + 1) * tp->ty_elements->ty_size;
|
||||||
|
|
|
@ -119,5 +119,5 @@ extern long
|
||||||
extern p_type char_type, uchar_type, bool_type, int_type,
|
extern p_type char_type, uchar_type, bool_type, int_type,
|
||||||
long_type, double_type, string_type;
|
long_type, double_type, string_type;
|
||||||
extern p_type void_type, incomplete_type;
|
extern p_type void_type, incomplete_type;
|
||||||
extern long int_size, pointer_size;
|
extern long int_size, pointer_size, long_size, double_size;
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
#include "message.h"
|
#include "message.h"
|
||||||
#include "langdep.h"
|
#include "langdep.h"
|
||||||
|
#include "expr.h"
|
||||||
|
|
||||||
int stack_offset; /* for up and down commands */
|
int stack_offset; /* for up and down commands */
|
||||||
|
|
||||||
|
@ -83,7 +84,11 @@ get_addr(sym, psize)
|
||||||
|
|
||||||
size = proctype->ty_nbparams;
|
size = proctype->ty_nbparams;
|
||||||
if (has_static_link(sc)) size += pointer_size;
|
if (has_static_link(sc)) size += pointer_size;
|
||||||
AB = Malloc((unsigned) size);
|
AB = malloc((unsigned) size);
|
||||||
|
if (! AB) {
|
||||||
|
error("could not allocate enough memory");
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (! get_bytes(size, EM_regs[AB_OFF], AB)) {
|
if (! get_bytes(size, EM_regs[AB_OFF], AB)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -91,7 +96,7 @@ get_addr(sym, psize)
|
||||||
size = compute_size(tp, AB);
|
size = compute_size(tp, AB);
|
||||||
*psize = size;
|
*psize = size;
|
||||||
}
|
}
|
||||||
a = (t_addr) BUFTOA(AB+sym->sy_name.nm_value);
|
a = (t_addr) get_int(AB+sym->sy_name.nm_value, pointer_size, T_UNSIGNED);
|
||||||
free(AB);
|
free(AB);
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
@ -105,7 +110,7 @@ get_addr(sym, psize)
|
||||||
Return 0 on failure,
|
Return 0 on failure,
|
||||||
1 on success.
|
1 on success.
|
||||||
On success, 'buf' contains the value, and 'size' contains the size.
|
On success, 'buf' contains the value, and 'size' contains the size.
|
||||||
For 'buf', storage is allocated by Malloc; this storage must
|
For 'buf', storage is allocated by malloc; this storage must
|
||||||
be freed by caller (I don't like this any more than you do, but caller
|
be freed by caller (I don't like this any more than you do, but caller
|
||||||
does not know sizes).
|
does not know sizes).
|
||||||
*/
|
*/
|
||||||
|
@ -123,27 +128,20 @@ get_value(sym, buf, psize)
|
||||||
*buf = 0;
|
*buf = 0;
|
||||||
switch(sym->sy_class) {
|
switch(sym->sy_class) {
|
||||||
case CONST:
|
case CONST:
|
||||||
*buf = Malloc((unsigned) size);
|
*buf = malloc((unsigned) size);
|
||||||
|
if (! *buf) {
|
||||||
|
error("could not allocate enough memory");
|
||||||
|
break;
|
||||||
|
}
|
||||||
switch(tp->ty_class) {
|
switch(tp->ty_class) {
|
||||||
case T_REAL:
|
case T_REAL:
|
||||||
if (size != sizeof(double)) {
|
put_real(*buf, size, sym->sy_const.co_rval);
|
||||||
*((float *) *buf) = sym->sy_const.co_rval;
|
|
||||||
}
|
|
||||||
else *((double *) *buf) = sym->sy_const.co_rval;
|
|
||||||
break;
|
break;
|
||||||
case T_INTEGER:
|
case T_INTEGER:
|
||||||
case T_SUBRANGE:
|
case T_SUBRANGE:
|
||||||
case T_UNSIGNED:
|
case T_UNSIGNED:
|
||||||
case T_ENUM:
|
case T_ENUM:
|
||||||
if (size == sizeof(char)) {
|
put_int(*buf, size, sym->sy_const.co_ival);
|
||||||
*((char *) *buf) = sym->sy_const.co_ival;
|
|
||||||
}
|
|
||||||
else if (size == sizeof(short)) {
|
|
||||||
*((short *) *buf) = sym->sy_const.co_ival;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
*((long *) *buf) = sym->sy_const.co_ival;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case T_SET:
|
case T_SET:
|
||||||
memcpy(*buf, sym->sy_const.co_setval, (int) size);
|
memcpy(*buf, sym->sy_const.co_setval, (int) size);
|
||||||
|
@ -162,7 +160,11 @@ get_value(sym, buf, psize)
|
||||||
a = get_addr(sym, psize);
|
a = get_addr(sym, psize);
|
||||||
if (a) {
|
if (a) {
|
||||||
size = *psize;
|
size = *psize;
|
||||||
*buf = Malloc((unsigned) size);
|
*buf = malloc((unsigned) size);
|
||||||
|
if (! *buf) {
|
||||||
|
error("Could not allocate enough memory");
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (get_bytes(size, a, *buf)) {
|
if (get_bytes(size, a, *buf)) {
|
||||||
retval = 1;
|
retval = 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue