Added
This commit is contained in:
parent
443aae6f7a
commit
132d7ddd95
7 changed files with 742 additions and 0 deletions
1
mach/m68020/libdb/.distr
Normal file
1
mach/m68020/libdb/.distr
Normal file
|
@ -0,0 +1 @@
|
||||||
|
machdep.s
|
63
mach/m68020/libdb/machdep.s
Normal file
63
mach/m68020/libdb/machdep.s
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
.define ___Get_PC, ___Set_PC, ___u_LiB
|
||||||
|
.sect .text; .sect .rom; .sect .data
|
||||||
|
|
||||||
|
! $Header$
|
||||||
|
|
||||||
|
! This is the machine-dependant part of the ACK debugger support.
|
||||||
|
! ___Get_PC takes a frame pointer (local base) argument and returns the
|
||||||
|
! return address from this frame.
|
||||||
|
! ___Set_PC takes a frame pointer (local base) argument plus a return
|
||||||
|
! address and sets the return address of this frame to the
|
||||||
|
! return address supplied.
|
||||||
|
! ___u_LiB saves the scratch registers and then calls ___uX_LiB;
|
||||||
|
! when ___uX_LiB returns, the scratch registers are restored.
|
||||||
|
! ___u_LiB is the solution chosen for the MC68020 back-end.
|
||||||
|
! Other back-ends could choose different solutions.
|
||||||
|
|
||||||
|
! The local base of ___uX_LiB is kind of special: because of ___u_LiB,
|
||||||
|
! the "interesting" return address of this particular stack-frame is found
|
||||||
|
! in a different place than the one of a normal stack-frame:
|
||||||
|
! the "interesting" return address is in fact the return address of
|
||||||
|
! ___u_LiB. Therefore, we save the local base of ___uX_LiB in sv_a6.
|
||||||
|
|
||||||
|
.sect .data
|
||||||
|
sv_a6:
|
||||||
|
.data4 0
|
||||||
|
|
||||||
|
.sect .text
|
||||||
|
___Get_PC:
|
||||||
|
move.l (4,sp),d0
|
||||||
|
beq 1f
|
||||||
|
move.l d0,a0
|
||||||
|
cmp.l (sv_a6),d0
|
||||||
|
beq 2f
|
||||||
|
move.l (4,a0),d0
|
||||||
|
1:
|
||||||
|
rts
|
||||||
|
2:
|
||||||
|
move.l (32,a0),d0
|
||||||
|
rts
|
||||||
|
|
||||||
|
___Set_PC:
|
||||||
|
move.l (4,sp),d0
|
||||||
|
beq 1f
|
||||||
|
move.l d0,a0
|
||||||
|
cmp.l (sv_a6),d0
|
||||||
|
beq 2f
|
||||||
|
move.l (8,sp),(4,a0)
|
||||||
|
1:
|
||||||
|
rts
|
||||||
|
2:
|
||||||
|
move.l (8,sp),(32,a0)
|
||||||
|
rts
|
||||||
|
|
||||||
|
___u_LiB:
|
||||||
|
movem.l d0/d1/d2/a0/a1,-(sp)
|
||||||
|
move.l (sv_a6),-(sp)
|
||||||
|
move.l sp,d0
|
||||||
|
sub.l #8,d0
|
||||||
|
move.l d0,(sv_a6) ! this is the LB of __uX_LiB
|
||||||
|
jsr (___uX_LiB)
|
||||||
|
move.l (sp)+,(sv_a6)
|
||||||
|
movem.l (sp)+,d0/d1/d2/a0/a1
|
||||||
|
rts
|
4
mach/proto/grind/.distr
Normal file
4
mach/proto/grind/.distr
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
READ_ME
|
||||||
|
atlin.c
|
||||||
|
lib.e
|
||||||
|
par_misc.e
|
17
mach/proto/grind/READ_ME
Normal file
17
mach/proto/grind/READ_ME
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
$Header$
|
||||||
|
|
||||||
|
The machine-dependant part of the ACK debugger support requires three
|
||||||
|
routines:
|
||||||
|
___Get_PC takes a frame pointer (local base) argument and returns the
|
||||||
|
return address from this frame.
|
||||||
|
___Set_PC takes a frame pointer (local base) argument plus a return
|
||||||
|
address and sets the return address of this frame to the
|
||||||
|
return address supplied.
|
||||||
|
??? a third routine which is called at every line (see for
|
||||||
|
instance mach/m68020/ncg/mach.c for an example of how to
|
||||||
|
do this). This routine must save the scratch registers
|
||||||
|
and then call (or jump to) ___uX_LiB. If this is a call,
|
||||||
|
___Get_PC and ___Set_PC are complicated by the existance
|
||||||
|
of a procedure frame that we do not want the "grind" user
|
||||||
|
to know about. See for instance the mach/m68020/libdb version
|
||||||
|
for how to solve this problem.
|
508
mach/proto/grind/atlin.c
Normal file
508
mach/proto/grind/atlin.c
Normal file
|
@ -0,0 +1,508 @@
|
||||||
|
/* $Header$ */
|
||||||
|
|
||||||
|
#define DEBUGGEE
|
||||||
|
#include "message.h"
|
||||||
|
|
||||||
|
#define MAXBP 128
|
||||||
|
#define MAXTRACE 16
|
||||||
|
|
||||||
|
static int nbp; /* # of breakpoints */
|
||||||
|
static char *bp[MAXBP];
|
||||||
|
static int ntrace;
|
||||||
|
static struct trace {
|
||||||
|
char *begin_trace, *end_trace;
|
||||||
|
} trace_buf[MAXTRACE];
|
||||||
|
|
||||||
|
static struct message_hdr ok_message;
|
||||||
|
|
||||||
|
#define OFF 0
|
||||||
|
#define SS 1 /* single stepping */
|
||||||
|
#define SSF 2 /* single stepping, counting functions
|
||||||
|
as single statements */
|
||||||
|
|
||||||
|
static char *
|
||||||
|
BUFTOA(p)
|
||||||
|
register char *p;
|
||||||
|
{
|
||||||
|
register long l = 0;
|
||||||
|
register int i;
|
||||||
|
|
||||||
|
for (i = PS; i>0; i--) {
|
||||||
|
l = (l << 8) | (*p++ & 0377);
|
||||||
|
}
|
||||||
|
return (char *) l;
|
||||||
|
}
|
||||||
|
|
||||||
|
static long
|
||||||
|
BUFTOL(p)
|
||||||
|
register char *p;
|
||||||
|
{
|
||||||
|
register long l = 0;
|
||||||
|
register int i;
|
||||||
|
|
||||||
|
for (i = LS; i>0; i--) {
|
||||||
|
l = (l << 8) | (*p++ & 0377);
|
||||||
|
}
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
ATOBUF(p, cp)
|
||||||
|
register char *p;
|
||||||
|
char *cp;
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
register long l = (long) cp;
|
||||||
|
|
||||||
|
p += PS;
|
||||||
|
for (i = PS; i > 0; i--) {
|
||||||
|
*--p = l;
|
||||||
|
l >>= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
LTOBUF(p, l)
|
||||||
|
register char *p;
|
||||||
|
register long l;
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
|
||||||
|
p += LS;
|
||||||
|
for (i = LS; i > 0; i--) {
|
||||||
|
*--p = l;
|
||||||
|
l >>= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int single_stepping = OFF;
|
||||||
|
static int db_ss = 0;
|
||||||
|
static int step_count = 0;
|
||||||
|
static char *savedlb;
|
||||||
|
static int break_flag = 0;
|
||||||
|
static int reading = 0;
|
||||||
|
static char *retaddr;
|
||||||
|
static char *LB;
|
||||||
|
static char *currbrk;
|
||||||
|
|
||||||
|
extern char *__Get_LB();
|
||||||
|
extern char *__Get_Hol0();
|
||||||
|
extern char *__Get_PC();
|
||||||
|
extern char *__Cvt_LB_AB();
|
||||||
|
extern char *__Get_HP();
|
||||||
|
extern char *_sbrk();
|
||||||
|
extern int etext;
|
||||||
|
extern __Set_PC();
|
||||||
|
static send_ok();
|
||||||
|
|
||||||
|
#define check_ptr(c) (((c) >= (char *)&etext && (c) <= currbrk) || (c) >= LB)
|
||||||
|
|
||||||
|
#define IN_FD 3
|
||||||
|
#define OUT_FD 6
|
||||||
|
|
||||||
|
static int
|
||||||
|
ureceive(p, c)
|
||||||
|
char *p;
|
||||||
|
long c;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int retval = 1;
|
||||||
|
|
||||||
|
reading = 1;
|
||||||
|
while (c >= 0x1000) {
|
||||||
|
i = _read(IN_FD, p, 0x1000);
|
||||||
|
if (i == 0) return 0;
|
||||||
|
if (i < 0) {
|
||||||
|
retval = 0;
|
||||||
|
c -= 0x1000;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p += i;
|
||||||
|
c -= i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (c > 0) {
|
||||||
|
i = _read(IN_FD, p, (int)c);
|
||||||
|
if (i == 0) return 0;
|
||||||
|
if (i < 0) {
|
||||||
|
retval = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p += i;
|
||||||
|
c -= i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reading = 0;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
usend(p, c)
|
||||||
|
char *p;
|
||||||
|
long c;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
while (c >= 0x1000) {
|
||||||
|
i = _write(OUT_FD, p, 0x1000);
|
||||||
|
if (i < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
p += i;
|
||||||
|
c -= i;
|
||||||
|
}
|
||||||
|
while (c > 0) {
|
||||||
|
i = _write(OUT_FD, p, (int)c);
|
||||||
|
if (i < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
p += i;
|
||||||
|
c -= i;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ugetm(message)
|
||||||
|
struct message_hdr *message;
|
||||||
|
{
|
||||||
|
if (! ureceive((char *) message, (long) sizeof(struct message_hdr))) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
uputm(message)
|
||||||
|
struct message_hdr *message;
|
||||||
|
{
|
||||||
|
if (! usend((char *) message, (long) sizeof(struct message_hdr))) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
sendreply(m, p, sz)
|
||||||
|
struct message_hdr *m;
|
||||||
|
char *p;
|
||||||
|
long sz;
|
||||||
|
{
|
||||||
|
if (! uputm(m) || ! (sz && p ? usend(p, sz) : 1)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_request()
|
||||||
|
{
|
||||||
|
/* obtain a request from the debugger and perform it */
|
||||||
|
int fail = 0;
|
||||||
|
register int i;
|
||||||
|
register char *c;
|
||||||
|
char *c1;
|
||||||
|
long sz;
|
||||||
|
struct message_hdr message;
|
||||||
|
|
||||||
|
start:
|
||||||
|
if (! ugetm(&message)) {
|
||||||
|
/* failed to get a message. Something is wrong. Let process continue */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.m_type & M_DB_SS) db_ss = 1;
|
||||||
|
message.m_type &= 0177;
|
||||||
|
switch(message.m_type) {
|
||||||
|
case M_OK:
|
||||||
|
/* sometimes sent to child to see if it lives */
|
||||||
|
goto start;
|
||||||
|
case M_SETBP:
|
||||||
|
/* set a breakpoint */
|
||||||
|
if (nbp == MAXBP) {
|
||||||
|
fail = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
bp[nbp++] = BUFTOA(message.m_buf+1);
|
||||||
|
break;
|
||||||
|
case M_SETTRACE:
|
||||||
|
if (ntrace == MAXTRACE) {
|
||||||
|
fail = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
trace_buf[ntrace].begin_trace = BUFTOA(message.m_buf+1);
|
||||||
|
trace_buf[ntrace++].end_trace = BUFTOA(message.m_buf+(PS+1));
|
||||||
|
break;
|
||||||
|
case M_CLRBP:
|
||||||
|
i = 0;
|
||||||
|
c = BUFTOA(message.m_buf+1);
|
||||||
|
while (i < nbp && bp[i] != c) {
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (i < nbp) {
|
||||||
|
while (i < nbp) {
|
||||||
|
bp[i] = bp[i+1];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
nbp--;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fail = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case M_CLRTRACE:
|
||||||
|
i = 0;
|
||||||
|
c = BUFTOA(message.m_buf+1);
|
||||||
|
c1 = BUFTOA(message.m_buf+(PS+1));
|
||||||
|
while (i < ntrace &&
|
||||||
|
trace_buf[i].begin_trace != c &&
|
||||||
|
trace_buf[i].end_trace != c1){
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (i < ntrace) {
|
||||||
|
while (i < ntrace) {
|
||||||
|
trace_buf[i] = trace_buf[i+1];
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
ntrace--;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fail = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case M_SETSS:
|
||||||
|
single_stepping = SS;
|
||||||
|
step_count = BUFTOL(message.m_buf+1);
|
||||||
|
return 1;
|
||||||
|
case M_CLRSS:
|
||||||
|
single_stepping = OFF;
|
||||||
|
break;
|
||||||
|
case M_SETSSF:
|
||||||
|
savedlb = __Get_LB(2);
|
||||||
|
step_count = BUFTOL(message.m_buf+1);
|
||||||
|
single_stepping = SSF;
|
||||||
|
return 1;
|
||||||
|
case M_GETBYTES:
|
||||||
|
message.m_type = M_DATA;
|
||||||
|
sz = BUFTOL(message.m_buf+1);
|
||||||
|
c = BUFTOA(message.m_buf+(LS+1));
|
||||||
|
currbrk = _sbrk(0);
|
||||||
|
if (! check_ptr(c) || ! check_ptr(c+sz-1)) {
|
||||||
|
fail = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return sendreply(&message, c, sz)
|
||||||
|
? 0
|
||||||
|
: -1;
|
||||||
|
|
||||||
|
case M_GETSTR:
|
||||||
|
sz = BUFTOL(message.m_buf+1);
|
||||||
|
c1 = c = BUFTOA(message.m_buf+(LS+1));
|
||||||
|
currbrk = _sbrk(0);
|
||||||
|
if (check_ptr(c)) {
|
||||||
|
while (*c) {
|
||||||
|
if (c - c1 + 1 >= sz) break;
|
||||||
|
c++;
|
||||||
|
if (! check_ptr(c)) {
|
||||||
|
fail = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else fail = 1;
|
||||||
|
if (fail) break;
|
||||||
|
message.m_type = M_DATA;
|
||||||
|
sz = c - c1 + 1;
|
||||||
|
LTOBUF(message.m_buf+1, sz);
|
||||||
|
return sendreply(&message, c1, sz)
|
||||||
|
? 0
|
||||||
|
: -1;
|
||||||
|
|
||||||
|
case M_SETBYTES:
|
||||||
|
if (! ureceive(BUFTOA(message.m_buf+(LS+1)), BUFTOL(message.m_buf+1))) {
|
||||||
|
fail = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case M_GETEMREGS:
|
||||||
|
i = BUFTOL(message.m_buf+1);
|
||||||
|
c = __Get_LB(i+2); /* local base */
|
||||||
|
c1 = __Get_LB(i+1); /* needed to find PC and SP */
|
||||||
|
ATOBUF(message.m_buf+LB_OFF, c);
|
||||||
|
ATOBUF(message.m_buf+AB_OFF, __Cvt_LB_AB(c));
|
||||||
|
ATOBUF(message.m_buf+PC_OFF, __Get_PC(c1));
|
||||||
|
ATOBUF(message.m_buf+HP_OFF, __Get_HP());
|
||||||
|
ATOBUF(message.m_buf+SP_OFF, __Cvt_LB_AB(c1));
|
||||||
|
return sendreply(&message, (char *) 0, 0L) ? 0 : -1;
|
||||||
|
|
||||||
|
case M_SETEMREGS:
|
||||||
|
/* actually, only the program counter is settable */
|
||||||
|
i = BUFTOL(message.m_buf+1);
|
||||||
|
c = __Get_LB(i+1);
|
||||||
|
__Set_PC(c, BUFTOA(message.m_buf+PC_OFF));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case M_CONT:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case M_DUMP:
|
||||||
|
currbrk = _sbrk(0);
|
||||||
|
c = __Get_Hol0();
|
||||||
|
c1 = currbrk;
|
||||||
|
message.m_type = M_DGLOB;
|
||||||
|
sz = c1 - c;
|
||||||
|
LTOBUF(message.m_buf+1, sz);
|
||||||
|
ATOBUF(message.m_buf + HP_OFF, __Get_HP());
|
||||||
|
ATOBUF(message.m_buf + PC_OFF, __Get_PC(__Get_LB(1)));
|
||||||
|
ATOBUF(message.m_buf + LB_OFF, c1);
|
||||||
|
|
||||||
|
sendreply(&message, c, sz);
|
||||||
|
if (! ___topsave()) {
|
||||||
|
/* we get here after a ___topload() ! */
|
||||||
|
step_count = 0;
|
||||||
|
nbp = 0;
|
||||||
|
single_stepping = 0;
|
||||||
|
savedlb = 0;
|
||||||
|
break_flag = 0;
|
||||||
|
db_ss = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
case M_DGLOB:
|
||||||
|
_brk(BUFTOA(message.m_buf + LB_OFF));
|
||||||
|
__Set_HP(BUFTOA(message.m_buf+HP_OFF));
|
||||||
|
if (! ureceive(__Get_Hol0(), BUFTOL(message.m_buf+1))) {}
|
||||||
|
___topload(BUFTOA(message.m_buf + SP_OFF));
|
||||||
|
/*NOTREACHED*/
|
||||||
|
}
|
||||||
|
send_ok(fail ? M_FAIL : M_OK);
|
||||||
|
return fail ? -1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
___sendtop(addr, SP, sz)
|
||||||
|
char *addr, *SP;
|
||||||
|
unsigned sz;
|
||||||
|
{
|
||||||
|
struct message_hdr m;
|
||||||
|
|
||||||
|
m.m_type = M_DSTACK;
|
||||||
|
LTOBUF(m.m_buf+1, (long) sz);
|
||||||
|
ATOBUF(m.m_buf+SP_OFF, SP);
|
||||||
|
sendreply(&m, addr, (long)sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
___restoretop(SP)
|
||||||
|
char *SP;
|
||||||
|
{
|
||||||
|
struct message_hdr m;
|
||||||
|
|
||||||
|
if (! ugetm(&m)) {}
|
||||||
|
if (! ureceive(SP, BUFTOL(m.m_buf+1))) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
sigcatch()
|
||||||
|
{
|
||||||
|
signal(7, sigcatch);
|
||||||
|
if (reading) send_ok(M_INTR);
|
||||||
|
else break_flag = 1;
|
||||||
|
db_ss = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
check_bp()
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
|
||||||
|
for (i = 0; i < nbp; i++) {
|
||||||
|
if (bp[i] == retaddr) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
check_trace()
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ntrace; i++) {
|
||||||
|
if (trace_buf[i].begin_trace <= retaddr &&
|
||||||
|
trace_buf[i].end_trace >= retaddr) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
send_ok(type)
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
|
||||||
|
ok_message.m_type = type;
|
||||||
|
LTOBUF(ok_message.m_buf+1, (long) retaddr);
|
||||||
|
uputm(&ok_message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
__uX_LiB()
|
||||||
|
/* This function must be called after every LIN and LNI */
|
||||||
|
{
|
||||||
|
int status = M_CONT;
|
||||||
|
|
||||||
|
LB = __Get_LB(0);
|
||||||
|
if ( retaddr) {
|
||||||
|
/* not the first time ... */
|
||||||
|
retaddr = __Get_PC(LB);
|
||||||
|
|
||||||
|
/* first, adjust step_count when single stepping
|
||||||
|
*/
|
||||||
|
if (single_stepping == SS) step_count--;
|
||||||
|
else if (single_stepping == SSF) {
|
||||||
|
char *lb = __Get_LB(1);
|
||||||
|
if (!((char *) &lb < lb && lb >= savedlb ||
|
||||||
|
(char *) &lb > lb && lb <= savedlb)) {
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
savedlb = lb;
|
||||||
|
step_count--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (single_stepping != OFF && step_count <= 0) {
|
||||||
|
status = M_END_SS;
|
||||||
|
single_stepping = OFF;
|
||||||
|
}
|
||||||
|
else if (break_flag) status = M_INTR;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
signal(7, sigcatch);
|
||||||
|
retaddr = __Get_PC(LB);
|
||||||
|
status = M_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == M_CONT) {
|
||||||
|
if ((nbp != 0 && check_bp() != 0) ||
|
||||||
|
(ntrace != 0 && check_trace() != 0)) {
|
||||||
|
status = M_OK;
|
||||||
|
}
|
||||||
|
else if (break_flag) status = M_INTR;
|
||||||
|
else {
|
||||||
|
if (db_ss) {
|
||||||
|
db_ss = 0;
|
||||||
|
send_ok(M_DB_SS);
|
||||||
|
while (do_request() <= 0) /* nothing */;
|
||||||
|
}
|
||||||
|
if (break_flag) status = M_INTR;
|
||||||
|
else return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break_flag = 0;
|
||||||
|
send_ok(status);
|
||||||
|
db_ss = 0;
|
||||||
|
while (do_request() <= 0) /* nothing */;
|
||||||
|
}
|
58
mach/proto/grind/lib.e
Normal file
58
mach/proto/grind/lib.e
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
#
|
||||||
|
|
||||||
|
; $Header$
|
||||||
|
|
||||||
|
mes 2, EM_WSIZE, EM_PSIZE
|
||||||
|
|
||||||
|
exp $__Get_LB
|
||||||
|
pro $__Get_LB,0
|
||||||
|
lor 0
|
||||||
|
1
|
||||||
|
lol 0
|
||||||
|
zlt *2
|
||||||
|
dup EM_PSIZE
|
||||||
|
zer EM_PSIZE
|
||||||
|
cmp
|
||||||
|
zeq *2
|
||||||
|
dch
|
||||||
|
del 0
|
||||||
|
bra *1
|
||||||
|
2
|
||||||
|
ret EM_PSIZE
|
||||||
|
end
|
||||||
|
|
||||||
|
exp $__Get_Hol0
|
||||||
|
pro $__Get_Hol0,0
|
||||||
|
lae 0
|
||||||
|
ret EM_PSIZE
|
||||||
|
end
|
||||||
|
|
||||||
|
exp $__Get_HP
|
||||||
|
pro $__Get_HP,0
|
||||||
|
lor 2
|
||||||
|
ret EM_PSIZE
|
||||||
|
end
|
||||||
|
|
||||||
|
exp $__Set_HP
|
||||||
|
pro $__Set_HP,0
|
||||||
|
lal 0
|
||||||
|
loi EM_PSIZE
|
||||||
|
str 2
|
||||||
|
ret 0
|
||||||
|
end
|
||||||
|
|
||||||
|
exp $__Cvt_LB_AB
|
||||||
|
pro $__Cvt_LB_AB,0
|
||||||
|
lal 0
|
||||||
|
loi EM_PSIZE
|
||||||
|
zer EM_PSIZE
|
||||||
|
cmp
|
||||||
|
zeq *2
|
||||||
|
lal 0
|
||||||
|
loi EM_PSIZE
|
||||||
|
lpb
|
||||||
|
ret EM_PSIZE
|
||||||
|
2
|
||||||
|
zer EM_PSIZE
|
||||||
|
ret EM_PSIZE
|
||||||
|
end
|
91
mach/proto/grind/par_misc.e
Normal file
91
mach/proto/grind/par_misc.e
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
#
|
||||||
|
;
|
||||||
|
; (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||||
|
; See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
|
;
|
||||||
|
|
||||||
|
;
|
||||||
|
; Module: coroutine primitives
|
||||||
|
; Author: Kees Bot, Edwin Scheffer, Ceriel Jacobs
|
||||||
|
; Version: $Header$
|
||||||
|
;
|
||||||
|
; This has been taken from the ACK Modula-2 runtime system and adapted.
|
||||||
|
;
|
||||||
|
|
||||||
|
mes 2,EM_WSIZE,EM_PSIZE
|
||||||
|
|
||||||
|
;
|
||||||
|
; ___topsave: save the stack by sending it to the debugger
|
||||||
|
;
|
||||||
|
exp $___topsave
|
||||||
|
pro $___topsave, 0
|
||||||
|
mes 11
|
||||||
|
loe 0
|
||||||
|
lae 4 ; load line number and file name
|
||||||
|
loi EM_PSIZE
|
||||||
|
lim ; load ignore mask
|
||||||
|
lor 0 ; load LB
|
||||||
|
|
||||||
|
; now find the last argument base: first find the local base that has
|
||||||
|
; dynamic link 0.
|
||||||
|
|
||||||
|
lor 0
|
||||||
|
1
|
||||||
|
dup EM_PSIZE
|
||||||
|
dch
|
||||||
|
zer EM_PSIZE
|
||||||
|
cmp
|
||||||
|
zeq *2
|
||||||
|
dch
|
||||||
|
bra *1
|
||||||
|
2
|
||||||
|
lpb ; last argument base
|
||||||
|
|
||||||
|
; Now the stuff between the current stack pointer and this argument base
|
||||||
|
; is saved by sending it to the debugger.
|
||||||
|
|
||||||
|
lor 1
|
||||||
|
sbs EM_WSIZE
|
||||||
|
loc EM_WSIZE
|
||||||
|
adu EM_WSIZE ; gives size
|
||||||
|
lor 1 ; SP (the SP BEFORE pushing)
|
||||||
|
lor 1 ; SP (address of stack top to save)
|
||||||
|
cal $___sendtop ; ___sendtop(char *address, char *SP, unsigned size)
|
||||||
|
asp 4*EM_PSIZE+3*EM_WSIZE ; remove the lot from the stack
|
||||||
|
loc 1
|
||||||
|
ret EM_WSIZE ; return 1
|
||||||
|
end 0
|
||||||
|
|
||||||
|
exp $___topload
|
||||||
|
pro $___topload, 0
|
||||||
|
|
||||||
|
lal 0
|
||||||
|
loi EM_PSIZE
|
||||||
|
|
||||||
|
lxl 0
|
||||||
|
2
|
||||||
|
dup EM_PSIZE
|
||||||
|
lal 0
|
||||||
|
loi EM_PSIZE ; compare target SP with current LB to see if we must
|
||||||
|
loi EM_PSIZE
|
||||||
|
cmp ; find another LB first
|
||||||
|
zgt *1
|
||||||
|
dch ; just follow dynamic chain to make sure we find
|
||||||
|
; a legal one
|
||||||
|
bra *2
|
||||||
|
1
|
||||||
|
str 0
|
||||||
|
|
||||||
|
str 1 ; restore SP
|
||||||
|
lor 1
|
||||||
|
adp -EM_PSIZE
|
||||||
|
cal $___restoretop ; ___restoretop(char *SP)
|
||||||
|
asp EM_PSIZE+EM_WSIZE
|
||||||
|
str 0 ; restore local base
|
||||||
|
sim ; ignore mask
|
||||||
|
lae 4
|
||||||
|
sti EM_PSIZE
|
||||||
|
ste 0 ; line and file
|
||||||
|
loc 0
|
||||||
|
ret EM_WSIZE ; return 0
|
||||||
|
end 0
|
Loading…
Reference in a new issue