Many more changes
This commit is contained in:
parent
1ade1b814d
commit
1f408a38c2
|
@ -13,7 +13,6 @@
|
|||
#include "scope.h"
|
||||
#include "rd.h"
|
||||
|
||||
extern char *Malloc();
|
||||
extern char *strindex();
|
||||
extern struct outname *DbxString();
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include "position.h"
|
||||
#include "tree.h"
|
||||
#include "message.h"
|
||||
#include "type.h"
|
||||
#include "expr.h"
|
||||
|
||||
extern long pointer_size;
|
||||
extern p_tree get_from_item_list();
|
||||
|
@ -29,7 +31,7 @@ do_dump(p)
|
|||
return;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* $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)
|
||||
This routine evaluates the conditional expression indicated by p
|
||||
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
|
||||
the resulting value, type and size are left in pbuf, ptp, and
|
||||
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>
|
||||
|
@ -41,10 +52,16 @@
|
|||
#include "langdep.h"
|
||||
|
||||
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 */
|
||||
|
||||
static long
|
||||
long
|
||||
get_int(buf, size, class)
|
||||
char *buf;
|
||||
long size;
|
||||
|
@ -68,7 +85,6 @@ get_int(buf, size, class)
|
|||
return l;
|
||||
}
|
||||
|
||||
static
|
||||
put_int(buf, size, value)
|
||||
char *buf;
|
||||
long size;
|
||||
|
@ -90,7 +106,7 @@ put_int(buf, size, value)
|
|||
|
||||
/* buffer to real and vice versa routines */
|
||||
|
||||
static double
|
||||
double
|
||||
get_real(buf, size)
|
||||
char *buf;
|
||||
long size;
|
||||
|
@ -104,7 +120,6 @@ get_real(buf, size)
|
|||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
static
|
||||
put_real(buf, size, value)
|
||||
char *buf;
|
||||
long size;
|
||||
|
@ -138,7 +153,8 @@ convert(pbuf, psize, ptp, tp, size)
|
|||
|
||||
if (*ptp == tp) return 1;
|
||||
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;
|
||||
switch((*ptp)->ty_class) {
|
||||
|
@ -298,7 +314,8 @@ do_deref(p, pbuf, psize, ptp)
|
|||
t_addr addr;
|
||||
|
||||
if (ptr_addr(p, &addr, psize, ptp)) {
|
||||
*pbuf = Malloc((unsigned) *psize);
|
||||
*pbuf = malloc((unsigned) *psize);
|
||||
malloc_succeeded(*pbuf);
|
||||
if (! get_bytes(*psize, addr, *pbuf)) {
|
||||
error("could not get value");
|
||||
}
|
||||
|
@ -317,7 +334,8 @@ do_addr(p, pbuf, psize, ptp)
|
|||
t_addr addr;
|
||||
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
|
@ -780,8 +798,8 @@ do_cmp(p, pbuf, psize, ptp)
|
|||
}
|
||||
if (*psize < int_size) {
|
||||
*psize = int_size;
|
||||
free(*pbuf);
|
||||
*pbuf = Malloc((unsigned int) int_size);
|
||||
*pbuf = realloc(*pbuf, (unsigned int) int_size);
|
||||
malloc_succeeded(*pbuf);
|
||||
}
|
||||
else *psize = int_size;
|
||||
if (currlang->has_bool_type) {
|
||||
|
@ -824,7 +842,8 @@ do_in(p, pbuf, psize, ptp)
|
|||
&& l <= (size << 3)
|
||||
&& (((int *) buf)[(int)(l>>sft)] & (1 << (l & ((1 << sft)-1))));
|
||||
free(buf);
|
||||
*pbuf = Realloc(*pbuf, (unsigned) int_size);
|
||||
*pbuf = realloc(*pbuf, (unsigned) int_size);
|
||||
malloc_succeeded(*pbuf);
|
||||
*psize = int_size;
|
||||
*ptp = currlang->has_bool_type ? bool_type : int_type;
|
||||
put_int(*pbuf, *psize, l);
|
||||
|
@ -889,7 +908,8 @@ do_array(p, pbuf, psize, ptp)
|
|||
t_addr a;
|
||||
|
||||
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)) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -945,7 +965,8 @@ do_select(p, pbuf, psize, ptp)
|
|||
{
|
||||
t_addr a;
|
||||
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)) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -1011,26 +1032,29 @@ eval_expr(p, pbuf, psize, ptp)
|
|||
break;
|
||||
|
||||
case OP_INTEGER:
|
||||
*pbuf = Malloc(sizeof(long));
|
||||
*psize = sizeof(long);
|
||||
*pbuf = malloc((unsigned int) long_size);
|
||||
malloc_succeeded(*pbuf);
|
||||
*psize = long_size;
|
||||
*ptp = long_type;
|
||||
*((long *) (*pbuf)) = p->t_ival;
|
||||
put_int(*pbuf, long_size, p->t_ival);
|
||||
retval = 1;
|
||||
break;
|
||||
|
||||
case OP_REAL:
|
||||
*pbuf = Malloc(sizeof(double));
|
||||
*psize = sizeof(double);
|
||||
*pbuf = malloc((unsigned int) double_size);
|
||||
malloc_succeeded(*pbuf);
|
||||
*psize = double_size;
|
||||
*ptp = double_type;
|
||||
*((double *) (*pbuf)) = p->t_fval;
|
||||
put_real(*pbuf, double_size, p->t_fval);
|
||||
retval = 1;
|
||||
break;
|
||||
|
||||
case OP_STRING:
|
||||
*pbuf = Malloc(sizeof(char *));
|
||||
*psize = sizeof(char *);
|
||||
*psize = strlen(p->t_sval)+1;
|
||||
*pbuf = malloc((unsigned int)*psize);
|
||||
malloc_succeeded(*pbuf);
|
||||
*ptp = string_type;
|
||||
*((char **) (*pbuf)) = p->t_sval;
|
||||
strcpy(*pbuf, p->t_sval);
|
||||
retval = 1;
|
||||
break;
|
||||
|
||||
|
|
|
@ -34,3 +34,62 @@
|
|||
#define E_LSFT 26
|
||||
#define E_RSFT 27
|
||||
#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
|
||||
.B Grind
|
||||
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
|
||||
.IR dbx ,
|
||||
a source-level debugger
|
||||
available on many Unix systems. However, some
|
||||
.B Grind
|
||||
.B grind
|
||||
commands are not available in
|
||||
.IR dbx ,
|
||||
and some more
|
||||
some more
|
||||
.I dbx
|
||||
commands are not available in
|
||||
.BR grind ,
|
||||
|
@ -48,8 +48,8 @@ Some
|
|||
.B grind
|
||||
commands take an expression argument.
|
||||
.SS Expressions
|
||||
.B Grind expressions
|
||||
are combinations of variables, constants, and operators.
|
||||
.B Grind
|
||||
expressions are combinations of variables, constants, and operators.
|
||||
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
|
||||
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
|
||||
.BR grind ,
|
||||
the conversions needed are performed automatically.
|
||||
Expressions cannot involve strings, structures, or
|
||||
arrays, although elements of structures or arrays may be used.
|
||||
.SS Operators
|
||||
.LP
|
||||
.B Grind
|
||||
|
@ -72,19 +70,19 @@ The syntax and priority of these operators depends on the source language.
|
|||
Parentheses can be used for grouping.
|
||||
.SS "Scope Rules"
|
||||
.LP
|
||||
.B dbx
|
||||
.B Grind
|
||||
uses the current file and function to resolve scope conflicts.
|
||||
Their values are updated as files and functions are entered and exited
|
||||
during execution.
|
||||
Names can also be qualified with procedure- or module names, as in
|
||||
\fImodule\fP`\fIproc\fP`\fIname\fP.
|
||||
.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
|
||||
does not help.
|
||||
.SS "Positions"
|
||||
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
|
||||
\fBat\fP [ "\fIfilename\fP": ] \fIlinenumber\fP
|
||||
.RE
|
||||
|
@ -99,7 +97,7 @@ This indicates the first statement within the named function (except for
|
|||
the trace command discussed later).
|
||||
.SS "Commands"
|
||||
.TP
|
||||
.B \s+2^\s0C
|
||||
.B ^C
|
||||
Interrupt. Stop the program being debugged and enter
|
||||
.BR grind .
|
||||
.TP
|
||||
|
@ -114,11 +112,18 @@ and possible redirection of standard input and/or standard output.
|
|||
Repeats the last
|
||||
.B run
|
||||
command.
|
||||
.TP
|
||||
\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
|
||||
given, at that source line.
|
||||
.TP
|
||||
\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.
|
||||
If no argument is specified, each source line is displayed before
|
||||
execution.
|
||||
|
@ -167,10 +172,13 @@ If no condition is given, stop when
|
|||
is reached.
|
||||
Either a position or a condition (or both) must be given.
|
||||
.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.
|
||||
.TP
|
||||
\fBdisplay\fP \fIexpression\fP [ ',' \fIexpression\fP ] ...
|
||||
\fBdisplay\fP \fIexpression\fP [ , \fIexpression\fP ] ...
|
||||
Print the value of each expression whenever the program stops.
|
||||
.TP
|
||||
.B dump
|
||||
|
@ -197,11 +205,17 @@ Also display current
|
|||
records.
|
||||
.TP
|
||||
\fBdelete\fP \fIcommandnumber\fP
|
||||
.ti -0.5i
|
||||
\fBd\fP \fIcommandnumber\fP
|
||||
.br
|
||||
Remove the command corresponding to \fIcommandnumber\fP
|
||||
(as displayed by
|
||||
.BR status ).
|
||||
.TP
|
||||
\fBrestore\fP \fIcommandnumber\fP
|
||||
.ti -0.5i
|
||||
\fBr\fP \fIcommandnumber\fP
|
||||
.br
|
||||
Restore the data corresponding to the dump of \fIcommandnumber\fP
|
||||
(as displayed by
|
||||
.BR status ).
|
||||
|
@ -215,6 +229,9 @@ Apart from this,
|
|||
even works when the program is finished.
|
||||
.TP
|
||||
\fBstep\fP [ \fIn\fP ]
|
||||
.ti -0.5i
|
||||
\fBs\fP [ \fIn\fP ]
|
||||
.br
|
||||
Execute the next
|
||||
.I n
|
||||
source lines.
|
||||
|
@ -224,6 +241,9 @@ is taken to be 1.
|
|||
This command steps into functions.
|
||||
.TP
|
||||
\fBnext\fP [ \fIn\fP ]
|
||||
.ti -0.5i
|
||||
\fBn\fP [ \fIn\fP ]
|
||||
.br
|
||||
Execute the next
|
||||
.I n
|
||||
source lines.
|
||||
|
@ -258,12 +278,14 @@ List all, or the top
|
|||
active functions on the stack.
|
||||
.TP
|
||||
\fBfile\fP [ \fIfilename\fP ]
|
||||
.br
|
||||
Print the name of the current source file, or
|
||||
change the current source file to
|
||||
.IR filename .
|
||||
.TP
|
||||
\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 a
|
||||
.I startline
|
||||
|
@ -279,15 +301,20 @@ the first statement of
|
|||
.B quit
|
||||
Exit
|
||||
.BR grind .
|
||||
.LP
|
||||
Some commands can be repeated by entering an empty command line: step,
|
||||
next, print, list, status, cont.
|
||||
.SH ENVIRONMENT
|
||||
P.M.
|
||||
.SH SEE ALSO
|
||||
.BR ack (1ACK).
|
||||
.BR led (6ACK).
|
||||
.IR ack (1ACK).
|
||||
.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
|
||||
.LP
|
||||
.B Grind
|
||||
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;
|
||||
}
|
||||
|
||||
#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)
|
||||
register p_file file;
|
||||
int l1, l2;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "file.h"
|
||||
#include "symbol.h"
|
||||
#include "scope.h"
|
||||
#include "Lpars.h"
|
||||
|
||||
static char *usage = "Usage: %s [<ack.out>] [<a.out>]";
|
||||
static char *progname;
|
||||
|
@ -18,6 +19,18 @@ int debug;
|
|||
extern struct tokenname tkidf[];
|
||||
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)
|
||||
char *argv[];
|
||||
{
|
||||
|
@ -52,6 +65,7 @@ main(argc, argv)
|
|||
if (DbxRead(AckObj) && AObj == 0) AObj = AckObj;
|
||||
else if (AObj == 0) AObj = "a.out";
|
||||
reserve(tkidf);
|
||||
reserve(shorts);
|
||||
if (currfile) CurrentScope = currfile->sy_file->f_scope;
|
||||
if (! init_run()) {
|
||||
fatal("something wrong with file descriptors");
|
||||
|
|
|
@ -3,4 +3,4 @@ sed '
|
|||
s/.*{//
|
||||
s/,.*//
|
||||
s/.*/%token &;/
|
||||
'
|
||||
' | sort | uniq
|
||||
|
|
|
@ -48,12 +48,3 @@ struct message_hdr {
|
|||
|
||||
#define IN_FD 3
|
||||
#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;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
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.
|
||||
|
@ -161,21 +132,6 @@ add_position_addr(filename, 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);
|
||||
Prints position 'a' and returns it. If 'print_function' is set,
|
||||
an attempt is made to print the function name as well.
|
||||
|
|
|
@ -14,19 +14,6 @@ typedef struct pos {
|
|||
char *filename;
|
||||
} 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);
|
||||
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.
|
||||
|
@ -45,11 +32,6 @@ extern t_addr get_addr_from_position();
|
|||
*/
|
||||
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);
|
||||
Prints position 'a' and returns it. If 'print_function' is set,
|
||||
an attempt is made to print the function name as well.
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "symbol.h"
|
||||
#include "position.h"
|
||||
#include "idf.h"
|
||||
#include "expr.h"
|
||||
|
||||
extern FILE *db_out;
|
||||
extern long float_size, pointer_size, int_size;
|
||||
|
@ -18,7 +19,7 @@ extern long float_size, pointer_size, int_size;
|
|||
static
|
||||
print_literal(tp, v)
|
||||
p_type tp;
|
||||
int v;
|
||||
long v;
|
||||
{
|
||||
register struct literal *lit = tp->ty_literals;
|
||||
register int i;
|
||||
|
@ -75,7 +76,11 @@ print_params(tp, AB, static_link)
|
|||
par = tp->ty_params;
|
||||
size = tp->ty_nbparams;
|
||||
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 (! get_bytes(size, AB, param_bytes)) {
|
||||
error("no debuggee");
|
||||
|
@ -90,13 +95,19 @@ print_params(tp, AB, static_link)
|
|||
try and get value.
|
||||
*/
|
||||
char *q;
|
||||
t_addr addr = get_int(p, pointer_size, T_UNSIGNED);
|
||||
|
||||
if ((size = par->par_type->ty_size) == 0) {
|
||||
size = compute_size(par->par_type, param_bytes);
|
||||
}
|
||||
q = Malloc((unsigned) size);
|
||||
if (! get_bytes(size, (t_addr) BUFTOA(p), q)) {
|
||||
fprintf(db_out, currlang->addr_fmt, BUFTOA(p));
|
||||
q = malloc((unsigned) size);
|
||||
if (! q) {
|
||||
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 {
|
||||
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++) {
|
||||
long sz = fld->fld_type->ty_size;
|
||||
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 */
|
||||
/* ??? */
|
||||
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>");
|
||||
break;
|
||||
case T_ENUM:
|
||||
print_literal(tp, tp_sz == 1
|
||||
? (*addr & 0xFF)
|
||||
: tp_sz == 2
|
||||
? (BUFTOS(addr) & 0xFFFF)
|
||||
: (int) BUFTOL(addr));
|
||||
print_literal(tp, get_int(addr, tp_sz, T_ENUM));
|
||||
break;
|
||||
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) {
|
||||
fprintf(db_out, sc->sc_definedby->sy_idf->id_text);
|
||||
|
@ -215,7 +222,7 @@ print_val(tp, tp_sz, addr, compressed, indent)
|
|||
}
|
||||
/* Fall through */
|
||||
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;
|
||||
case T_FILE:
|
||||
fprintf(db_out, "<file>");
|
||||
|
@ -226,7 +233,7 @@ print_val(tp, tp_sz, addr, compressed, indent)
|
|||
long nelements = tp->ty_size << 3;
|
||||
int count = 0;
|
||||
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 (compressed) {
|
||||
|
@ -241,7 +248,7 @@ print_val(tp, tp_sz, addr, compressed, indent)
|
|||
}
|
||||
indent += 4;
|
||||
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++;
|
||||
if (count > 1) {
|
||||
if (compressed) {
|
||||
|
@ -258,7 +265,7 @@ print_val(tp, tp_sz, addr, compressed, indent)
|
|||
print_unsigned(base, val+i);
|
||||
break;
|
||||
case T_ENUM:
|
||||
print_literal(base, (int)val+i);
|
||||
print_literal(base, val+i);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
|
@ -272,26 +279,14 @@ print_val(tp, tp_sz, addr, compressed, indent)
|
|||
fprintf(db_out, currlang->close_set_display);
|
||||
}
|
||||
break;
|
||||
case T_REAL: {
|
||||
double val = tp->ty_size == float_size
|
||||
? BUFTOF(addr)
|
||||
: BUFTOD(addr);
|
||||
fprintf(db_out, currlang->real_fmt, val);
|
||||
case T_REAL:
|
||||
fprintf(db_out, currlang->real_fmt, get_real(addr, tp->ty_size));
|
||||
break;
|
||||
}
|
||||
case T_UNSIGNED:
|
||||
print_unsigned(tp, tp_sz == 1
|
||||
? (*addr & 0xFF)
|
||||
: tp_sz == 2
|
||||
? (BUFTOS(addr) & 0xFFFF)
|
||||
: BUFTOL(addr));
|
||||
print_unsigned(tp, get_int(addr, tp_sz, T_UNSIGNED));
|
||||
break;
|
||||
case T_INTEGER:
|
||||
print_integer(tp, tp_sz == 1
|
||||
? *addr
|
||||
: tp_sz == 2
|
||||
? BUFTOS(addr)
|
||||
: BUFTOL(addr));
|
||||
print_integer(tp, get_int(addr, tp_sz, T_INTEGER));
|
||||
break;
|
||||
case T_STRING:
|
||||
(*currlang->printstring)(addr, (int) tp_sz);
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include "symbol.h"
|
||||
#include "idf.h"
|
||||
#include "scope.h"
|
||||
#include "type.h"
|
||||
#include "expr.h"
|
||||
|
||||
#define MAXARG 128
|
||||
|
||||
|
@ -126,25 +128,26 @@ start_child(p)
|
|||
/* I/O redirection */
|
||||
if (in_redirect) {
|
||||
int fd;
|
||||
|
||||
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");
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
if (fd != 0) {
|
||||
dup2(fd, 0);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
if (out_redirect) {
|
||||
int fd;
|
||||
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");
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
if (fd != 1) {
|
||||
dup2(fd, 1);
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
@ -152,7 +155,7 @@ start_child(p)
|
|||
/* and run process to be debugged */
|
||||
execv(AObj, argp);
|
||||
error("could not exec %s", AObj);
|
||||
exit(-1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* debugger */
|
||||
|
@ -369,7 +372,7 @@ get_bytes(size, from, to)
|
|||
|
||||
m.m_type = GETBYTES;
|
||||
m.m_size = size;
|
||||
ATOBUF(m.m_buf, (char *) from);
|
||||
put_int(m.m_buf, pointer_size, (long)from);
|
||||
|
||||
if (! could_send(&m, 0)) {
|
||||
return 0;
|
||||
|
@ -394,7 +397,7 @@ set_bytes(size, from, to)
|
|||
|
||||
m.m_type = SETBYTES;
|
||||
m.m_size = size;
|
||||
ATOBUF(m.m_buf, (char *) to);
|
||||
put_int(m.m_buf, pointer_size, (long) to);
|
||||
|
||||
return uputm(&m)
|
||||
&& usend(from, size)
|
||||
|
@ -428,8 +431,8 @@ get_dump(globmessage, globbuf, stackmessage, stackbuf)
|
|||
free(*stackbuf);
|
||||
return 0;
|
||||
}
|
||||
ATOBUF(globmessage->m_buf+SP_OFF*pointer_size,
|
||||
BUFTOA(stackmessage->m_buf+SP_OFF*pointer_size));
|
||||
put_int(globmessage->m_buf+SP_OFF*pointer_size, pointer_size,
|
||||
get_int(stackmessage->m_buf+SP_OFF*pointer_size, pointer_size, T_UNSIGNED));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -467,11 +470,11 @@ get_EM_regs(level)
|
|||
return 0;
|
||||
}
|
||||
if (answer.m_type == FAIL) return 0;
|
||||
*to++ = (t_addr) BUFTOA(answer.m_buf);
|
||||
*to++ = (t_addr) BUFTOA(answer.m_buf+pointer_size);
|
||||
*to++ = (t_addr) BUFTOA(answer.m_buf+2*pointer_size);
|
||||
*to++ = (t_addr) BUFTOA(answer.m_buf+3*pointer_size);
|
||||
*to++ = (t_addr) BUFTOA(answer.m_buf+4*pointer_size);
|
||||
*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);
|
||||
*to++ = (t_addr) get_int(answer.m_buf+3*pointer_size, pointer_size, T_UNSIGNED);
|
||||
*to++ = (t_addr) get_int(answer.m_buf+4*pointer_size, pointer_size, T_UNSIGNED);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
@ -483,7 +486,7 @@ set_pc(PC)
|
|||
|
||||
m.m_type = SETEMREGS;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -540,8 +543,8 @@ set_or_clear_trace(start, end, type)
|
|||
struct message_hdr m;
|
||||
|
||||
m.m_type = type;
|
||||
ATOBUF(m.m_buf, (char *) start);
|
||||
ATOBUF(m.m_buf+pointer_size, (char *) end);
|
||||
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)) { }
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ extern long pointer_size;
|
|||
extern char *strrindex();
|
||||
|
||||
p_tree run_command;
|
||||
t_lineno list_line;
|
||||
|
||||
|
||||
/*VARARGS1*/
|
||||
|
@ -107,7 +106,7 @@ freenode(p)
|
|||
}
|
||||
|
||||
static t_addr
|
||||
get_addr(p)
|
||||
get_addr_from_node(p)
|
||||
p_tree p;
|
||||
{
|
||||
t_addr a = ILL_ADDR;
|
||||
|
@ -132,7 +131,7 @@ get_addr(p)
|
|||
break;
|
||||
|
||||
case OP_IN:
|
||||
a = get_addr(p->t_args[0]);
|
||||
a = get_addr_from_node(p->t_args[0]);
|
||||
p->t_address = a;
|
||||
break;
|
||||
|
||||
|
@ -365,7 +364,7 @@ do_list(p)
|
|||
l2 = p->t_args[1]->t_ival;
|
||||
}
|
||||
else {
|
||||
t_addr a = get_addr(p->t_args[0]);
|
||||
t_addr a = get_addr_from_node(p->t_args[0]);
|
||||
p_position pos;
|
||||
|
||||
if (a == ILL_ADDR) {
|
||||
|
@ -414,7 +413,7 @@ newfile(id)
|
|||
do_stop(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) {
|
||||
return;
|
||||
|
@ -437,7 +436,7 @@ do_trace(p)
|
|||
|
||||
p->t_address = NO_ADDR;
|
||||
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 (p->t_args[0]->t_oper == OP_AT) {
|
||||
e = a;
|
||||
|
@ -569,7 +568,7 @@ do_delete(p)
|
|||
if (p) switch(p->t_oper) {
|
||||
case OP_WHEN:
|
||||
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) {
|
||||
set_or_clear_breakpoint(a, CLRBP);
|
||||
|
@ -577,7 +576,7 @@ do_delete(p)
|
|||
break;
|
||||
}
|
||||
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) {
|
||||
t_addr e;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "scope.h"
|
||||
#include "message.h"
|
||||
#include "langdep.h"
|
||||
#include "expr.h"
|
||||
|
||||
p_type int_type, char_type, short_type, long_type, bool_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);
|
||||
|
||||
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;
|
||||
tp->ty_lb = low;
|
||||
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;
|
||||
tp->ty_hb = high;
|
||||
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,
|
||||
long_type, double_type, string_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 "message.h"
|
||||
#include "langdep.h"
|
||||
#include "expr.h"
|
||||
|
||||
int stack_offset; /* for up and down commands */
|
||||
|
||||
|
@ -83,7 +84,11 @@ get_addr(sym, psize)
|
|||
|
||||
size = proctype->ty_nbparams;
|
||||
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)) {
|
||||
break;
|
||||
}
|
||||
|
@ -91,7 +96,7 @@ get_addr(sym, psize)
|
|||
size = compute_size(tp, AB);
|
||||
*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);
|
||||
return a;
|
||||
}
|
||||
|
@ -105,7 +110,7 @@ get_addr(sym, psize)
|
|||
Return 0 on failure,
|
||||
1 on success.
|
||||
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
|
||||
does not know sizes).
|
||||
*/
|
||||
|
@ -123,27 +128,20 @@ get_value(sym, buf, psize)
|
|||
*buf = 0;
|
||||
switch(sym->sy_class) {
|
||||
case CONST:
|
||||
*buf = Malloc((unsigned) size);
|
||||
*buf = malloc((unsigned) size);
|
||||
if (! *buf) {
|
||||
error("could not allocate enough memory");
|
||||
break;
|
||||
}
|
||||
switch(tp->ty_class) {
|
||||
case T_REAL:
|
||||
if (size != sizeof(double)) {
|
||||
*((float *) *buf) = sym->sy_const.co_rval;
|
||||
}
|
||||
else *((double *) *buf) = sym->sy_const.co_rval;
|
||||
put_real(*buf, size, sym->sy_const.co_rval);
|
||||
break;
|
||||
case T_INTEGER:
|
||||
case T_SUBRANGE:
|
||||
case T_UNSIGNED:
|
||||
case T_ENUM:
|
||||
if (size == sizeof(char)) {
|
||||
*((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;
|
||||
}
|
||||
put_int(*buf, size, sym->sy_const.co_ival);
|
||||
break;
|
||||
case T_SET:
|
||||
memcpy(*buf, sym->sy_const.co_setval, (int) size);
|
||||
|
@ -162,7 +160,11 @@ get_value(sym, buf, psize)
|
|||
a = get_addr(sym, psize);
|
||||
if (a) {
|
||||
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)) {
|
||||
retval = 1;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue