/* * Disassemble */ static void do_list(char *s) { register int i; while (isspace((int)*s)) s++; if (isxdigit((int)*s)) wrk_ram = ram + exatoi(s); for (i = 0; i < 10; i++) { printf("%04x - ", (WORD)(wrk_ram - ram)); disass(&wrk_ram, wrk_ram - ram); if (wrk_ram > ram + 65535) wrk_ram = ram; } }
/* * Execute a single step */ void do_step(void) { BYTE *p; cpu_state = SINGLE_STEP; cpu_error = NONE; cpu(); if (cpu_error == OPHALT) handel_break(); cpu_err_msg(); print_head(); print_reg(); p = PC; disass(&p, p - ram); }
/* * Disassemble */ static void do_list(char *s) { register int i; while (isspace((int)*s)) s++; if (isxdigit((int)*s)) wrk_ram = mem_base() + exatoi(s); for (i = 0; i < 10; i++) { printf("%04x - ", (unsigned int)(wrk_ram - mem_base())); disass(&wrk_ram, wrk_ram - mem_base()); if (wrk_ram > mem_base() + 65535) wrk_ram = mem_base(); } }
static DebugWaitFor dbgShowCode(char *line, processPo p, termPo loc, insWord ins, void *cl) { integer count = maximum(1, cmdCount(line, 1)); methodPo mtd = p->prog; insPo pc = p->pc; insPo last = entryPoint(mtd) + insCount(mtd); for (integer ix = 0; ix < count && pc < last; ix++) { pc = disass(debugOutChnnl, p, mtd, pc, Null, Null); outStr(debugOutChnnl, "\n"); } flushFile(debugOutChnnl); resetDeflt("n"); return moreDebug; }
static void step(unsigned start, unsigned end) { if (end > start) for (unsigned i = start; i < end; i++) { single_step(); printf("I = %s\n", disass(I)); if (I != O_NEXT00) { printf("Result: %d; correct result: %d\n\n", LOAD_CELL(SP), correct[i - i / 5]); if (correct[i - i / 5] != LOAD_CELL(SP)) { printf("Error in comparison tests: EP = %"PRIu32"\n", EP); exit(1); } (void)POP; // drop result of comparison } else putchar('\n'); } }
void build_code_cache(void) { int i; unsigned int line; BYTE *p, *oldp; line = 0; p = PC; while (p < (PC + K64K)) /* scan entire Z80 mem space */ { Disass_Str[0] = 0; /* reset the disass string */ oldp = p; /* get the start point */ disass(&p, p - ram); /* get the operation length */ for (i = 0; i < (int)(p - oldp); i++) /* set all addrs to this line */ { codelines[(oldp - ram) + i] = line; } line++; /* next line */ } }
/* * Execute a single step */ static void do_step(void) { BYTE *p; cpu_state = SINGLE_STEP; cpu_error = NONE; switch(cpu) { case Z80: cpu_z80(); break; case I8080: cpu_8080(); break; } if (cpu_error == OPHALT) handel_break(); cpu_err_msg(); print_head(); print_reg(); p = mem_base() + PC; disass(&p, PC); }
int main(void) { int exception = 0; init((CELL *)calloc(1024, 1), 256); start_ass(EP); ass(O_ZERO); ass(O_ONE); ass(O_MONE); ass(O_CELL); ass(O_MCELL); ass(O_ROT); ass(O_PLUS); ass(O_PLUS); ass(O_MINUS); ass(O_PLUS1); ass(O_MINUS1); ass(O_SWAP); ass(O_PLUSCELL); ass(O_MINUSCELL); ass(O_MONE); ass(O_CELL); ass(O_STAR); ass(O_SWAPMINUS); ass(O_SLASHMOD); ass(O_SLASH); ass(O_MONE); ass(O_MOD); ass(O_PLUS1); ass(O_CELLS); ass(O_SLASH2); ass(O_DROP); ass(O_CELL); ass(O_NEGATE); ass(O_ABS); ass(O_ABS); ass(O_ONE); ass(O_MAX); ass(O_MCELL); ass(O_MIN); ass(O_LITERALI); ilit(3); ass(O_SSLASHREM); ass(O_DROP); ass(O_LITERALI); ilit(-2); ass(O_USLASHMOD); assert(single_step() == -259); // load first instruction word for (size_t i = 0; i < sizeof(correct) / sizeof(correct[0]); i++) { show_data_stack(); printf("Correct stack: %s\n\n", correct[i - i / 5]); if (strcmp(correct[i - i / 5], val_data_stack())) { printf("Error in arithmetic tests: EP = %"PRIu32"\n", EP); exit(1); } single_step(); printf("I = %s\n", disass(I)); } assert(exception == 0); printf("Arithmetic tests ran OK\n"); return 0; }
void Show_Code(BYTE *disas_addr, gboolean force) { BYTE *p, *isabreak; int line, i, pc_line, pc_row, scrollto, win_offset; unsigned int disas_addr_line; char whole_buffer[CODE_LIST_LENGTH*48]; char br_char, pc_char; WORD code_ptr; BYTE *Start_Code_List; GtkTextIter aniter; GtkTextMark *mark; GdkRectangle coderect; gint winx, winy; int vbuf_start, vbuf_end, disas_buff_line; disas_addr_line = codelines[disas_addr - ram]; /* get line from disas addr */ printf("P1: disas_addr_line=%d force=%d buff_lines_start=%ld buff_lines_end=%ld\n", disas_addr_line, force, buff_lines_start, buff_lines_start + CODE_LIST_LENGTH); /* * (1) If 'disas_addr_line' is not in the text buffer rebuild the text buffer. * If 'force' is set, do it anyway. */ if (disas_addr_line < buff_lines_start || disas_addr_line > buff_lines_start + CODE_LIST_LENGTH || force) { buff_lines_start = disas_addr_line - BACKUP_LINES; if (buff_lines_start < 0) buff_lines_start = 0; code_ptr = 0; /* scan the codelines table */ while (codelines[code_ptr] != buff_lines_start) /*..for the new start addr */ code_ptr++; Start_Code_List = code_ptr + ram; /* set disass start addr */ p = Start_Code_List; /* tmp pointer for disass */ whole_buffer[0] = 0; /* rewind to start */ printf("Starting disassembly from %04X (line=%d) PC=%04X (line=%d)\n", (p - ram), disas_addr_line, (PC - ram), codelines[PC - ram]); for (line = 0; line < CODE_LIST_LENGTH; line++) { Disass_Str[0] = 0; isabreak = 0; /* zero if no break */ if ((((BYTE)(*p)) & 0xff) == BREAK_OP) /* possible breakpoint? */ for (i = 0; i < SBSIZE; i++) /* scan all BPs */ if (soft[i].sb_adr == (p - ram)) /* BP here? */ { isabreak = p; /* mark the BP address */ *p = soft[i].sb_oldopc; /* restore the opcode */ } sprintf(tstr, "%04X: ", /* put addr etc @ SOL */ (WORD)(p - ram)); strcat(whole_buffer, tstr); disass(&p, p - ram); /* get Opcode and Disass */ /* DEBUG: show buffered line number and code line number */ sprintf(tstr, "%02d %03d ", line, disas_addr_line + line); strcat(whole_buffer, tstr); if (show_opcodes) /* machine code display? */ { strcat(whole_buffer, Opcode_Str); /* yes - add it */ strcat(whole_buffer, " "); /* and a separator */ } strcat(whole_buffer, Disass_Str); /* add the disas string */ if (isabreak) /* breakpoint to restore? */ *isabreak = BREAK_OP; } gtk_text_buffer_set_text( /* show buffer in the win */ code_textbuffer, whole_buffer, -1); } /* END OF (1) */ /* * At this point we know that disas_addr_line is within the text buffer. * * Now we check to see if it is within the visible lines. * * If not we need to scroll the window so that disas_addr_line is in * the middle of the visible lines. */ /* Find the limits of the visible lines, upper and lower. */ gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(codetext), &coderect); // printf("coderect1: x=%d y=%d width=%d height=%d\n", // coderect.x, coderect.y, coderect.width, coderect.height); gtk_text_view_get_line_at_y(GTK_TEXT_VIEW(codetext), &aniter, coderect.y, NULL); vbuf_start = gtk_text_iter_get_line(&aniter); gtk_text_view_get_line_at_y(GTK_TEXT_VIEW(codetext), &aniter, coderect.y+coderect.height, NULL); vbuf_end = gtk_text_iter_get_line(&aniter) - 1; // printf("visible (modified): start=%d end=%d\n", vbuf_start, vbuf_end); /* Is the target line NOT in the visible window? */ disas_buff_line = disas_addr_line - buff_lines_start; // printf("Checking for %d between %d and %d\n", // disas_buff_line, vbuf_start, vbuf_end); if ( !(disas_buff_line >= vbuf_start && disas_buff_line <= vbuf_end ) ) { if (disas_buff_line <= vbuf_start) /* backing up or down? */ { scrollto = disas_buff_line - BACKUP_LINES; if (scrollto < 0) scrollto = 0; } else scrollto = disas_buff_line + BACKUP_LINES; // printf("scrolling to %d\n", scrollto); gtk_text_buffer_get_end_iter(code_textbuffer, &aniter); gtk_text_iter_set_line(&aniter, scrollto); mark = gtk_text_buffer_create_mark(code_textbuffer, NULL, &aniter, FALSE); gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(codetext), mark, 0.0, FALSE, 0.0, 0.0); } // printf("p1: dch\n"); do_code_highlights(); }
static logical shouldWeStopIns(processPo p, insWord ins) { if (focus == NULL || focus == p) { if (debugDebugging) { outMsg(logFile, "debug: traceDepth=%d, traceCount=%d, tracing=%s, ins: ", p->traceDepth, p->traceCount, (p->tracing ? "yes" : "no")); disass(logFile, p, p->prog, p->pc, p->fp, p->sp); outMsg(logFile, "\n%_"); } switch (p->waitFor) { case stepInto: if (p->traceCount > 0) p->traceCount--; return (logical) (p->traceCount == 0); case stepOver: case nextBreak: break; default: return False; } switch (ins) { case Ret: { switch (p->waitFor) { case stepOver: if (p->traceDepth > 0) p->traceDepth--; return (logical) (p->traceDepth == 0 && p->traceCount == 0); default: return False; } } case Call: case OCall: { switch (p->waitFor) { case stepOver: p->traceDepth++; return (logical) (p->traceCount == 0 && p->traceDepth == 1); default: return False; } } case Tail: case OTail: switch (p->waitFor) { case stepOver: return (logical) (p->traceDepth == 0 && p->traceCount == 0); default: return False; } case dLine: { termPo loc = findPcLocation(p->prog, insOffset(p->prog, p->pc)); breakPointPo bp = lineBreakPointHit(C_TERM(loc)); if (bp != Null) { p->waitFor = stepInto; p->tracing = True; p->traceDepth = p->traceCount = 0; if (isTempBreakPoint(bp)) clearBreakPoint(bp); return True; } else return False; } default: return False; } } else return False; }
/* * All is there: now use it */ int main(int argc, char **argv) { char s[512]; char *subs=NULL, *savedsubs; int status=0, offset; unsigned int j, k, esp, eip; unsigned int i[16]; /* 8 suffice by now, but who knows... */ char names[16][8], c[20]; /* [8][8] suffice, but who knows */ char *ptr; char *prgname=argv[0]; struct ksym *symlist=NULL; char defaultmap[]="/usr/src/linux/System.map"; char *mapname=defaultmap; if (argc>2) { fprintf(stderr,"%s: Usage: \"%s [mapfile_name] < oops-log\"\n", prgname, prgname); exit(1); } if (argc==2) mapname=argv[1]; fprintf(stderr,"%s: Using %s as map\n", prgname, mapname); symlist = filesym(symlist,NULL,mapname); symlist = filesym(symlist,NULL,"/proc/ksyms"); symlist=fixlist(symlist); /* dumplist(symlist); */ gsymlist=symlist; /* * Ok, the symbol table is there, now get the message */ if (isatty(0)) { fprintf(stderr,"%s: please paste the oops on my stdin\n",prgname); } while (fgets(s,512,stdin)) { if (!subs) { /* nothing yet */ savedsubs = subs = strstr(s,"EIP: "); } switch(status) { case 0: /* not found */ if (!subs) continue; status++; offset=0; esp=0; j=sscanf(subs,"%s %x:[<%x>]",s,&i[0],&i[1]); if (j!=3) { fprintf(stderr,"Wrong \"EIP\" line\n"); continue; } printf("\n%-7s %04x:%08x %s\n",s,i[0],i[1],decode(i[1],0)); eip=i[1]; /* keep to disass */ break; case 1: /* before the stack */ j=sscanf(subs,"%s %x %s %x %s %x %s %x",names[0+offset],i+offset, names[1+offset],i+1+offset,names[2+offset],i+2+offset, names[3+offset],i+3+offset); if (j==8 && strlen(names[0])==4) { /* registers */ /* * The problem with registers is that I need "esp" * first, on order to refer registers to the stack. * So, I save them, and decode later on */ if ( (ptr=strstr(subs,"esp:")) ) { sscanf(ptr,"%*s %x",&esp); } if (esp) { /* decode only when they can be ref'd to stack */ for (j=0; j<4+offset; j++) printf("%s %08x %s\n",names[j],i[j],decode(i[j],esp)); offset=0; } else { offset+=4; /* next time, write after these ones */ } continue; } else if (strncmp(subs,"Stack: ",7)) { printf("%s",subs); continue; } else { status++; offset=0; subs+=6; /* skip the string, and fall through */ } case 2: /* stack and trace*/ if (strncmp(subs,"Call Trace",4) != 0) { k=sscanf(subs,"%x %x %x %x %x %x %x %x",i,i+1,i+2,i+3, i+4,i+5,i+6,i+7); if (k<=0) { fprintf(stderr,"Bad stack line (%i items)\n",j); } else { for (j=0; j<k; j++) printf("esp+%02x: %08x %s\n",(offset+j)*4,i[j], decode(i[j],esp)); } if (!offset) subs = savedsubs; /* restore */ offset+=8; continue; } /* call trace */ status++; offset=0; subs+=12; /* skip the string, and fall through */ case 3: /* the trace */ if (strncmp(subs,"Code",4)) { k=sscanf(subs," [<%x>] [<%x>] [<%x>] [<%x>] " "[<%x>] [<%x>] [<%x>] [<%x>]",i,i+1,i+2,i+3, i+4,i+5,i+6,i+7); if (k==0) { fprintf(stderr,"Bad trace line %s(no add found)\n",subs); } else { for (j=0; j<k; j++) printf("Trace: %08x %s\n", i[j], decode(i[j],esp)); } subs = savedsubs; /* restore */ continue; } /* the code */ ptr = subs+5; /* skip "Code:" */ for (j=0; j<20; j++) { long l=strtol(ptr,&ptr,16); c[j]=(char)l; } disass(c, eip, esp); esp=0; status=0; subs=NULL; /* ready for another oops */ } } return 0; }