#help_index "Debugging" InstructionEntry **disasm_table=NULL; I8 disasm_table_entries=0; U8 ins64_mask=0x0880088880; I8 CompareInstructionEntries(InstructionEntry **tempi1,InstructionEntry **tempi2) { I8 i1,i2,j=0,result=0; while (TRUE) { if (j<(*tempi1)->opcode_cnt && j<(*tempi2)->opcode_cnt) { i1=(*tempi1)->opcode[j]; i2=(*tempi2)->opcode[j]; result=i1-i2; if (result) return result; j++; } else { i1=(*tempi1)->opcode_cnt; i2=(*tempi2)->opcode_cnt; result=i1-i2; if (result) return result; i1=(*tempi1)->slash_value; i2=(*tempi2)->slash_value; result=i1-i2; if (result) return result; i1=(*tempi1)->flags & IEF_OP_SIZE32; i2=(*tempi2)->flags & IEF_OP_SIZE32; result=i1-i2; if (result) return result; i1=Bt(&ins64_mask,(*tempi1)->arg1) || Bt(&ins64_mask,(*tempi1)->arg2); i2=Bt(&ins64_mask,(*tempi2)->arg1) || Bt(&ins64_mask,(*tempi2)->arg2); result=i1-i2; if (result) return result; return result; } } } void LoadDisasmTable() { SysHashTable *h=asm_hash; OpcodeHashEntry *temph; InstructionEntry *tempi; U8 cnt=0; I8 i,j,k; for (i=0;i<=h->mask;i++) { temph=h->body[i]; while (temph) { if (temph->type==HTT_OPCODE) cnt+=temph->instruction_entry_cnt; temph=temph->next; } } disasm_table_entries=cnt; j=0; disasm_table=MAlloc(cnt*sizeof(void *)); for (i=0;i<=h->mask;i++) { temph=h->body[i]; while (temph) { if (temph->type==HTT_OPCODE) { tempi=&temph->ins; for (k=0;kinstruction_entry_cnt;k++) { disasm_table[j++]=tempi; tempi+=sizeof(InstructionEntry); } } temph=temph->next; } } QSort(disasm_table,cnt,sizeof(void *),&CompareInstructionEntries); } if (!disasm_table) { LoadDisasmTable; LoadList("ST_INT_NAMES", " \0 \0NMI\0 \0 \0 \0 \0 \0" " \0 \0 \0 \0 \0 \0 \0 \0" " \0 \0 \0 \0 \0 \0 \0 \0" " \0 \0 \0 \0 \0 \0 \0 \0" " \0 \0 \0 \0 \0 \0 \0 \0" " \0 \0 \0 \0 \0 \0 \0 \0" " \0 \0 \0 \0cout\0coutln\0 \0 \0" " \0 \0 \0 \0 \0 \0 \0 \0" "f_unary_minus\0f_inc\0f_dec\0f_power\0f_mul\0f_div\0f_mod\0f_add\0" "f_sub\0f_less\0f_greater\0f_less_equal\0f_greater_equal\0f_to_int_RAX\0f_to_double_RAX\0f_to_int_RDX\0" "f_to_double_RDX\0\0"); } BoolU8 PutSourceLine(void *add,U8 cnt,I1 *buf=NULL) { ClassStruct *tempc; I8 i,minl,maxl,offset; DbgInfo *dbg; void **body; I1 *src; if (tempc=FindPSect(add,&offset)) { if (dbg=tempc->debug) { body=dbg->body; minl=dbg->min_line; maxl=dbg->max_line; for (i=minl;i<=maxl;i++) { if (*body>=add) { if (*bodysource_link); RemoveFirstSeg(src,":"); RemoveLastSeg(src,","); if (buf) SPrintF(buf,"$$LK-A,\"FL:%s,%d\"$$",src,i); else PrintF("$$LK-A,\"FL:%s,%d\"$$",src,i); Free(src); return TRUE; } else return FALSE; } body+=sizeof(void *); } } } return FALSE; } public void DasmIns(I1 *buf,I8 *add,I8 seg_size=64,I8 *branch=NULL) //Disassembles one instruction { U1 *ip=*add,*bb; U2 *ww; U4 *dd; U8 *dddd; I8 disp,imm; I8 opsize,opadd; BoolU4 cont; I8 i,j,k,n,m,o1,o2,a1,a2,aa1,aa2,arg1_size=0,arg2_size=0,a1_size,a2_size, ModrM=-1,SIB=-1,scale,r1,r2, Mod=-1,RM1=-1,RM2=-1,REX=-1,REX_r=0,REX_x=0,REX_b=0; InstructionEntry *tempi; OpcodeHashEntry *tempo,dummy; I1 *a1_st,*a2_st,*bin_data_area,*bin_data_area2, buf2[256],buf3[256],seg_overrides[40],arg1_st[256],arg2_st[256]; if (branch) *branch=-1; if (seg_size==16) { opsize=16; opadd=16; } else if (seg_size==32) { opsize=32; opadd=32; } else { opsize=32; opadd=64; } *arg1_st=0; *arg2_st=0; a1_st=arg1_st; a2_st=arg2_st; *buf=0; if (PutSourceLine(ip,1,buf)) StrCat(buf,"\r\n"); SPrintF(buf+StrLen(buf),"%16tP ",ip); bin_data_area=buf+StrLen(buf); for (i=0;i<6;i++) { SPrintF(buf2,"%02X",ip[i]); StrCat(buf,buf2); } StrCat(buf," "); SPrintF(buf3,"%16tP ",ip+6); bin_data_area2=buf3+StrLen(buf3); for (i=6;i<12;i++) { SPrintF(buf2,"%02X",ip[i]); StrCat(buf3,buf2); } *seg_overrides=0; cont=TRUE; do { switch (*ip++) { case 0x2E: StrCat(seg_overrides,"CS:"); break; case 0x36: StrCat(seg_overrides,"SS:"); break; case 0x3E: StrCat(seg_overrides,"DS:"); break; case 0x26: StrCat(seg_overrides,"ES:"); break; case 0x64: StrCat(seg_overrides,"FS:"); break; case 0x65: StrCat(seg_overrides,"GS:"); break; case 0x66: if (opsize==16) opsize=32; else opsize=16; break; case 0x67: if (opadd==16) opadd=32; else opadd=16; break; case 0x40: REX=0x40; break; case 0x41: REX=0x41; REX_b=8; break; case 0x42: REX=0x42; REX_x=8; break; case 0x43: REX=0x43; REX_b=8; REX_x=8; break; case 0x44: REX=0x44; REX_r=8; break; case 0x45: REX=0x45; REX_b=8; REX_r=8; break; case 0x46: REX=0x46; REX_x=8; REX_r=8; break; case 0x47: REX=0x47; REX_b=8; REX_x=8; REX_r=8; break; case 0x48: REX=0x48; opsize=64; break; case 0x49: REX=0x49; REX_b=8; opsize=64; break; case 0x4A: REX=0x4A; REX_x=8; opsize=64; break; case 0x4B: REX=0x4B; REX_b=8; REX_x=8; opsize=64; break; case 0x4C: REX=0x4C; REX_r=8; opsize=64; break; case 0x4D: REX=0x4D; REX_b=8; REX_r=8; opsize=64; break; case 0x4E: REX=0x4E; REX_x=8; REX_r=8; opsize=64; break; case 0x4F: REX=0x4F; REX_b=8; REX_x=8; REX_r=8; opsize=64; break; default: cont=FALSE; } } while (cont); ip--; i=0; j=disasm_table_entries-1; do { k=(i+j)>>1; //binary search tempi=disasm_table[k]; m=0; n=0; while (TRUE) { if (nopcode_cnt) { o1=ip[n]; if (n==tempi->opcode_cnt-1 && tempi->flags & IEF_PLUS_OPCODE) o1&=-8; o2=tempi->opcode[n]; m=o1-o2; n++; if (m) break; } else { if (tempi->slash_value<8) { o1=(ip[n] >> 3) & 7; o2=tempi->slash_value; m=o1-o2; if (!m) { if (opsize==16) { if (tempi->flags & IEF_OP_SIZE32) m=-1; } else { if (tempi->flags & IEF_OP_SIZE16) m=1; } if (!m) { if (opsize==64||tempi->flags&IEF_NO_REX) { if (!Bt(&ins64_mask,tempi->arg1) && !Bt(&ins64_mask,tempi->arg2)) m=1; } else { if (Bt(&ins64_mask,tempi->arg1) || Bt(&ins64_mask,tempi->arg2)) m=-1; } } } break; } else { m=0; if (opsize==16) { if (tempi->flags & IEF_OP_SIZE32) m=-1; } else { if (tempi->flags & IEF_OP_SIZE16) m=1; } if (!m) { a1=tempi->arg1; a2=tempi->arg2; if (opsize==64) { if (!Bt(&ins64_mask,a1) && !Bt(&ins64_mask,a2) && !(a2==ARGT_NO && (a1>=ARGT_UIMM8 && a1<=ARGT_UIMM64 || a1>=ARGT_IMM8 && a1<=ARGT_IMM64 ) )) m=1; } else { if (Bt(&ins64_mask,a1) || Bt(&ins64_mask,a2)) m=-1; } } break; } } } if (m>0) { if (k==i) { k=j; break; } else i=k; } else if (m<0) { if (k-i<=1) { k=i; break; } else j=k; } else break; } while (TRUE); tempi=disasm_table[k]; ip+=tempi->opcode_cnt; tempo=tempi-(tempi->ins_entry_num*sizeof(InstructionEntry))+&dummy-&dummy.ins; StrCat(buf,tempo->str); a1=tempi->arg1; a2=tempi->arg2; aa1=a1; aa2=a2; StrCpy(buf2,SysTextSub(a1,"ST_ARGUMENT_TYPES")); if (StrStr(buf2,"8")) { arg1_size=1; StrCat(arg1_st,"U1 "); } else if (StrStr(buf2,"16")) { arg1_size=2; StrCat(arg1_st,"U2 "); } else if (StrStr(buf2,"32")) { arg1_size=4; StrCat(arg1_st,"U4 "); } else if (StrStr(buf2,"64")) { arg1_size=8; StrCat(arg1_st,"U8 "); } StrCpy(buf2,SysTextSub(a2,"ST_ARGUMENT_TYPES")); if (StrStr(buf2,"8")) { arg2_size=1; StrCat(arg2_st,"U1 "); } else if (StrStr(buf2,"16")) { arg2_size=2; StrCat(arg2_st,"U2 "); } else if (StrStr(buf2,"32")) { arg2_size=4; StrCat(arg2_st,"U4 "); } else if (StrStr(buf2,"64")) { arg2_size=8; StrCat(arg2_st,"U8 "); } a1_size=arg1_size; a2_size=arg2_size; if (tempi->flags & IEF_PLUS_OPCODE && (tempi->slash_value==SV_REGISTER || tempi->opcode_modifier>=OM_RB && tempi->opcode_modifier<=OM_RD)) { ip--; RM1=*(ip++) - tempi->opcode[tempi->opcode_cnt-1]+REX_b; *buf2=0; if (a1>=ARGT_R8 && a1<=ARGT_R64) { if (a1_size==1) SPrintF(buf2,"%Z",RM1,"ST_U1_REGS"); else if (a1_size==2) SPrintF(buf2,"%Z",RM1,"ST_U2_REGS"); else if (a1_size==4) SPrintF(buf2,"%Z",RM1,"ST_U4_REGS"); else if (a1_size==8) SPrintF(buf2,"%Z",RM1,"ST_U8_REGS"); StrCat(a1_st,buf2); } else { if (a2_size==1) SPrintF(buf2,"%Z",RM1,"ST_U1_REGS"); else if (a2_size==2) SPrintF(buf2,"%Z",RM1,"ST_U2_REGS"); else if (a2_size==4) SPrintF(buf2,"%Z",RM1,"ST_U4_REGS"); else if (a2_size==8) SPrintF(buf2,"%Z",RM1,"ST_U8_REGS"); StrCat(a2_st,buf2); } } if ((a1>=ARGT_RM8 && a1<=ARGT_RM64) || (a2>=ARGT_RM8 && a2<=ARGT_RM64)) { if (a2>=ARGT_RM8 && a2<=ARGT_RM64) { a1_st=arg2_st; a2_st=arg1_st; a1_size=arg2_size; a2_size=arg1_size; aa1=a2; aa2=a1; } StrCat(a1_st,seg_overrides); ModrM=*(ip++); Mod=(ModrM>>6) & 3; RM1=ModrM & 7+REX_b; RM2=(ModrM>>3) & 7+REX_r; if (Mod<3 && RM1&7==4) { SIB=*(ip++); } if (Mod==1) { bb=ip; disp=*bb; SPrintF(buf2,"%02X",disp); StrCat(a1_st,buf2); ip++; } if (Mod==2) { dd=ip; disp=*dd; SPrintF(buf2,"%08X",disp); StrCat(a1_st,buf2); ip+=4; } if (tempi->slash_value<8) RM2=-1; else { *buf2=0; if (aa2==ARGT_SREG) SPrintF(buf2,"%Z",RM2,"ST_SEG_REGS"); else if (!(aa2>=ARGT_IMM8 && aa2<=ARGT_IMM64) && !(aa2>=ARGT_UIMM8 && aa2<=ARGT_UIMM64)) { if (a2_size==1) SPrintF(buf2,"%Z",RM2,"ST_U1_REGS"); else if (a2_size==2) SPrintF(buf2,"%Z",RM2,"ST_U2_REGS"); else if (a2_size==4) SPrintF(buf2,"%Z",RM2,"ST_U4_REGS"); else if (a2_size==8) SPrintF(buf2,"%Z",RM2,"ST_U8_REGS"); } StrCat(a2_st,buf2); } if (RM1&7==5 && Mod==0) { dd=ip; disp=*dd; ip+=4; if (disp>MAX_I4) disp|=0xFFFFFFFF00000000; if (seg_size==64) { disp+=ip; if (aa2==ARGT_IMM8 || aa2==ARGT_UIMM8) disp++; else if (aa2==ARGT_IMM16 || aa2==ARGT_UIMM16) disp+=2; else if (aa2==ARGT_IMM32 || aa2==ARGT_UIMM32) disp+=4; else if (aa2==ARGT_IMM64 || aa2==ARGT_UIMM64) disp+=8; } SPrintF(buf2,"[%X] ",disp); StrCat(a1_st,buf2); RM1=-1; } else { if (Mod<3) { if (RM1&7==4) { RM1=-1; r1=SIB & 7+REX_b; r2=(SIB >> 3) & 7+REX_x; scale=(SIB >> 6) &3; if (scale==3) scale=8; else if (scale==2) scale=4; else if (scale==1) scale=2; else scale=1; if (r1&7==5 && Mod==0) { dd=ip; disp=*dd; SPrintF(buf2,"%08X",disp); StrCat(a1_st,buf2); ip+=4; if (seg_size!=64) SPrintF(buf2,"[%Z*%d]",r2,"ST_U4_REGS",scale); else SPrintF(buf2,"[%Z*%d]",r2,"ST_U8_REGS",scale); StrCat(a1_st,buf2); } else { if (seg_size!=64) SPrintF(buf2,"[%Z+%Z*%d]",r1,"ST_U4_REGS", r2,"ST_U4_REGS",scale); else SPrintF(buf2,"[%Z+%Z*%d]",r1,"ST_U8_REGS", r2,"ST_U8_REGS",scale); StrCat(a1_st,buf2); } } else { *buf2=0; if (opadd==16) SPrintF(buf2,"[%Z]",RM1,"ST_U2_REGS"); else if (opadd==32) SPrintF(buf2,"[%Z]",RM1,"ST_U4_REGS"); else SPrintF(buf2,"[%Z]",RM1,"ST_U8_REGS"); StrCat(a1_st,buf2); } } else { *buf2=0; if (a1_size==1) SPrintF(buf2,"%Z",RM1,"ST_U1_REGS"); else if (a1_size==2) SPrintF(buf2,"%Z",RM1,"ST_U2_REGS"); else if (a1_size==4) SPrintF(buf2,"%Z",RM1,"ST_U4_REGS"); else if (a1_size==8) SPrintF(buf2,"%Z",RM1,"ST_U8_REGS"); StrCat(a1_st,buf2); } } } if (a1>=ARGT_MOFFS8 && a1<=ARGT_MOFFS64) { StrCat(arg1_st,seg_overrides); if (arg1_size==1) { bb=ip; disp=*bb; ip++; SPrintF(buf2,"[%X]",disp); StrCat(arg1_st,buf2); } else if (opadd==16) { ww=ip; disp=*ww; ip+=2; SPrintF(buf2,"[%X]",disp); StrCat(arg1_st,buf2); } else { dd=ip; disp=*dd; ip+=4; SPrintF(buf2,"[%X]",disp); StrCat(arg1_st,buf2); } } if (a2>=ARGT_MOFFS8 && a2<=ARGT_MOFFS64) { StrCat(arg2_st,seg_overrides); if (arg2_size==1) { bb=ip; disp=*bb; ip++; SPrintF(buf2,"[%X]",disp); StrCat(arg2_st,buf2); } else if (opadd==16) { ww=ip; disp=*ww; ip+=2; SPrintF(buf2,"[%X]",disp); StrCat(arg2_st,buf2); } else { dd=ip; disp=*dd; ip+=4; SPrintF(buf2,"[%X]",disp); StrCat(arg2_st,buf2); } } switch (a1) { case ARGT_IMM8: case ARGT_UIMM8: bb=ip; imm=*bb; SPrintF(buf2,"%02X",imm); StrCat(arg1_st,buf2); if (tempi->opcode[0]==0xCD) { StrCat(arg1_st," "); StrCat(arg1_st,SysTextSub(imm,"ST_INT_NAMES")); } ip++; break; case ARGT_IMM16: case ARGT_UIMM16: ww=ip; imm=*ww; SPrintF(buf2,"%04X",imm); StrCat(arg1_st,buf2); ip+=2; break; case ARGT_IMM32: case ARGT_UIMM32: dd=ip; imm=*dd; SPrintF(buf2,"%08X",imm); StrCat(arg1_st,buf2); ip+=4; break; case ARGT_IMM64: case ARGT_UIMM64: dddd=ip; imm=*dddd; SPrintF(buf2,"%016X",imm); StrCat(arg1_st,buf2); ip+=8; break; case ARGT_REL8: bb=ip; disp=*bb; if (disp>MAX_I1) disp|=0xFFFFFFFFFFFFFF00; ip++; disp+=ip; SPrintF(buf2,"%P ",disp); if (branch) *branch=disp; StrCat(arg1_st,buf2); break; case ARGT_REL16: ww=ip; disp=*ww; if (disp>MAX_I2) disp|=0xFFFFFFFFFFFF0000; ip+=2; disp+=ip; SPrintF(buf2,"%P ",disp); if (branch) *branch=disp; StrCat(arg1_st,buf2); break; case ARGT_REL32: dd=ip; disp=*dd; if (disp>MAX_I4) disp|=0xFFFFFFFF00000000; ip+=4; disp+=ip; SPrintF(buf2,"%P ",disp); if (branch) *branch=disp; StrCat(arg1_st,buf2); break; case ARGT_CL: StrCat(arg1_st,"CL"); break; case ARGT_AL: StrCat(arg1_st,"AL"); break; case ARGT_AX: StrCat(arg1_st,"AX"); break; case ARGT_EAX: StrCat(arg1_st,"EAX"); break; case ARGT_DX: StrCat(arg1_st,"DX"); break; case ARGT_SS: StrCat(arg1_st,"SS"); break; case ARGT_DS: StrCat(arg1_st,"DS"); break; case ARGT_ES: StrCat(arg1_st,"ES"); break; case ARGT_FS: StrCat(arg1_st,"FS"); break; case ARGT_GS: StrCat(arg1_st,"GS"); break; case ARGT_CS: StrCat(arg1_st,"CS"); break; } switch (a2) { case ARGT_IMM8: case ARGT_UIMM8: bb=ip; imm=*bb; SPrintF(buf2,"%02X",imm); StrCat(arg2_st,buf2); ip++; break; case ARGT_IMM16: case ARGT_UIMM16: ww=ip; imm=*ww; SPrintF(buf2,"%04X",imm); StrCat(arg2_st,buf2); ip+=2; break; case ARGT_IMM32: case ARGT_UIMM32: dd=ip; imm=*dd; SPrintF(buf2,"%08X",imm); StrCat(arg2_st,buf2); ip+=4; break; case ARGT_IMM64: case ARGT_UIMM64: dddd=ip; imm=*dddd; SPrintF(buf2,"%016X",imm); StrCat(arg2_st,buf2); ip+=8; break; case ARGT_CL: StrCat(arg2_st,"CL"); break; case ARGT_AL: StrCat(arg2_st,"AL"); break; case ARGT_AX: StrCat(arg2_st,"AX"); break; case ARGT_EAX: StrCat(arg2_st,"EAX"); break; case ARGT_DX: StrCat(arg2_st,"DX"); break; case ARGT_SS: StrCat(arg2_st,"SS"); break; case ARGT_DS: StrCat(arg2_st,"DS"); break; case ARGT_ES: StrCat(arg2_st,"ES"); break; case ARGT_FS: StrCat(arg2_st,"FS"); break; case ARGT_GS: StrCat(arg2_st,"GS"); break; case ARGT_CS: StrCat(arg2_st,"CS"); break; } if (*arg1_st) { StrCat(buf,"\t"); StrCat(buf,arg1_st); } if (*arg2_st) { StrCat(buf,","); StrCat(buf,arg2_st); } for (i=ip-*add;i<6;i++) { bin_data_area[i<<1]=CH_SPACE; bin_data_area[i<<1+1]=CH_SPACE; } for (i=ip-*add;i<12;i++) { bin_data_area2[(i-6)<<1]=CH_SPACE; bin_data_area2[(i-6)<<1+1]=CH_SPACE; } StrCat(buf,"\r\n"); if (ip-*add>6) { StrCat(buf,buf3); StrCat(buf,"\r\n"); } *add=ip; } public U1 *Dasm(U1 *ip,U8 cnt=20,I8 seg_size=64) //Disassembles a number of instructions. { I8 i; I1 buf[1024]; for (i=0;i=0 && i=filter_cnt) { PrintF("$$FG,GREEN$$%3d.%02d%% %08X:",routine_total*100/total_time, routine_total*10000/total_time%100,routine_total); PrintF("%s\r\n$$FG$$",last_buf); } StrCpy(last_buf,buf2); routine_total=0; } hits=pf_array[i]; routine_total+=hits; if (hits>=filter_cnt) { PrintF("%3d.%02d%% %08X:",hits*100/total_time, hits*10000/total_time%100,hits); if (!PutSourceLine(ip,ip-last_ip+1)) PrintF("%s\r\n",buf); else CrLf; last_ip=ip; } } if (*last_buf && routine_total>=filter_cnt) { PrintF("$$FG,GREEN$$%3d.%02d%% %08X:",routine_total*100/total_time, routine_total*10000/total_time%100,routine_total); PrintF("%s\r\n$$FG$$",last_buf); } break; case PFM_ALL: QSort(pf_array,pf_ptr,sizeof(U8),&PFACompare); *last_buf=0; for (i=0;i=pf_ptr) break; } SPrintF(buf,"%P",ip); StrCpy(buf3,buf); RemoveFirstSeg(buf3,",",buf2); if (StrCmp(buf2,last_buf)) { if (*last_buf && routine_total>=filter_cnt) { PrintF("$$FG,GREEN$$%3d.%02d%% %08X:",routine_total*100/total_time, routine_total*10000/total_time%100,routine_total); PrintF("%s\r\n$$FG$$",last_buf); } StrCpy(last_buf,buf2); routine_total=0; } routine_total+=hits; if (hits>=filter_cnt) { PrintF("%3d.%02d%% %08X:",hits*100/total_time, hits*10000/total_time%100,hits); if (!PutSourceLine(ip,ip-last_ip+1)) PrintF("%s\r\n",buf); else CrLf; last_ip=ip; } } if (*last_buf && routine_total>=filter_cnt) { PrintF("$$FG,GREEN$$%3d.%02d%% %08X:",routine_total*100/total_time, routine_total*10000/total_time%100,routine_total); PrintF("%s\r\n$$FG$$",last_buf); } break; } prof_mode=mode; } #help_index "Debugging" void ClassRep2(Ltf *l,I1 *class_name,U1 *d,I8 depth,U8 max_depth,U8 types=HTT_CLASS,I8 offset=0) { U8 i,j; MemberListStruct *ml; I1 ch,*s,*s2; U4 *ptr; U8 *ptr2; ClassStruct *cl2,*cl=FindLocalHash(class_name,types); if (depth>=max_depth) return; if (!cl) { LtfPutSExt(l,"Class Not Found.\r\n"); return; } if (!CheckPtr(d) || !CheckPtr(d+cl->size)) { LtfPrintF(l,"Bad Ptr:%016X\r\n",d); return; } LtfPrintF(l,"Class:\"%s\"\r\n",class_name); ml=cl->member_list; while (ml) { cl2=ml->member_class; ptr=d+ml->offset; LtfPrintF(l,"%08X ",ptr+offset); //TODO j=cl2->ptr_cnt; while (cl2->return_class) cl2=cl2->return_class; cl2-=cl2->ptr_cnt*sizeof(ClassStruct); if (cl2->type & HTT_INTERNAL_TYPE) { LtfPrintF(l,"$$FG,GREEN$$%-20ts:$$FG$$",ml->str); if (!j && ml->cnt==0) { switch (cl2->sub_type) { case IT_I1: LtfPrintF(l,"%02X '%c'",ptr->u1[0],ptr->u1[0]); break; case IT_U1: LtfPrintF(l,"%02X",ptr->u1[0]); break; case IT_I2: LtfPrintF(l,"%04X",ptr->u2[0]); break; case IT_U2: LtfPrintF(l,"%04X",ptr->u2[0]); break; case IT_I4: LtfPrintF(l,"%08X",*ptr); break; case IT_U4: LtfPrintF(l,"%08X",*ptr); break; case IT_DOUBLE: ptr2=ptr; LtfPrintF(l,"%16g",*ptr2); break; default: ptr2=ptr; LtfPrintF(l,"%016X",*ptr2); break; } } else if ((j==1 || ml->cnt) && cl2->sub_type==IT_I1) { if (j==1) { if (CheckPtr(*ptr)) { s2=MStrUtil(*ptr,SU_SAFE_DOLLAR); LtfPrintF(l,"\"%40ts\"",s2); Free(s2); } } else { if (ml->cnt<40) s=ptr+ml->cnt; else s=ptr+40; ch=*s; *s=0; s2=MStrUtil(ptr,SU_SAFE_DOLLAR); LtfPrintF(l,"\"%s\"",s2); Free(s2); *s=ch; } } else if (ml->cnt>0 && ml->cnt<=32 && !j) { for (i=0;icnt;i++) { switch (cl2->sub_type) { case IT_I1: LtfPrintF(l,"%02X '%c' ",ptr->u1[0],ptr->u1[0]); ptr+=1; break; case IT_U1: LtfPrintF(l,"%02X ",ptr->u1[0]); ptr+=1; break; case IT_I2: LtfPrintF(l,"%04X ",ptr->u2[0]); ptr+=2; break; case IT_U2: LtfPrintF(l,"%04X ",ptr->u2[0]); ptr+=2; break; case IT_I4: LtfPrintF(l,"%08X ",*ptr); ptr+=4; break; case IT_U4: LtfPrintF(l,"%08X ",*ptr); ptr+=4; break; case IT_DOUBLE: ptr2=ptr; LtfPrintF(l,"%16g ",*ptr2); ptr+=8; break; default: ptr2=ptr; LtfPrintF(l,"%016X ",*ptr2); ptr+=8; break; } } } else LtfPrintF(l,"%016X",*ptr); LtfPutSExt(l,"\r\n"); } else { if (depth<2) { if (j==1 && !CheckPtr(*ptr)) LtfPrintF(l,"%-20ts:%016X\r\n",ml->str,*ptr); else { LtfPrintF(l,"$$TR,\"%s\"$$\r\n",ml->str); LtfPutSExt(l,"$$ID,2$$"); if (!j) ClassRep2(l,cl2->str,ptr,depth+1,max_depth); else if (j==1) ClassRep2(l,cl2->str,*ptr,depth+1,max_depth); LtfPutSExt(l,"$$ID,-2$$"); } } else LtfPrintF(l,"%-20ts\r\n",ml->str); } ml=ml->next; } } public void ClassRep(I1 *class_name,U1 *d,I8 max_depth=2,BoolU4 fun=FALSE,I8 offset=0) //Displays members of a record //by using the compiler's info. { Ltf *l; BoolU4 old_preempt; if (IsRaw) { l=LtfNew; } else { LtfMax; old_preempt=Preempt(OFF); l=Fs->cur_ltf; } if (fun) ClassRep2(l,class_name,d,0,max_depth,HTT_FUNCTION,offset); else ClassRep2(l,class_name,d,0,max_depth,HTT_CLASS,offset); LtfPutSExt(l,"\r\n"); LtfRecalc(l); if (IsRaw) { LtfDump(l,150000); LtfDel(l); } else Preempt(old_preempt); } void RawClassRep(I1 *st,U1 *rbp=NULL,I8 max_depth,BoolU8 is_function,I8 offset=0) { BoolU4 old_raw=Raw(ON); dc_col=0; ClassRep(st,rbp,max_depth,is_function,offset); old_raw=Raw(old_raw); } void UpdateRegVarImg(ClassStruct *cl,U1 *d,TssStruct *tss) { MemberListStruct *ml; ClassStruct *cl2; ml=cl->member_list; while (ml) { if (ml->register>=CREG_RAX) { cl2=ml->member_class; while (cl2->return_class) cl2=cl2->return_class; MemCpy(d+ml->offset,&tss->rax+ml->register*8,cl2->size); } ml=ml->next; } } public void FunRep(I1 *st,U1 *rbp=NULL,I8 max_depth=2,TssStruct *tss=NULL) //Shows names and values of a function's //local variables using info the compiler //has. { I8 size; void *img; ClassStruct *tempc=FindLocalHash(st,HTT_FUNCTION); MemberListStruct *tempm; if (tempc) { if (rbp) { if (tss) { size=tempc->parameter_cnt*8-tempc->size+16; img=MAlloc(size); MemCpy(img,rbp+tempc->size,size); UpdateRegVarImg(tempc,img-tempc->size,tss); ClassRep(st,img-tempc->size,max_depth,TRUE,rbp-img+tempc->size); Free(img); } else ClassRep(st,rbp,max_depth,TRUE); } else { tempm=tempc->member_list; while (tempm) { if (tempm->register==-1) PrintF("%08tX %s\r\n",tempm->offset,tempm->str); else PrintF("%08Z %s\r\n",tempm->register,"ST_U8_REGS",tempm->str); tempm=tempm->next; } PrintF("%08tX Stack Size\r\n",tempc->size); } } } public void DasmFun(I1 *st) { ClassStruct *tempc=FindLocalHash(st,HTT_FUNCTION); DbgInfo *tempd; if (tempc) { FunRep(st); if (tempd=tempc->debug) { Dasm2(tempc->executable_address, tempd->body[tempd->max_line-tempd->min_line+1]- tempc->executable_address); } else Dasm(tempc->executable_address); } } #help_index "Debugging/Breakpoints" SysBpt *FindBpt(TssStruct *tss,U1 *a,U8 flags=ALL_MASK,BoolU4 remove=FALSE) {//Removes SysBpt *result=NULL; U8 old_flags=GetFlags; SysBpt *tempb,*tempb1,*tempb2; Cli; tempb1=&tss->bpt_list; tempb=tss->bpt_list; while (tempb) { tempb2=tempb->next; if (tempb->address==a && tempb->flags & flags) { result=tempb; if (remove) tempb1->next=tempb2; else tempb1=&tempb->next; } else tempb1=&tempb->next; tempb=tempb2; } SetFlags(old_flags); return result; } public BoolU4 SBpt(TssStruct *tss,U1 *a,U8 flags=SBPTF_BPT) //set Bpt //Sets a breakpoint //Honestly, I never use this. I put //output statements to debug, partly //because breakpoints don't work well. //You can configure your $FG,2$Fault.CPZ$FG$ file //in your $FG,2$HOME$FG$ directory to assist debuggting. { U8 old_flags=GetFlags; BoolU4 result=TRUE; SysBpt *tempb; Cli; if (!(tempb=FindBpt(tss,a,flags,FALSE))) { tempb=MAlloc(sizeof(SysBpt),tss); tempb->address=a; tempb->b=*a; tempb->flags=flags; result=FALSE; tempb->next=tss->bpt_list; tss->bpt_list=tempb; if (tss==Fs) *a=0xCC; } SetFlags(old_flags); return result; } public BoolU4 RBpt(TssStruct *tss,U1 *a,U8 flags=ALL_MASK) //Resets (removes) one breakpoint { U8 old_flags=GetFlags; BoolU4 result=FALSE; SysBpt *tempb; Cli; if (tempb=FindBpt(tss,a,flags,TRUE)) { result=TRUE; Free(tempb,tss); } SetFlags(old_flags); return result; } BoolU8 DBpt(TssStruct *tss,U1 *a,U8 flags=ALL_MASK) //disable one Bpt { //used for continuing after a bpt U8 old_flags=GetFlags; BoolU4 result=FALSE; SysBpt *tempb; Cli; if (tempb=FindBpt(tss,a,flags,FALSE)) { Bts(&tempb->flags,SBPTf_DISABLE); result=TRUE; } SetFlags(old_flags); return result; } public void CBpt(TssStruct *tss,U8 flags=ALL_MASK) //clear Bpts //Clear break-point { U1 *a; U8 old_flags=GetFlags; SysBpt *tempb,*tempb1,*tempb2; Cli; tempb=tss->bpt_list; tempb1=&tss->bpt_list; while (tempb) { tempb2=tempb->next; if (tempb->flags & flags) { a=tempb->address; if (tss==Fs) *a=tempb->b; Free(tempb,tss); tempb1->next=tempb2; } else tempb1=&tempb->next; tempb=tempb2; } SetFlags(old_flags); } public void Go() //Continue after breakpoint { TssStruct *tss=Fs->parent_tss; void *rip=&tss->rip; if (!Btr(&tss->task_flags,TSSf_DISABLE_BPTS)) { *rip-=1; if (!DBpt(tss,*rip)) *rip+=1; } Btr(&tss->rflags,8); Btr(&tss->task_flags,TSSf_SUSPENDED); Exit; } public void Step() //Execute single assembly instruction //and stop. { TssStruct *tss=Fs->parent_tss; void *rip=&tss->rip; if (!Bts(&tss->task_flags,TSSf_DISABLE_BPTS)) { *rip-=1; if (!DBpt(tss,*rip)) *rip+=1; } Bts(&tss->rflags,8); Btr(&tss->task_flags,TSSf_SUSPENDED); Exit; } #help_index ""