void cmdsrc(int c, Map *map) { u32int w; long locval, locmsk; ADDR savdot; ushort sh; char buf[512]; int ret; if (c == 'L') dotinc = 4; else dotinc = 2; savdot=dot; expr(1); locval=expv; if (expr(0)) locmsk=expv; else locmsk = ~0; if (c == 'L') while ((ret = get4(map, dot, &w)) > 0 && (w&locmsk) != locval) dot = inkdot(dotinc); else while ((ret = get2(map, dot, &sh)) > 0 && (sh&locmsk) != locval) dot = inkdot(dotinc); if (ret < 0) { dot=savdot; error("%r"); } symoff(buf, 512, dot, CANY); dprint(buf); }
void quesie(char *p) { int c, count, i; char tbuf[512]; c = 0; symoff(tbuf, sizeof(tbuf), dot, CTEXT); Bprint(bioout, "%s?\t", tbuf); while(*p) { p = nextc(p); if(*p == '"') { for(p++; *p && *p != '"'; p++) { Bputc(bioout, *p); c++; } if(*p) p++; continue; } count = 0; while(*p >= '0' && *p <= '9') count = count*10 + (*p++ - '0'); if(count == 0) count = 1; p = nextc(p); if(*p == '\0') { p[0] = fmt; p[1] = '\0'; } for(i = 0; i < count; i++) { c += pfmt(*p, 1, 0); dot += inc; if(c > width) { Bprint(bioout, "\n"); symoff(tbuf, sizeof(tbuf), dot, CTEXT); Bprint(bioout, "%s?\t", tbuf); c = 0; } } fmt = *p++; p = nextc(p); } Bprint(bioout, "\n"); }
void colon(char *addr, char *cp) { int argc; char *argv[100]; char tbuf[512]; cp = nextc(cp); switch(*cp) { default: Bprint(bioout, "?\n"); return; case 'b': breakpoint(addr, cp+1); return; case 'd': delbpt(addr); return; /* These fall through to print the stopped address */ case 'r': reset(); argc = buildargv(cp+1, argv, 100); initstk(argc, argv); count = 0; atbpt = 0; run(); break; case 'c': count = 0; atbpt = 0; run(); break; case 's': cp = nextc(cp+1); count = 0; if(*cp) count = strtoul(cp, 0, 0); if(count == 0) count = 1; atbpt = 0; run(); break; } dot = reg.pc; Bprint(bioout, "%s at #%lux ", atbpt ? "breakpoint" : "stopped", dot); symoff(tbuf, sizeof(tbuf), dot, CTEXT); Bprint(bioout, tbuf); if(fmt == 'z') printsource(dot); Bprint(bioout, "\n"); }
void dobplist(void) { Breakpoint *b; char buf[512]; for(b = bplist; b; b = b->next) { switch(b->type) { case Instruction: Bprint(bioout, "0x%lux,%d:b %d done, at ", b->addr, b->count, b->done); symoff(buf, sizeof(buf), b->addr, CTEXT); Bprint(bioout, buf); break; case Access: Bprint(bioout, "0x%lux,%d:ba %d done, at ", b->addr, b->count, b->done); symoff(buf, sizeof(buf), b->addr, CDATA); Bprint(bioout, buf); break; case Read: Bprint(bioout, "0x%lux,%d:br %d done, at ", b->addr, b->count, b->done); symoff(buf, sizeof(buf), b->addr, CDATA); Bprint(bioout, buf); break; case Write: Bprint(bioout, "0x%lux,%d:bw %d done, at ", b->addr, b->count, b->done); symoff(buf, sizeof(buf), b->addr, CDATA); Bprint(bioout, buf); break; case Equal: Bprint(bioout, "0x%lux,%d:be at ", b->addr, b->count); symoff(buf, sizeof(buf), b->addr, CDATA); Bprint(bioout, buf); break; } Bprint(bioout, "\n"); } }
static int i386trace(uvlong pc, uvlong sp, uvlong link) { int i; uvlong osp; Symbol s, f; char buf[128]; USED(link); i = 0; osp = 0; while(findsym(pc, CTEXT, &s)) { symoff(buf, sizeof buf, pc, CANY); fmt(buf, pc); //XXX s.value &= ~(uintptr)0; if(pc != s.value) { /* not at first instruction */ if(findlocal(&s, FRAMENAME, &f) == 0) break; sp += f.value-mach->szaddr; }else if(strcmp(s.name, "forkret") == 0){ //XXX print("//passing interrupt frame; last pc found at sp=%#llux\n", osp); sp += 15 * mach->szaddr; /* pop interrupt frame */ } pc = getval(sp); //XXX if(pc == 0 && strcmp(s.name, "forkret") == 0){ sp += 3 * mach->szaddr; /* pop iret eip, cs, eflags */ print("//guessing call through invalid pointer, try again at sp=%#llux\n", sp); s.name = ""; pc = getval(sp); } if(pc == 0) { print("//didn't find pc at sp=%#llux, last pc found at sp=%#llux\n", sp, osp); break; } osp = sp; sp += mach->szaddr; //XXX if(strcmp(s.name, "forkret") == 0) sp += 2 * mach->szaddr; /* pop iret cs, eflags */ if(++i > 40) break; } return i; }
void printpc(Map *map, uvlong pc, uvlong sp) { char buf[1024]; if(registers) arch->regprint(); if(have_syms > 0 && linenums && fileline(buf, sizeof buf, pc)) fprint(2, "%s\n", buf); if(have_syms > 0 && functions) { symoff(buf, sizeof(buf), pc, CANY); fprint(2, "%s\n", buf); } if(stacks || pprof){ stacktracepcsp(map, pc, sp); } else if(histograms){ addtohistogram(pc, 0, sp); } }
static int rtrace(uvlong pc, uvlong sp, uvlong link) { Symbol s, f; char buf[128]; uvlong oldpc; int i; i = 0; while(findsym(pc, CTEXT, &s)) { if(pc == s.value) /* at first instruction */ f.value = 0; else if(findlocal(&s, FRAMENAME, &f) == 0) break; symoff(buf, sizeof buf, pc, CANY); fmt(buf, pc); oldpc = pc; if(s.type == 'L' || s.type == 'l' || pc <= s.value+mach->pcquant){ if(link == 0) fprint(2, "%s: need to supply a valid link register\n", argv0); pc = link; }else{ pc = getval(sp); if(pc == 0) break; } if(pc == 0 || (pc == oldpc && f.value == 0)) break; sp += f.value; if(++i > 40) break; } return i; }
static int ctrace(uvlong pc, uvlong sp, uvlong link) { Symbol s; char buf[128]; int found; uvlong opc, moved; long j; USED(link); j = 0; opc = 0; while(pc && opc != pc) { moved = pc2sp(pc); if (moved == ~0){ print("pc2sp(%#.8llux) = -1 %r\n", pc); break; } found = findsym(pc, CTEXT, &s); if (!found){ print("findsym fails\n"); break; } symoff(buf, sizeof buf, pc, CANY); fmt(buf, pc); sp += moved; opc = pc; pc = getval(sp); if(pc == 0) break; sp += mach->szaddr; /*assumes address size = stack width*/ if(++j > 40) break; } return j; }
static void format(char *mnemonic, Instr *i, char *f) { if (mnemonic) format(0, i, mnemonic); if (f == 0) return; if (i->curr < i->end) *i->curr++ = '\t'; for ( ; *f && i->curr < i->end; f++) { if (*f != '%') { *i->curr++ = *f; continue; } switch (*++f) { case 's': bprint(i, "%d", i->rs); break; case 't': bprint(i, "%d", i->rt); break; case 'd': bprint(i, "%d", i->rd); break; case 'a': bprint(i, "%d", i->sa); break; case 'l': if (i->rs == 30) { i->curr += symoff(i->curr, i->end-i->curr, i->immediate+mach->sb, CANY); bprint(i, "(SB)"); } else bprint(i, "%lx(r%d)", i->immediate, i->rs); break; case 'i': bprint(i, "$%lx", i->immediate); break; case 'u': *i->curr++ = '$'; i->curr += symoff(i->curr, i->end-i->curr, i->immediate, CANY); bprint(i, "(SB)"); break; case 'j': i->curr += symoff(i->curr, i->end-i->curr, (i->target<<2)|(i->addr & 0xF0000000), CANY); bprint(i, "(SB)"); break; case 'b': i->curr += symoff(i->curr, i->end-i->curr, (i->immediate<<2)+i->addr+4, CANY); break; case 'c': bprint(i, "%lux", i->cofun); break; case 'w': bprint(i, "[%lux]", i->w0); break; case 'f': *i->curr++ = fsub[i->rs & 0x0F]; break; case '\0': *i->curr++ = '%'; return; default: bprint(i, "%%%c", *f); break; } } }
static int amd64trace(uvlong pc, uvlong sp, uvlong link) { int i, isintrr; uvlong osp; Symbol s, f; char buf[128]; USED(link); i = 0; osp = 0; while(findsym(pc, CTEXT, &s)) { symoff(buf, sizeof buf, pc, CANY); fmt(buf, pc); if(strcmp(s.name, "_intrr") == 0) isintrr = 1; else isintrr = 0; if(pc != s.value) { /* not at first instruction */ if(findlocal(&s, FRAMENAME, &f) == 0) break; sp += f.value-mach->szaddr; } else if(isintrr){ print("//passing interrupt frame; last pc found at sp=%#llux\n", osp); /* * Pop interrupt frame (ureg.h) up to the IP value. */ sp += 19 * mach->szaddr; } pc = getval(sp); if(pc == 0 && isintrr){ /* * Pop IP, CS and FLAGS to get to the SP. * The AMD64 aligns the interrupt stack on * a 16-byte boundary so have the get the * SP from the saved frame. */ sp += 3 * mach->szaddr; print("//guessing call through invalid pointer; try again at sp=%#llux\n", sp); s.name = ""; sp = getval(sp); pc = getval(sp); } if(pc == 0) { print("//didn't find pc at sp=%#llux, last pc found at sp=%#llux\n", sp, osp); break; } osp = sp; if(!isintrr) sp += mach->szaddr; if(++i > 40) break; } return i; }
int pfmt(char fmt, int mem, uint32_t val) { int c, i; Symbol s; char *p, ch, str[1024]; c = 0; switch(fmt) { default: Bprint(bioout, "bad modifier\n"); return 0; case 'o': c = Bprint(bioout, "%-4lo ", mem ? (uint16_t)getmem_2(dot) : val); inc = 2; break; case 'O': c = Bprint(bioout, "%-8lo ", mem ? getmem_4(dot) : val); inc = 4; break; case 'q': c = Bprint(bioout, "%-4lo ", mem ? (int16_t)getmem_2(dot) : val); inc = 2; break; case 'Q': c = Bprint(bioout, "%-8lo ", mem ? (int32_t)getmem_4(dot) : val); inc = 4; break; case 'd': c = Bprint(bioout, "%-5ld ", mem ? (int16_t)getmem_2(dot) : val); inc = 2; break; case 'D': c = Bprint(bioout, "%-8ld ", mem ? (int32_t)getmem_4(dot) : val); inc = 4; break; case 'x': c = Bprint(bioout, "#%-4lux ", mem ? (int32_t)getmem_2(dot) : val); inc = 2; break; case 'X': c = Bprint(bioout, "#%-8lux ", mem ? (int32_t)getmem_4(dot) : val); inc = 4; break; case 'u': c = Bprint(bioout, "%-5ld ", mem ? (uint16_t)getmem_2(dot) : val); inc = 2; break; case 'U': c = Bprint(bioout, "%-8ld ", mem ? (uint32_t)getmem_4(dot) : val); inc = 4; break; case 'b': c = Bprint(bioout, "%-3d ", (int)(mem ? getmem_b(dot) : val)); inc = 1; break; case 'c': c = Bprint(bioout, "%c ", (int)(mem ? getmem_b(dot) : val)); inc = 1; break; case 'C': ch = mem ? getmem_b(dot) : val; if(isprint(ch)) c = Bprint(bioout, "%c ", ch); else c = Bprint(bioout, "\\x%.2x ", ch); inc = 1; break; case 's': i = 0; while(ch = getmem_b(dot+i)) str[i++] = ch; str[i] = '\0'; dot += i; c = Bprint(bioout, "%s", str); inc = 0; break; case 'S': i = 0; while(ch = getmem_b(dot+i)) str[i++] = ch; str[i] = '\0'; dot += i; for(p = str; *p; p++) if(isprint(*p)) c += Bprint(bioout, "%c", *p); else c += Bprint(bioout, "\\x%.2ux", *p); inc = 0; break; case 'Y': p = ctime(mem ? getmem_b(dot) : val); p[30] = '\0'; c = Bprint(bioout, "%s", p); inc = 4; break; case 'a': symoff(str, sizeof(str), dot, CTEXT); Bprint(bioout, "%s", str); inc = 0; break; case 'e': for (i = 0; globalsym(&s, i); i++) Bprint(bioout, "%-15s #%lux\n", s.name, getmem_4(s.value)); inc = 0; break; case 'I': case 'i': inc = machdata->das(symmap, dot, fmt, str, sizeof(str)); if (inc < 0) { Bprint(bioout, "ki: %r\n"); return 0; } c = Bprint(bioout, "\t%s", str); break; case 'n': c = width+1; inc = 0; break; case '-': c = 0; inc = -1; break; case '+': c = 0; inc = 1; break; case '^': c = 0; if(inc > 0) inc = -inc; break; case 'z': if (findsym(dot, CTEXT, &s)) Bprint(bioout, " %s() ", s.name); printsource(dot); inc = 0; break; } return c; }