blob: 7a93bc5ff515fe3443eba3fc9bd06235aab38acc [file] [log] [blame]
/*
*
* debugger
*
*/
#include "defs.h"
#include "fns.h"
void
scanform(long icount, int prt, char *ifp, Map *map, int literal)
{
char *fp;
char c;
int fcount;
ADDR savdot;
int firstpass;
firstpass = 1;
while (icount) {
fp=ifp;
savdot=dot;
/*now loop over format*/
while (*fp) {
if (!isdigit((uchar)*fp))
fcount = 1;
else {
fcount = 0;
while (isdigit((uchar)(c = *fp++))) {
fcount *= 10;
fcount += c-'0';
}
fp--;
}
if (*fp==0)
break;
fp=exform(fcount,prt,fp,map,literal,firstpass);
firstpass = 0;
}
dotinc=dot-savdot;
dot=savdot;
if (--icount)
dot=inkdot(dotinc);
}
}
char *
exform(int fcount, int prt, char *ifp, Map *map, int literal, int firstpass)
{
/* execute single format item `fcount' times
* sets `dotinc' and moves `dot'
* returns address of next format item
*/
vlong v;
WORD w;
ulong savdot;
u16int u2;
u32int u4;
u64int u8;
char *fp;
char c, modifier;
int i;
ushort sh;
uchar ch, *cp;
Symbol s;
char buf[512];
extern int printcol;
fp = 0;
while (fcount > 0) {
fp = ifp;
c = *fp;
modifier = *fp++;
if (firstpass) {
firstpass = 0;
if (!literal && (c == 'i' || c == 'I' || c == 'M')
&& (dot & (mach->pcquant-1))) {
dprint("warning: instruction not aligned");
printc('\n');
}
if (prt && modifier != 'a' && modifier != 'A') {
symoff(buf, 512, dot, CANY);
dprint("%s%c%16t", buf, map==symmap? '?':'/');
}
}
if (printcol==0 && modifier != 'a' && modifier != 'A')
dprint("\t\t");
switch(modifier) {
case SPC:
case TB:
dotinc = 0;
break;
case 't':
case 'T':
dprint("%*t", fcount);
dotinc = 0;
return(fp);
case 'a':
symoff(buf, sizeof(buf), dot, CANY);
dprint("%s%c%16t", buf, map==symmap? '?':'/');
dotinc = 0;
break;
case 'A':
dprint("%#lux%10t", dot);
dotinc = 0;
break;
case 'p':
if (get4(map, dot, &u4) < 0)
error("%r");
w = u4;
symoff(buf, sizeof(buf), w, CANY);
dprint("%s%16t", buf);
dotinc = mach->szaddr;
break;
case 'u':
case 'd':
case 'x':
case 'o':
case 'q':
if (literal)
u2 = (ushort) dot;
else if (get2(map, dot, &u2) < 0)
error("%r");
w = u2;
dotinc = 2;
if (c == 'u')
dprint("%-8lud", w);
else if (c == 'x')
dprint("%-8#lux", w);
else if (c == 'd')
dprint("%-8ld", w);
else if (c == 'o')
dprint("%-8#luo", w);
else if (c == 'q')
dprint("%-8#lo", w);
break;
case 'U':
case 'D':
case 'X':
case 'O':
case 'Q':
if (literal)
u4 = (long) dot;
else if (get4(map, dot, &u4) < 0)
error("%r");
dotinc = 4;
if (c == 'U')
dprint("%-16lud", u4);
else if (c == 'X')
dprint("%-16#lux", u4);
else if (c == 'D')
dprint("%-16ld", u4);
else if (c == 'O')
dprint("%-#16luo", u4);
else if (c == 'Q')
dprint("%-#16lo", u4);
break;
case 'Z':
case 'V':
case 'Y':
if (literal)
v = dot;
else if (get8(map, dot, &u8) < 0)
error("%r");
dotinc = 8;
if (c == 'Y')
dprint("%-20#llux", u8);
else if (c == 'V')
dprint("%-20lld", u8);
else if (c == 'Z')
dprint("%-20llud", u8);
break;
case 'B':
case 'b':
case 'c':
case 'C':
if (literal)
ch = (uchar) dot;
else if (get1(map, dot, &ch, 1) < 0)
error("%r");
if (modifier == 'C')
printesc(ch);
else if (modifier == 'B' || modifier == 'b')
dprint("%-8#lux", (long) ch);
else
printc(ch);
dotinc = 1;
break;
case 'r':
if (literal)
sh = (ushort) dot;
else if (get2(map, dot, &sh) < 0)
error("%r");
dprint("%C", sh);
dotinc = 2;
break;
case 'R':
if (literal) {
u16int sp[2];
memmove(&sp, &dot, 4);
dprint("%C%C", sp[0], sp[1]);
endline();
dotinc = 4;
break;
}
savdot=dot;
while ((i = get2(map, dot, &u2) > 0) && u2) {
dot=inkdot(2);
dprint("%C", u2);
endline();
}
if (i < 0)
error("%r");
dotinc = dot-savdot+2;
dot=savdot;
break;
case 's':
if (literal) {
cp = (uchar*)(void*)&dot;
for (i = 0; i < 4; i++)
buf[i] = cp[i];
buf[i] = 0;
dprint("%s", buf);
endline();
dotinc = 4;
break;
}
savdot = dot;
for(;;){
i = 0;
do{
if (get1(map, dot, (uchar*)(void*)&buf[i], 1) < 0)
error("%r");
dot = inkdot(1);
i++;
}while(!fullrune(buf, i));
if(buf[0] == 0)
break;
buf[i] = 0;
dprint("%s", buf);
endline();
}
dotinc = dot-savdot+1;
dot = savdot;
break;
case 'S':
if (literal) {
cp = (uchar*) &dot;
for (i = 0; i < 4; i++)
printesc(cp[i]);
endline();
dotinc = 4;
break;
}
savdot=dot;
while ((i = get1(map, dot, &ch, 1) > 0) && ch) {
dot=inkdot(1);
printesc(ch);
endline();
}
if (i < 0)
error("%r");
dotinc = dot-savdot+1;
dot=savdot;
break;
case 'I':
case 'i':
dotinc = mach->das(map, dot, modifier, buf, sizeof(buf));
if (dotinc < 0)
error("%r");
dprint("%s\n", buf);
break;
case 'M':
dotinc = mach->hexinst(map, dot, buf, sizeof(buf));
if (dotinc < 0)
error("%r");
dprint("%s", buf);
if (*fp) {
dotinc = 0;
dprint("%48t");
} else
dprint("\n");
break;
case 'f':
/* BUG: 'f' and 'F' assume szdouble is sizeof(vlong) in the literal case */
if (literal) {
v = mach->swap8((ulong)dot);
memmove(buf, &v, mach->szfloat);
}else if (get1(map, dot, (uchar*)buf, mach->szfloat) < 0)
error("%r");
mach->ftoa32(buf, sizeof(buf), (void*) buf);
dprint("%s\n", buf);
dotinc = mach->szfloat;
break;
case 'F':
/* BUG: 'f' and 'F' assume szdouble is sizeof(vlong) in the literal case */
if (literal) {
v = mach->swap8(dot);
memmove(buf, &v, mach->szdouble);
}else if (get1(map, dot, (uchar*)buf, mach->szdouble) < 0)
error("%r");
mach->ftoa64(buf, sizeof(buf), (void*) buf);
dprint("%s\n", buf);
dotinc = mach->szdouble;
break;
case 'n':
case 'N':
printc('\n');
dotinc=0;
break;
case '"':
dotinc=0;
while (*fp != '"' && *fp)
printc(*fp++);
if (*fp)
fp++;
break;
case '^':
dot=inkdot(-dotinc*fcount);
return(fp);
case '+':
dot=inkdot((WORD)fcount);
return(fp);
case '-':
dot=inkdot(-(WORD)fcount);
return(fp);
case 'z':
if (findsym(locaddr(dot), CTEXT, &s) >= 0)
dprint("%s() ", s.name);
printsource(dot);
printc(EOR);
return fp;
default:
error("bad modifier");
}
if (map->seg[0].fd >= 0)
dot=inkdot(dotinc);
fcount--;
endline();
}
return(fp);
}
void
printesc(int c)
{
static char hex[] = "0123456789abcdef";
if (c < SPC || c >= 0177)
dprint("\\x%c%c", hex[(c&0xF0)>>4], hex[c&0xF]);
else
printc(c);
}
ADDR
inkdot(WORD incr)
{
ADDR newdot;
newdot=dot+incr;
if ((incr >= 0 && newdot < dot)
|| (incr < 0 && newdot > dot))
error("address wraparound");
return(newdot);
}