//---------------------------------------------------------------------- int emu(void) { uint32 Feature = cmd.get_canon_feature(); flow = ((Feature & CF_STOP) == 0); if ( Feature & CF_USE1 ) TouchArg(cmd.Op1,1); if ( Feature & CF_USE2 ) TouchArg(cmd.Op2,1); if ( Feature & CF_JUMP ) QueueMark(Q_jumps,cmd.ea); if ( Feature & CF_CHG1 ) TouchArg(cmd.Op1,0); if ( Feature & CF_CHG2 ) TouchArg(cmd.Op2,0); if ( flow && canFlow() ) ua_add_cref(0,cmd.ea+cmd.size,fl_F); switch ( cmd.itype ) { case TMS_ldp: // change DP register case TMS2_ldp: // change DP register case TMS2_ldpk: // change DP register { uint v = (cmd.Op1.type == o_imm) ? uint(cmd.Op1.value) : -1u; splitSRarea1(get_item_end(cmd.ea),rDP,v,SR_auto); } break; } return 1; }
//---------------------------------------------------------------------- // емулятер int idaapi C39_emu(void) { #if IDP_INTERFACE_VERSION > 37 uint32 Feature = cmd.get_canon_feature(); #else uint32 Feature = Instructions[cmd.itype].feature; uFlag = getFlags(cmd.ea); #endif // получим типы операндов int flag1 = is_forced_operand(cmd.ea, 0); int flag2 = is_forced_operand(cmd.ea, 1); int flag3 = is_forced_operand(cmd.ea, 2); flow = ((Feature & CF_STOP) == 0); // пометим ссылки двух операндов if(Feature & CF_USE1) TouchArg(cmd.Op1, flag1, 1); if(Feature & CF_USE2) TouchArg(cmd.Op2, flag2, 1); if(Feature & CF_USE3) TouchArg(cmd.Op3, flag3, 1); // поставим переход в очередь if(Feature & CF_JUMP) QueueMark(Q_jumps,cmd.ea); // поставим изменения if(Feature & CF_CHG1) TouchArg(cmd.Op1, flag1, 0); if(Feature & CF_CHG2) TouchArg(cmd.Op2, flag2, 0); if(Feature & CF_CHG3) TouchArg(cmd.Op3, flag3, 0); // если не стоп - продолжим на след. инструкции if(flow) ua_add_cref(0,cmd.ea+cmd.size,fl_F); return(1); }
/* outputs an operand 'x' */ bool outop(op_t &x) { // const char *ptr; ea_t v; switch (x.type) { case o_reg: out_register(ph.regNames[x.reg]); break; case o_imm: OutValue(x, OOFS_IFSIGN | OOFW_IMM); break; case o_mem: case o_near: v=toEA(cmd.cs, x.addr); if ( !out_name_expr(x, v, x.addr) ) { OutValue(x, OOF_ADDR | OOF_NUMBER | OOFS_NOSIGN | OOFW_32); QueueMark(Q_noName, cmd.ea); break; } break; default: out_symbol('?'); break; } return 1; }
//---------------------------------------------------------------------- static void out_address(ea_t ea, op_t &x, bool mapping, bool at) { regnum_t reg = get_mapped_register(ea); if ( mapping && reg != rnone) out_register(ph.regNames[reg] ); else { #ifndef TMS320C54_NO_NAME_NO_REF char buf[MAXSTR]; // since tms320c54 uses memory mapping, we turn off verification // of name expression values (3d arg of get_name_expr is BADADDR) if ( get_name_expr(cmd.ea+x.offb, x.n, ea, BADADDR, buf, sizeof(buf)) > 0 ) { if ( at) out_symbol('@' ); OutLine(buf); } else #endif { out_tagon(COLOR_ERROR); OutValue(x, OOFW_IMM|OOF_ADDR); out_tagoff(COLOR_ERROR); QueueMark(Q_noName, cmd.ea); } } }
//---------------------------------------------------------------------- static void outmem(op_t &x, ea_t ea) { char buf[MAXSTR]; if ( get_name_expr(cmd.ea+x.offb, x.n, ea, BADADDR, buf, sizeof(buf)) <= 0 ) { const ioport_t *p = find_sym(x.addr); if ( p == NULL ) { out_tagon(COLOR_ERROR); OutLong(x.addr, 16); out_tagoff(COLOR_ERROR); QueueMark(Q_noName,cmd.ea); } else { out_line(p->name, COLOR_IMPNAME); } } else { bool complex = strchr(buf, '+') || strchr(buf, '-'); if ( complex ) out_symbol(ash.lbrace); OutLine(buf); if ( complex ) out_symbol(ash.rbrace); } }
//---------------------------------------------------------------------- static void out_bad_address(ea_t addr) { out_tagon(COLOR_ERROR); OutLong(addr, 16); out_tagoff(COLOR_ERROR); QueueMark(Q_noName, cmd.ea); }
int idaapi emu( void ) { uint32 Feature = cmd.get_canon_feature(); flow = ((Feature & CF_STOP) == 0); if( Feature & CF_USE1 ) TouchArg( cmd.Op1, 1 ); if( Feature & CF_USE2 ) TouchArg( cmd.Op2, 1 ); if( Feature & CF_USE3 ) TouchArg( cmd.Op3, 1 ); if( Feature & CF_JUMP ) QueueMark( Q_jumps, cmd.ea ); if( Feature & CF_CHG1 ) TouchArg( cmd.Op1, 0 ); if( Feature & CF_CHG2 ) TouchArg( cmd.Op2, 0 ); if( Feature & CF_CHG3 ) TouchArg( cmd.Op3, 0 ); switch ( cmd.itype ) { case I196_popa: splitSRarea1(cmd.ea, WSR, BADSEL, SR_auto); splitSRarea1(cmd.ea, WSR1, BADSEL, SR_auto); break; } if( flow ) ua_add_cref( 0, cmd.ea+cmd.size, fl_F ); return 1; }
//---------------------------------------------------------------------- bool outop( op_t &x ) { uval_t v, v1; // const char *ptr; switch( x.type ) { case o_imm: out_symbol( '#' ); OutValue( x, OOF_SIGNED | OOFW_IMM ); break; case o_indexed: OutValue( x, OOF_ADDR|OOF_SIGNED|(is_ext_insn() ? OOFW_32 : OOFW_16) ); //.addr v = x.value; out_symbol( '[' ); if ( v != 0 ) goto OUTPHRASE; out_symbol( ']' ); break; case o_indirect: case o_indirect_inc: out_symbol( '[' ); case o_mem: case o_near: v = x.addr; OUTPHRASE: v1 = toEA( getSR(cmd.ea, (x.type == o_near) ? rVcs : rVds), v); if( !out_name_expr( x, v1, v ) ) { OutValue( x, (x.type == o_indexed ? 0 : OOF_ADDR) | OOF_NUMBER|OOFS_NOSIGN| ((x.type == o_near) ? (is_ext_insn() ? OOFW_32 : OOFW_16) : OOFW_8) ); QueueMark( Q_noName, cmd.ea ); } if( x.type == o_indirect || x.type == o_indirect_inc || x.type == o_indexed ) { out_symbol( ']' ); if( x.type == o_indirect_inc ) out_symbol( '+' ); } break; case o_void: return 0; case o_bit: out_symbol( char('0' + x.reg) ); break; default: warning( "out: %a: bad optype %d", cmd.ea, x.type ); } return 1; }
//---------------------------------------------------------------------- static void out_address(ea_t ea, op_t &x) { if ( !out_name_expr(x, ea,/* ea */ BADADDR) ) { out_tagon(COLOR_ERROR); OutValue(x, OOFW_IMM|OOF_ADDR|OOFW_16); out_snprintf(" (ea = %a)", ea); out_tagoff(COLOR_ERROR); QueueMark(Q_noName, cmd.ea); } }
//---------------------------------------------------------------------- void OutAddr(op_t& x, ea_t ea, ea_t off, bool isSigned = false) { // try and find the real name expression if ( !out_name_expr(x, ea, off) ) { // work out flags correctly uint32 flags = OOF_ADDR | OOFW_16; if (isSigned) flags |= OOF_SIGNED; else flags |= OOFS_NOSIGN; // if name wasn't found, just output the value & add to noname queue OutValue(x, flags); QueueMark(Q_noName, cmd.ea); } }
//---------------------------------------------------------------------- char outName(ea_t from, int n, ea_t ea, uval_t off, uchar *rbad) { char buf[MAXSTR]; if ( get_name_expr(from, n, ea + off, off, buf, sizeof(buf)) <= 0 ) { if ( loadpass >= 0) QueueMark(Q_noName, cmd.ea ); return(0); } if ( chkOutLine(buf, tag_strlen(buf)) ) { *rbad = 1; return(0); } return(1); }
//---------------------------------------------------------------------- static void out_bad_address(ea_t addr) { const char *name = find_sym((int)addr); if ( name != NULL ) { out_line(name, COLOR_IMPNAME); } else { out_tagon(COLOR_ERROR); OutLong(addr, 16); out_tagoff(COLOR_ERROR); QueueMark(Q_noName, cmd.ea); } }
int emu( void ) { ulong Feature = cmd.get_canon_feature(); flow = ((Feature & CF_STOP) == 0); if( Feature & CF_USE1 ) TouchArg( cmd.Op1, 1 ); if( Feature & CF_USE2 ) TouchArg( cmd.Op2, 1 ); if( Feature & CF_JUMP ) QueueMark( Q_jumps, cmd.ea ); if( Feature & CF_CHG1 ) TouchArg( cmd.Op1, 0 ); if( Feature & CF_CHG2 ) TouchArg( cmd.Op2, 0 ); if( flow ) ua_add_cref( 0, cmd.ea+cmd.size, fl_F ); return 1; }
// emulate an instruction int emu(void) { uint32 feature = cmd.get_canon_feature(); flow = ((feature & CF_STOP) == 0); if (cmd.Op1.type != o_void) handle_operand(cmd.Op1); if (cmd.Op2.type != o_void) handle_operand(cmd.Op2); if (cmd.Op3.type != o_void) handle_operand(cmd.Op3); /* we can't use this code if (feature & CF_USE1) handle_operand(cmd.Op1, 1); if (feature & CF_USE2) handle_operand(cmd.Op2, 1); if (feature & CF_USE3) handle_operand(cmd.Op3, 1); */ // we don't use CF_JUMP //if (feature & CF_JUMP) switch (cmd.itype) { case m740_jmp: case m740_jsr: if (cmd.Op1.type != o_void && is_addr_ind(cmd.Op1)) QueueMark(Q_jumps, cmd.ea); break; } /* if (feature & CF_CHG1) handle_operand(cmd.Op1, 0); if (feature & CF_CHG2) handle_operand(cmd.Op2, 0); if (feature & CF_CHG3) handle_operand(cmd.Op3, 0); */ if (flow) { // skip the next byte if the current insn is brk if (cmd.itype == m740_brk) { ua_add_cref(0, cmd.ea + cmd.size + 1, fl_JN); doByte(cmd.ea + cmd.size, 1); } else { ua_add_cref(0, cmd.ea + cmd.size, fl_F); } } return 1; }
//---------------------------------------------------------------------- int i860_emu(void) { bool funcret = true; uint32 Feature = cmd.get_canon_feature(); if ( Feature & CF_USE1 ) if ( !TouchArg(cmd.Op1,1) ) funcret = false; if ( Feature & CF_USE2 ) if ( !TouchArg(cmd.Op2,1) ) funcret = false; if ( Feature & CF_USE3 ) if ( !TouchArg(cmd.Op3,1) ) funcret = false; if ( Feature & CF_JUMP ) QueueMark(Q_jumps,cmd.ea); if ( Feature & CF_CHG1 ) if ( !TouchArg(cmd.Op1,0) ) funcret = false; if ( Feature & CF_CHG2 ) if ( !TouchArg(cmd.Op2,0) ) funcret = false; if ( Feature & CF_CHG3 ) if ( !TouchArg(cmd.Op3,0) ) funcret = false; if ( funcret && canFlow() ) ua_add_cref(0,cmd.ea+cmd.size,fl_F); return 1; }
// emulate an instruction int idaapi emu(void) { uint32 feature = cmd.get_canon_feature(); flow = ((feature & CF_STOP) == 0); if ( feature & CF_USE1) handle_operand(cmd.Op1, 1 ); if ( feature & CF_USE2) handle_operand(cmd.Op2, 1 ); if ( feature & CF_USE3) handle_operand(cmd.Op3, 1 ); if ( feature & CF_JUMP) QueueMark(Q_jumps, cmd.ea ); if ( feature & CF_CHG1) handle_operand(cmd.Op1, 0 ); if ( feature & CF_CHG2) handle_operand(cmd.Op2, 0 ); if ( feature & CF_CHG3) handle_operand(cmd.Op3, 0 ); if ( flow) ua_add_cref(0, cmd.ea + cmd.size, fl_F ); return 1; }
int emu(void) { uint32 Feature = cmd.get_canon_feature(); flow = ((Feature & CF_STOP) == 0); // you may emulate selected instructions with a greater care: switch ( cmd.itype ) { case I51_mov: if ( cmd.Op1.type == o_mem && cmd.Op1.addr == 0x81 ) // mov SP, #num { if ( cmd.Op2.type == o_imm && !isDefArg(uFlag,1) ) set_offset(cmd.ea,1,intmem); // convert it to an offset } break; case I51_trap: ua_add_cref(0, 0x7B, fl_CN); break; case I51_pop: add_stkpnt(1); break; case I51_push: add_stkpnt(-1); break; } if ( Feature & CF_USE1 ) handle_operand(cmd.Op1, 1); if ( Feature & CF_USE2 ) handle_operand(cmd.Op2, 1); if ( Feature & CF_USE3 ) handle_operand(cmd.Op3, 1); if ( Feature & CF_JUMP ) QueueMark(Q_jumps,cmd.ea); if ( Feature & CF_CHG1 ) handle_operand(cmd.Op1, 0); if ( Feature & CF_CHG2 ) handle_operand(cmd.Op2, 0); if ( Feature & CF_CHG3 ) handle_operand(cmd.Op3, 0); // if the execution flow is not stopped here, then create // a xref to the next instruction. // Thus we plan to analyze the next instruction. if ( flow ) ua_add_cref(0,cmd.ea+cmd.size,fl_F); return 1; // actually the return value is unimportant, but let's it be so }
//---------------------------------------------------------------------- int emu(void) { uint32 Feature = cmd.get_canon_feature(); flow = (Feature & CF_STOP) == 0; int flag1 = is_forced_operand(cmd.ea, 0); int flag2 = is_forced_operand(cmd.ea, 1); int flag3 = is_forced_operand(cmd.ea, 2); if(Feature & CF_USE1) TouchArg(cmd.Op1, flag1, 1); if(Feature & CF_USE2) TouchArg(cmd.Op2, flag2, 1); if(Feature & CF_USE3) TouchArg(cmd.Op3, flag3, 1); if(Feature & CF_JUMP) QueueMark(Q_jumps, cmd.ea); if(Feature & CF_CHG1) TouchArg(cmd.Op1, flag1, 0); if(Feature & CF_CHG2) TouchArg(cmd.Op2, flag2, 0); if(Feature & CF_CHG3) TouchArg(cmd.Op3, flag3, 0); if(flow) ua_add_cref(0, cmd.ea + cmd.size, fl_F); return(1); }
static void OutVarName(op_t &x) { ea_t addr = x.addr; ea_t toea = toEA(codeSeg(addr,x.n), addr); #if IDP_INTERFACE_VERSION > 37 // msg("AT:%a target=%lx, segm=%lx, Result=%lx\n", // cmd.ea,addr, codeSeg(addr,x.n),toea); if ( out_name_expr(x,toea,addr) )return; #else const char *ptr; if ( (ptr=get_name_expr(cmd.ea+x.offb, toea, addr)) != NULL ){ //вывод имен переменных и меток перехода OutLine(ptr); } #endif else{ OutValue(x, OOF_ADDR | OOF_NUMBER | OOFS_NOSIGN | OOFW_32); // пометим проблему - нет имени QueueMark(Q_noName,cmd.ea); } }
bool __stdcall outop( op_t &x ) { char buf[MAXSTR]; switch( x.type ) { case o_imm: { switch(cmd.insnpref) { case SWFACTION_GETURL2: { switch(x.specflag1) { case 'M': if (x.value == 2) out_keyword("method:POST"); else x.value?out_keyword("method:GET"):out_keyword("method:none"); break; case 'T': x.value?out_keyword("target:sprite"):out_keyword("target:browser"); break; case 'V': x.value?out_keyword("vars:load"):out_keyword("vars:no"); } } break; case SWFACTION_CONSTANTPOOL: OutValue( x, OOFW_IMM ); break; case SWFACTION_GOTOFRAME2: if (x.n == 0) { x.value?out_keyword("play:yes"):out_keyword("play:no"); } else { OutValue( x, OOFW_IMM ); } break; case SWFACTION_DEFINEFUNCTION2: if (x.n == 5) { //output the parameters first uint16 p = cmd.auxpref, i = 0; uint16 param_length = get_word(cmd.ea + 1) - p -2; out_char('{', COLOR_SYMBOL); while (i < param_length) { uint8 reg = get_byte(cmd.ea + 3 + p + i); char* reg_name = buf; *reg_name = 0; while ((i++ < param_length) && ((*(reg_name++) = get_byte(cmd.ea + 3 + p + i))!= 0)) {;} i++; if (reg_name > buf && *(--reg_name) == 0) { char r[6]; out_char('{', COLOR_SYMBOL); if (reg) { qsnprintf(r, 5, "r%u", reg); out_register( r ); } else { out_char('0', COLOR_NUMBER); } out_line(",\"", COLOR_SYMBOL); out_line(buf, COLOR_CHAR); out_line("\"}, ", COLOR_SYMBOL); }//if }//while out_line("}, ", COLOR_SYMBOL); } OutValue( x, OOFW_IMM ); break; default: OutValue( x, OOFW_IMM ); } } break; case o_reg: qsnprintf(buf, MAXSTR, "r%u", x.reg); out_register( buf ); break; case o_near: if( !out_name_expr(x, x.addr, x.addr) ) { // if we could not create and output a name expression from the address OutValue(x, OOF_ADDR | OOF_NUMBER | OOFW_32); // instead output a raw value QueueMark(Q_noName, cmd.ea); //and mark this as a problem } break; case o_null: out_keyword("null"); break; case o_undefined: out_keyword("undefined"); break; case o_bool: x.value?out_keyword("true"):out_keyword("false"); break; case o_const: out_keyword("constant:"); OutValue( x, OOFW_IMM ); break; case o_string: { uint16 p = 0; char c; out_char('"', COLOR_SYMBOL); while ((c = get_byte(x.addr+p)) != 0) { if (is_printable(c)) { out_char(c, COLOR_CHAR); } else { qsnprintf(buf, MAXSTR, "\\x%02X", c); out_line(buf, COLOR_STRING); } p++; } out_char('"', COLOR_SYMBOL); } break; case o_void: return 0; default: warning( "out: %lx: bad optype %d", cmd.ea, x.type ); } return 1; }
//---------------------------------------------------------------------- bool outop(op_t &x) { ea_t segadr; switch (x.type) { case o_void: return 0; case o_reg: OutReg(x.reg); break; case o_fpreg: OutReg(x.reg + 8); break; case o_imm: // 27 if(x.ill_imm) { out_symbol('('); OutReg(rPC); out_symbol(')'); out_symbol('+'); } else { out_symbol('#'); if(x.dtyp == dt_float || x.dtyp == dt_double) { char str[MAXSTR]; if(out_real(&x.value, 2, str, sizeof(str))) { register char *p = str; while(*p == ' ') p++; out_symbol('^'); out_symbol('F'); out_line(p, COLOR_NUMBER); } else out_long(x.value, 8); } else OutValue(x, OOF_SIGNED | OOFW_IMM); } break; case o_mem: // 37/67/77 case o_near: // jcc/ [jmp/call 37/67] case o_far: if(x.phrase != 0) { if(x.phrase == 077 || x.phrase == 037) out_symbol('@'); if(x.phrase == 037) out_symbol('#'); if(x.addr16 < m.asect_top && !isOff(uFlag,x.n)) { OutValue(x, OOF_ADDR | OOF_NUMBER | OOFS_NOSIGN | OOFW_16); break; } } segadr = toEA(x.type == o_far ? x.segval : codeSeg(x.addr16,x.n), x.addr16); if(!out_name_expr(x, segadr, x.addr16)) { if(x.type == o_far || x.addr16 < 0160000) QueueMark(Q_noName, cmd.ea); OutValue(x, OOF_ADDR | OOF_NUMBER | OOFS_NOSIGN | OOFW_16); } break; case o_number: //EMT/TRAP/MARK/SPL OutValue(x, OOF_NUMBER | OOFS_NOSIGN | OOFW_8); break; case o_displ: // 6x/7x (!67/!77) if(x.phrase >= 070) out_symbol('@'); OutValue(x, OOF_ADDR | OOF_SIGNED | OOFW_16); out_symbol('('); goto endregout; case o_phrase: // 1x/2x/3x/4x/5x (!27/!37) switch(x.phrase >> 3) { case 1: out_symbol('@'); OutReg(x.phrase & 7); break; case 3: out_symbol('@'); case 2: out_symbol('('); OutReg(x.phrase & 7); out_symbol(')'); out_symbol('+'); break; case 5: out_symbol('@'); case 4: out_symbol('-'); out_symbol('('); endregout: OutReg(x.phrase & 7); out_symbol(')'); break; } break; default: warning("out: %" FMT_EA "o: bad optype %d", cmd.ip, x.type); break; } return 1; }
//---------------------------------------------------------------------- bool outop(op_t &x) { switch(x.type) { case o_void: return 0; case o_reg: if(x.prepost) out_symbol('['); //Вывод регистра по номеру в регистре OutReg(x.reg); if(x.xmode) { out_symbol('+'); OutValue(x, OOF_ADDR | OOF_NUMBER | OOFW_8); } if(x.prepost) out_symbol(']'); break; case o_phrase: OutLine(ph.regNames[x.reg]); break; case o_bit: { switch(x.reg) { case rPSW: { OutLine("PSW."); switch(x.value) { case 0: OutLine("CY");break; case 4: OutLine("AC");break; case 6: OutLine("Z");break; case 7: OutLine("IE");break; default:OutValue(x, OOFW_IMM); } break; } case rA: { OutLine( "A." ); OutChar(char('0'+x.value)); } break; default: { if(!OutVarName(x, 1, 0) ) OutValue(x, OOF_ADDR | OOFW_16); out_symbol('.'); //Ичем название бита по указанному адрессу if(!nec_find_ioport_bit((int)x.addr, (int)x.value)) { //Вывод данных(тип o_imm) OutChar(char('0'+x.value)); } }// switch(x.regmode) } // end switch(x.reg) } break; case o_imm: { if(!x.regmode) { out_symbol('#'); //Вывод данных(тип o_imm) OutValue(x, OOFW_IMM ); } else { out_symbol('1'); } } break; case o_mem: { if(x.addr16) out_symbol('!'); //выводит имя переменной из памяти(например byte_98) //Вывод имени переменной if(!OutVarName(x, 1, 0) ) //Вывод данных OutValue(x, OOF_ADDR | OOFW_16); } break; case o_near: { if(x.addr16) out_symbol('!'); if(x.form) out_symbol('['); //Получить линейный адресс ea_t v = toEA(cmd.cs,x.addr); if(!out_name_expr(x, v, x.addr)) { //Вывести значение OutValue(x, OOF_ADDR | OOF_NUMBER | OOFW_16); QueueMark(Q_noName, cmd.ea); } if(x.form) out_symbol(']'); } break; default: warning("out: %a: bad optype %d", cmd.ip, x.type); break; } return(1); }
//---------------------------------------------------------------------- // вывод одного операнда bool N78K_outop(op_t &x) { #if IDP_INTERFACE_VERSION <= 37 uFlag = getFlags(cmd.ea); #endif switch(x.type){ case o_void: return 0; case o_reg: if(x.FormOut & FORM_OUT_SKOBA) out_symbol('['); OutReg(x.reg); if(x.FormOut & FORM_OUT_PLUS) out_symbol('+'); if(x.FormOut & FORM_OUT_DISP){ if(isOff(uFlag, x.n)){ OutVarNameVal(x); } else OutValue(x, OOFW_IMM ); } if(x.FormOut & FORM_OUT_REG){ out_keyword( ph.regNames[x.SecondReg] ); } if(x.FormOut & FORM_OUT_SKOBA) out_symbol(']'); break; case o_bit: switch(x.FormOut){ case FORM_OUT_S_ADDR: case FORM_OUT_SFR: OutVarName(x); out_symbol('.'); #if IDP_INTERFACE_VERSION > 37 if( !nec_find_ioport_bit(x.addr, x.value) ) #endif { OutValue(x, OOFW_IMM); } break; case FORM_OUT_A: OutLine("A."); OutValue(x, OOFW_IMM); break; case FORM_OUT_PSW: OutLine("PSW."); switch(x.value){ case 0: OutLine("CY");break; case 1: OutLine("ISP");break; case 3: OutLine("RBS0");break; case 4: OutLine("AC");break; case 5: OutLine("RBS1");break; case 6: OutLine("Z");break; case 7: OutLine("IE");break; default:OutValue(x, OOFW_IMM); } break; case FORM_OUT_HL: out_symbol('['); OutReg(rHL); out_symbol(']'); out_symbol('.'); if(isOff(uFlag, x.n)){ OutVarNameVal(x); } else OutValue(x, OOFW_IMM ); break; } break; case o_imm: out_symbol('#'); if(isOff(uFlag, x.n)){ OutVarNameVal(x); } else OutValue(x, OOFW_IMM ); break; case o_mem: //выводит имя переменной из памяти(например byte_98) if(x.FormOut & FORM_OUT_VSK) out_symbol('!'); if(x.FormOut & FORM_OUT_SKOBA) out_symbol('['); //Вывод имени переменной OutVarName(x); if(x.FormOut & FORM_OUT_SKOBA) out_symbol(']'); break; case o_near: if(x.FormOut & FORM_OUT_VSK) out_symbol('!'); if(x.FormOut & FORM_OUT_SKOBA) out_symbol('['); { ulong adr; adr = toEA(codeSeg(x.addr,x.n),x.addr); #if IDP_INTERFACE_VERSION > 37 if( !out_name_expr(x, adr, x.addr)){ OutValue(x, OOF_ADDR | OOF_NUMBER | OOFW_16); QueueMark(Q_noName, cmd.ea); } #else {const char *ptr; ptr=get_name_expr(cmd.ea+x.offb, adr, x.addr); if( ptr == NULL ){ OutValue(x, OOF_ADDR | OOF_NUMBER | OOFW_16); QueueMark(Q_noName, cmd.ea); } else OutLine(ptr); } #endif } if(x.FormOut & FORM_OUT_SKOBA) out_symbol(']'); break; // неизвестный операнд default: warning("out: %lx: bad optype",cmd.ea,x.type); break; } return(1); }
//---------------------------------------------------------------------- int i5_emu(void) { uint32 Feature = cmd.get_canon_feature(); flow = ((Feature & CF_STOP) == 0); if ( (Feature & CF_USE1) ) LoadArg(cmd.Op1); if ( (Feature & CF_USE2) ) LoadArg(cmd.Op2); if ( Feature & CF_JUMP ) QueueMark(Q_jumps,cmd.ea); switch ( cmd.itype ) { case I5_mov: case I5_mvi: case Z80_ld: // if ( ! fail ) R1.doInt( R2.value() ); // else R1.undef(); break; case Z80_jp: case Z80_jr: // Z80 case Z80_ret: // Z80 if ( cmd.Op1.Cond != oc_not ) break; case I5_jmp: if ( cmd.Op2.type == o_phrase ) QueueMark(Q_jumps,cmd.ea); case I5_ret: flow = 0; break; case I5_rstv: ua_add_cref(0,toEA(codeSeg(0x40,0),0x40),fl_CN); break; case I5_rst: { int mul = (isZ80() ? 1 : 8); ushort offset = ushort(cmd.Op1.value * mul); ua_add_cref(0,toEA(codeSeg(offset,0),offset),fl_CN); } case I5_call: case I5_cc: case I5_cnc: case I5_cz: case I5_cnz: case I5_cpe: case I5_cpo: case I5_cp: case I5_cm: case Z80_exx: // Z80 // i5_CPUregs.bc.undef(); // i5_CPUregs.de.undef(); // i5_CPUregs.hl.undef(); // i5_CPUregs.af.undef(); // i5_CPUregs.ix.undef(); // i5_CPUregs.iy.undef(); break; default: // R1.undef(); // R2.undef(); break; } if ( Feature & CF_CHG1 ) SaveArg(cmd.Op1); if ( Feature & CF_CHG2 ) SaveArg(cmd.Op2); if ( flow ) ua_add_cref(0,cmd.ea+cmd.size,fl_F); return 1; }
int idaapi emu() { char szLabel[MAXSTR]; insn_t saved; segment_t* pSegment; ea_t ea, length, offset; flags_t flags; uint32 dwFeature, i; dwFeature = cmd.get_canon_feature(); fFlow = !(dwFeature & CF_STOP); if (dwFeature & CF_USE1) op_emu(cmd.Op1, 1); if (dwFeature & CF_USE2) op_emu(cmd.Op2, 1); if (dwFeature & CF_CHG1) op_emu(cmd.Op1, 0); if (dwFeature & CF_CHG2) op_emu(cmd.Op2, 0); saved = cmd; switch (cmd.itype) { case M8B_MOV: if (!cmd.Op1.is_reg(rPSP)) break; case M8B_SWAP: if (cmd.itype == M8B_SWAP && !cmd.Op2.is_reg(rDSP)) break; for (i = 0; i < 5; ++i) { ea = decode_prev_insn(cmd.ea); if (ea == BADADDR) break; if (cmd.itype == M8B_MOV && cmd.Op1.is_reg(rA) && cmd.Op2.type == o_imm) { ea = toRAM(cmd.Op2.value); if (ea != BADADDR) { qsnprintf(szLabel, sizeof(szLabel), "%s_%0.2X", cmd.itype == M8B_MOV ? "psp" : "dsp", cmd.Op2.value); ua_add_dref(cmd.Op2.offb, ea, dr_O); set_name(ea, szLabel, SN_NOWARN); } break; } } break; case M8B_JACC: pSegment = getseg(cmd.ea); if (!pSegment) break; length = pSegment->endEA - cmd.ea; if (length > 256) length = 256; for (offset = 2; offset < length; offset += 2) { ea = toROM(saved.Op1.addr + offset); if (ea == BADADDR) break; flags = getFlags(ea); if (!hasValue(flags) || (has_any_name(flags) || hasRef(flags)) || !create_insn(ea)) break; switch (cmd.itype) { case M8B_JMP: case M8B_RET: case M8B_RETI: case M8B_IPRET: add_cref(saved.ea, ea, fl_JN); break; default: offset = length; } } break; case M8B_IORD: case M8B_IOWR: case M8B_IOWX: for (i = 0; i < 5; ++i) { ea = (saved.itype == M8B_IORD) ? decode_insn(cmd.ea + cmd.size) : decode_prev_insn(cmd.ea); if (ea == BADADDR) break; if (cmd.Op1.is_reg(rA) && cmd.Op2.type == o_imm) { qsnprintf(szLabel, sizeof(szLabel), "[A=%0.2Xh] ", cmd.Op2.value); if (get_portbits_sym(szLabel + qstrlen(szLabel), saved.Op1.addr, cmd.Op2.value)) set_cmt(saved.ea, szLabel, false); break; } } } cmd = saved; if ((cmd.ea & 0xFF) == 0xFF) { switch (cmd.itype) { case M8B_RET: case M8B_RETI: case M8B_XPAGE: break; default: QueueMark(Q_noValid, cmd.ea); } } if (fFlow) ua_add_cref(0, cmd.ea + cmd.size, fl_F); return 1; }
//---------------------------------------------------------------------- static void out_address(op_t &op) { ea_t ea; if (op.type == o_near) ea = calc_code_mem(op.addr); else if (op.type == o_mem) ea = calc_data_mem(op); else if (op.type == o_io) ea = calc_io_mem(op); int reg = -1; if (op.type == o_mem) reg = get_mapped_register(ea); // print begin of the modifier switch(op.tms_modifier) { case TMS_MODIFIER_NULL: break; case TMS_MODIFIER_DMA: if ((int)reg == -1) out_symbol('@'); break; case TMS_MODIFIER_ABS16: case TMS_MODIFIER_PTR: out_symbol('*'); if (op.tms_modifier == TMS_MODIFIER_ABS16) out_line("abs16", COLOR_SYMBOL); out_line("(#", COLOR_SYMBOL); break; case TMS_MODIFIER_MMAP: out_line("mmap(@", COLOR_SYMBOL); break; case TMS_MODIFIER_PORT: out_line("port(#", COLOR_SYMBOL); break; case TMS_MODIFIER_PORT_AT: out_line("port(@", COLOR_SYMBOL); break; default: error("interr: out: o_address: modifier_begin"); } if (op.type != o_io) { if (int(reg) != -1) // memory mapped register out_register(ph.regNames[reg]); else { #ifndef TMS320C55_NO_NAME_NO_REF if ( !out_name_expr(op, ea, ea) ) #endif { out_tagon(COLOR_ERROR); if (op.type != o_mem) OutLong(op.addr, 16); else OutLong(op.addr, 16); out_tagoff(COLOR_ERROR); QueueMark(Q_noName, cmd.ea); } } } else // IO address { if (ea != BADADDR) { const char *name = NULL; if (idpflags & TMS320C55_IO) name = find_sym(ea); if (name) out_line(name, COLOR_IMPNAME); else OutLong(ea, 16); } else { out_tagon(COLOR_ERROR); OutLong(op.addr, 16); out_tagoff(COLOR_ERROR); } } // print end of the modifier switch(op.tms_modifier) { case TMS_MODIFIER_NULL: case TMS_MODIFIER_DMA: break; case TMS_MODIFIER_ABS16: case TMS_MODIFIER_PTR: case TMS_MODIFIER_MMAP: case TMS_MODIFIER_PORT: case TMS_MODIFIER_PORT_AT: out_symbol(')'); break; default: error("interr: out: o_address: modifier_begin"); } }
bool outop(op_t &x) { uval_t v; int dir, bit; char buf[MAXSTR]; switch ( x.type ) { case o_reg: OutReg(x.reg); break; case o_phrase: if ( x.phrase == fRi ) { out_symbol('@'); OutReg(x.indreg); break; } out_colored_register_line(phrases[x.phrase]); break; case o_displ: out_symbol('@'); OutReg(x.reg); out_symbol('+'); OutValue(x, OOF_ADDR | OOFS_IFSIGN | OOFW_16); break; case o_imm: out_symbol('#'); if ( cmd.auxpref & aux_0ext ) out_symbol('0'); if ( cmd.auxpref & aux_1ext ) out_symbol('1'); OutValue(x, OOFS_IFSIGN | OOFW_IMM); break; case o_mem: case o_near: v = map_addr(x.addr, x.n, x.type==o_mem); if ( get_name_expr(cmd.ea+x.offb, x.n, v, x.addr, buf, sizeof(buf)) <= 0 ) { /* int nbit; if ( cmd.itype == I51_ecall || cmd.itype == I51_ejmp ) nbit = OOFW_32; else nbit = OOFW_16;*/ OutValue(x, OOF_ADDR | OOF_NUMBER | OOFS_NOSIGN | OOFW_32); QueueMark(Q_noName, cmd.ea); break; } // we want to output SFR register names always in COLOR_REG, // so remove the color tags and output it manually: if ( x.type == o_mem && x.addr >= 0x80 ) { tag_remove(buf, buf, sizeof(buf)); out_register(buf); break; } OutLine(buf); break; case o_void: return false; case o_bit251: if ( x.b251_bitneg ) out_symbol('/'); dir = x.addr; bit = x.b251_bit; goto OUTBIT; case o_bitnot: out_symbol('/'); case o_bit: dir = (x.reg & 0xF8); bit = x.reg & 7; if ( (dir & 0x80) == 0 ) dir = dir/8 + 0x20; OUTBIT: if(ash.uflag & UAS_PBIT) { const ioport_bit_t *predef = find_bit( dir, bit); if ( predef != NULL ) { out_line(predef->name, COLOR_REG); break; } } { v = map_addr(dir, x.n, true); ssize_t len = get_name_expr(cmd.ea+x.offb, x.n, v, dir, buf, sizeof(buf)); if ( len > 0 && strchr(buf, '+') == NULL ) { // we want to output the bit names always in COLOR_REG, // so remove the color tags and output it manually: if ( dir < 0x80 ) { OutLine(buf); } else { tag_remove(buf, buf, sizeof(buf)); out_register(buf); } } else { out_long(dir, 16); } out_symbol(ash.uflag & UAS_NOBIT ? '_' : '.'); out_symbol('0'+bit); } break; default: warning("out: %a: bad optype",cmd.ea,x.type); break; } return true; }