1
0
mirror of https://github.com/PDP-10/its.git synced 2026-01-27 12:42:10 +00:00
Files
PDP-10.its/src/clib/stkdmp.c
2018-10-23 19:37:16 +02:00

249 lines
5.8 KiB
C

# include "c.defs"
/**********************************************************************
STKDMP - C Stack Dumping Routine
This file is PDP-10 dependent, but essentially system
independent.
**********************************************************************/
# rename findproc "FINDPR"
# rename findframe "FINDFR"
# rename print_name "PRNAME"
# rename callok "CALLOK"
# rename hack "STKDMP"
# rename seg2lo "SEG2LO"
# rename seg2hi "SEG2HI"
# rename seg3lo "SEG3LO"
# rename seg3hi "SEG3HI"
# rename pdlbot "PDLBOT"
# rename pdltop "PDLTOP"
# rename purbot "PURBOT"
# rename purtop "PURTOP"
# rename intptr "INTPTR"
# rename mpvh "MPVH"
# rename etsint "ETSINT"
# rename uuoh "UUOH"
# rename uuohan "UUO$HA"
# rename euuoh "EUUOH"
# rename caller "CALLER"
# define ADDI_P 0271740
# define SUBI_P 0275740
# define GO_P 0254037
# define JSP_D 0265200
# define GO 0254000
# define left(x) (((x) >> 18) & 0777777)
# define right(x) ((x) & 0777777)
extern int *seg2lo, *seg2hi, *seg3lo, *seg3hi,
*pdlbot, *pdltop, *purbot, *purtop, *caller,
mpvh[], etsint[], intptr, uuoh[], uuohan[], euuoh[],
cout, *findframe(), *findproc(), hack[];
/**********************************************************************
STKDMP - Dump stack.
**********************************************************************/
static int tuuoh;
stkdmp (fd)
{int *pc; /* procedure pointer */
int *opc; /* previously printed-out pc */
int *sp; /* stack pointer */
if (!cisfd(fd)) fd = cout;
cputc ('\n', fd);
tuuoh = uuoh[0];
sp = &fd; /* arg is on the stack */
pc = right(sp[1]); /* my caller's pc is on the stack */
opc = -1;
--sp; /* top of stack when he was running */
if (pc >= hack && pc <= hack+12) /* PUSHJ P,STKDMP$X */
{pc = right(sp[0]); /* 'real' caller */
sp =- 7; /* 'real' stack top */
}
while (TRUE)
{int *proc, nargs, *npc, *namep, *ap;
proc = findproc (pc);
if (proc == 0) break;
nargs = left(proc[-1]);
namep = right(proc[-1]);
sp = findframe (sp, proc, pc);
if (sp == 0)
{if (opc != caller)
{cprint (fd, " ");
print_name (namep, fd);
cprint (fd, "\n");
}
break;
}
npc = right(sp[0]);
sp =- nargs;
ap = sp;
--sp;
cprint (fd, "%7o ", sp);
print_name (namep, fd);
cprint (fd, " (");
if (nargs>10) nargs = 10;
while (--nargs >= 0)
{cprint (fd, "%o", *ap++);
if (nargs) cprint (fd, ", ");
}
cprint (fd, ")\n");
opc = proc;
pc = npc;
}
}
/**********************************************************************
FINDPROC - Find beginning of active procedure, given a PC.
**********************************************************************/
int *findproc (pc) int *pc;
{int *low, *high, n;
n = 3;
while (--n>=0)
{if (pc >= mpvh && pc < etsint)
{int *p;
p = right(intptr);
pc = right(p[-4]);
continue;
}
if (pc == uuoh+1 || (pc >= uuohan && pc < euuoh))
{pc = right(tuuoh);
if ((pc[0]>>29)==0) ++pc; /* hack */
continue;
}
}
if (pc > seg2lo && pc <= seg2hi)
{low = seg2lo;
high = seg2hi;
}
else if (pc > purbot && pc <= purtop)
{low = purbot;
high = purtop;
}
else return (0);
++pc;
while (--pc > low)
{int data, c, nargs, *namep;
if ((*pc >> 27) == 0) continue;
data = pc[-1];
nargs = left(data);
namep = right(data);
if (nargs >= 16) continue;
if (namep < seg3lo || namep > seg3hi) continue;
c = (*namep >> 29); /* left byte */
if (c < ' ' || c > 'z') continue;
return (pc);
}
return (0);
}
/**********************************************************************
FINDFRAME - Find stack frame, given stack top and procedure
pointer, and PC within procedure. Returns pointer
to return address on stack.
**********************************************************************/
int *findframe (sp, proc, pc) int *sp, *proc, *pc;
{int instr, signal();
instr = proc[0];
if (left(instr) == ADDI_P) /* procedure allocates a frame */
{int bump;
bump = right(instr); /* local frame size */
if (pc == proc); /* hasn't allocated it yet */
else if (left(pc[0]) == GO_P); /* has popped it */
else sp =- bump;
}
if (pc >= mpvh && pc < etsint) /* was in interrupt handler */
sp =- 17; /* ignore stuff pushed by handler */
/* !!! the above is wrong !!! */
++sp;
while (--sp >= pdlbot)
{int data, *opc;
data = *sp;
/* look for return address word on stack */
/* check for reasonable status bits */
if (!(data & 0010000000000)) continue;
/* must be in user mode */
if (data & 0027637000000) continue; /* bad for status bits */
/* check for reasonable old PC (within code segment) */
opc = right(data) - 1;
if (opc < seg2lo) continue;
if (opc > seg2hi) continue;
/* check to see if old PC was call to current proc */
if (callok (opc, proc))
{if (proc == signal && opc>=mpvh && opc<etsint)
tuuoh = sp[-1];
return (sp);
}
}
return (0);
}
/**********************************************************************
CALLOK
**********************************************************************/
int callok (opc, proc)
int *opc, *proc;
{int call, *tpc, op;
call = *opc;
if (call & 037000000) /* index or indirect */
return (TRUE); /* can't test it, assume it's the right one */
op = left(call); /* op code */
tpc = right(call); /* address */
if (op == JSP_D) /* call with nargs mismatch */
{int n, i; /* look for jump */
n = 20; /* up to 20 instructions before jump */
for (i=0;i<n;++i)
{call = tpc[i];
op = left(call);
if (op == GO)
{tpc = right(call);
break;
}
}
}
return (tpc == proc);
}
/**********************************************************************
PRINTNAME
**********************************************************************/
print_name (namep, fd)
{int c;
namep = right(namep) | 0440700000000;
while (c = ildb (&namep))
cputc (c>='A' && c<='Z' ? c+('a'-'A') : c, fd);
}