diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/db/format.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/db/format.c')
-rwxr-xr-x | sys/src/cmd/db/format.c | 386 |
1 files changed, 386 insertions, 0 deletions
diff --git a/sys/src/cmd/db/format.c b/sys/src/cmd/db/format.c new file mode 100755 index 000000000..78bc5f65b --- /dev/null +++ b/sys/src/cmd/db/format.c @@ -0,0 +1,386 @@ +/* + * + * 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(*fp)) + fcount = 1; + else { + fcount = 0; + while (isdigit(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 + */ + uvlong v; + ulong w; + ADDR savdot; + char *fp; + char c, modifier; + int i; + ushort sh, *sp; + 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("%#llux%10t", dot); + dotinc = 0; + break; + + case 'p': + if (get4(map, dot, &w) < 0) + error("%r"); + 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) + sh = (ushort) dot; + else if (get2(map, dot, &sh) < 0) + error("%r"); + w = sh; + 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) + w = (long) dot; + else if (get4(map, dot, &w) < 0) + error("%r"); + dotinc = 4; + if (c == 'U') + dprint("%-16lud", w); + else if (c == 'X') + dprint("%-16#lux", w); + else if (c == 'D') + dprint("%-16ld", w); + else if (c == 'O') + dprint("%-#16luo", w); + else if (c == 'Q') + dprint("%-#16lo", w); + break; + case 'Z': + case 'V': + case 'Y': + if (literal) + v = dot; + else if (get8(map, dot, &v) < 0) + error("%r"); + dotinc = 8; + if (c == 'Y') + dprint("%-20#llux", v); + else if (c == 'V') + dprint("%-20lld", v); + else if (c == 'Z') + dprint("%-20llud", v); + 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) { + sp = (ushort*) ˙ + dprint("%C%C", sp[0], sp[1]); + endline(); + dotinc = 4; + break; + } + savdot=dot; + while ((i = get2(map, dot, &sh) > 0) && sh) { + dot=inkdot(2); + dprint("%C", sh); + endline(); + } + if (i < 0) + error("%r"); + dotinc = dot-savdot+2; + dot=savdot; + break; + + case 's': + if (literal) { + cp = (uchar*) ˙ + 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*)&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*) ˙ + 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': + i = machdata->das(map, dot, modifier, buf, sizeof(buf)); + if (i < 0) + error("%r"); + dotinc = i; + dprint("%s\n", buf); + break; + + case 'M': + i = machdata->hexinst(map, dot, buf, sizeof(buf)); + if (i < 0) + error("%r"); + dotinc = i; + 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 = machdata->swav(dot); + memmove(buf, &v, mach->szfloat); + }else if (get1(map, dot, (uchar*)buf, mach->szfloat) < 0) + error("%r"); + machdata->sftos(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 = machdata->swav(dot); + memmove(buf, &v, mach->szdouble); + }else if (get1(map, dot, (uchar*)buf, mach->szdouble) < 0) + error("%r"); + machdata->dftos(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(dot, CTEXT, &s)) + 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(int incr) +{ + ADDR newdot; + + newdot=dot+incr; + if ((incr >= 0 && newdot < dot) + || (incr < 0 && newdot > dot)) + error("address wraparound"); + return(newdot); +} |