//---------------------------------------------------------------------- int idaapi emu(void) { uint32 Feature = cmd.get_canon_feature(); flow = ((Feature & CF_STOP) == 0); if ( Feature & CF_USE1 ) process_operand(cmd.Op1, true); if ( Feature & CF_USE2 ) process_operand(cmd.Op2, true); if ( Feature & CF_USE3 ) process_operand(cmd.Op3, true); if ( Feature & CF_CHG1 ) process_operand(cmd.Op1, false); if ( Feature & CF_CHG2 ) process_operand(cmd.Op2, false); if ( Feature & CF_CHG3 ) process_operand(cmd.Op3, false); // // Determine if the next instruction should be executed // if ( segtype(cmd.ea) == SEG_XTRN ) flow = 0; if ( flow ) ua_add_cref(0,cmd.ea+cmd.size,fl_F); // // convert "lda imm, reg" to "lda mem, reg" // if ( cmd.itype == I960_lda && cmd.Op1.type == o_imm && !isDefArg(uFlag, 0) && isEnabled(cmd.Op1.value) ) set_offset(cmd.ea, 0, 0); return 1; }
//---------------------------------------------------------------------- int emu(void) { uint32 Feature = cmd.get_canon_feature(); 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_CHG1 ) TouchArg(cmd.Op1, flag1, 0); if ( Feature & CF_CHG2 ) TouchArg(cmd.Op2, flag2, 0); if ( Feature & CF_CHG3 ) TouchArg(cmd.Op3, flag3, 0); // // Determine if the next instruction should be executed // if ( !flow ) flow = may_be_skipped(); if ( segtype(cmd.ea) == SEG_XTRN ) flow = 0; if ( flow ) ua_add_cref(0,cmd.ea+cmd.size,fl_F); return 1; }
//---------------------------------------------------------------------- int idaapi emu(void) { uint32 Feature = cmd.get_canon_feature(); 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 ) process_operand(cmd.Op1, flag1, 1); if ( Feature & CF_USE2 ) process_operand(cmd.Op2, flag2, 1); if ( Feature & CF_USE3 ) process_operand(cmd.Op3, flag3, 1); if ( Feature & CF_CHG1 ) process_operand(cmd.Op1, flag1, 0); if ( Feature & CF_CHG2 ) process_operand(cmd.Op2, flag2, 0); if ( Feature & CF_CHG3 ) process_operand(cmd.Op3, flag3, 0); // // Check for table and generic indirect jumps // if ( cmd.itype == H8_jmp && cmd.Op1.type == o_phrase ) { if ( !check_for_table_jump() ) check_for_generic_indirect_jump(); } if ( cmd.itype == H8_jsr && cmd.Op1.type == o_phrase ) { check_for_generic_indirect_call(); } // // Determine if the next instruction should be executed // if ( segtype(cmd.ea) == SEG_XTRN ) flow = 0; if ( flow ) ua_add_cref(0,cmd.ea+cmd.size,fl_F); // // Handle SP modifications // if ( may_trace_sp() ) { if ( !flow ) recalc_spd(cmd.ea); // recalculate SP register for the next insn else trace_sp(); } return 1; }
//---------------------------------------------------------------------- static void destroy_if_unnamed_array(ea_t ea) { flags_t F = get_flags_novalue(ea); if ( isTail(F) && segtype(ea) == SEG_IMEM ) { ea_t head = prev_not_tail(ea); if ( !has_user_name(get_flags_novalue(head)) ) { do_unknown(head, DOUNK_SIMPLE); doByte(head, ea-head); ea_t end = nextthat(ea, inf.maxEA, f_isHead, NULL); if ( end == BADADDR ) end = getseg(ea)->endEA; doByte(ea+1, end-ea-1); } } }
//---------------------------------------------------------------------- static void process_vector(uint32 ea, const char *name) { set_offset(ea,0,0); set_offset(ea+4,0,0); uint32 mintoc = get_long(ea+4); if ( segtype(mintoc) == SEG_DATA && mintoc < toc_ea ) { toc_ea = mintoc; ph.notify(processor_t::idp_notify(ph.loader+1), toc_ea); } set_name(ea, name); char buf[MAXSTR]; qsnprintf(buf, sizeof(buf), ".%s", name); uint32 code = get_long(ea); add_entry(code, code, buf, 1); make_name_auto(code); }
//---------------------------------------------------------------------- int emu(void) { uint32 feature = cmd.get_canon_feature(); flow = (feature & CF_STOP) == 0; if ((cmd.auxpref & DBrFlag) == 0) // У отложенных переходов не надо обрабатывать операнды, т.к. // регистры и так не обрабатываются, а адр. перехода будет обработан через 3 команды { if ( feature & CF_USE1 ) process_operand(cmd.Op1, 1); if ( feature & CF_USE2 ) process_operand(cmd.Op2, 1); if ( feature & CF_USE3 ) process_operand(cmd.Op3, 1); if ( feature & CF_CHG1 ) process_operand(cmd.Op1, 0); if ( feature & CF_CHG2 ) process_operand(cmd.Op2, 0); if ( feature & CF_CHG3 ) process_operand(cmd.Op3, 0); } if (GetDelayedBranchAdr() != BADADDR) // добавить ссылку по отложенному переходу ua_add_cref(0, toEA(cmd.cs, GetDelayedBranchAdr()), fl_JN); if (cmd.itype == TMS320C3X_RETScond) // добавить ссылку по условному выходу ua_add_cref(0, cmd.ea, fl_JN); // check for DP changes if ( ((cmd.itype == TMS320C3X_LDIcond) || (cmd.itype == TMS320C3X_LDI)) && (cmd.Op1.type == o_imm) && (cmd.Op2.type == o_reg) && (cmd.Op2.reg == dp)) splitSRarea1(get_item_end(cmd.ea), dp, cmd.Op1.value & 0xFF, SR_auto); // determine if the next instruction should be executed if ( segtype(cmd.ea) == SEG_XTRN ) flow = 0; if ( flow && delayed_stop() ) flow = 0; if ( flow ) ua_add_cref(0,cmd.ea+cmd.size,fl_F); if ( may_trace_sp() ) { if ( !flow ) recalc_spd(cmd.ea); // recalculate SP register for the next insn else trace_sp(); } return 1; }
//----------------------------------------------------------------------- static void show_pubdefs(linput_t *li, uint32 offset, uint32 length) { if ( offset == 0 || length == 0 ) return; qlseek(li, offset); for ( int i=0; i < length; ) { pubdef p; const int size = offsetof(pubdef, sym_name); lread(li, &p, size); int nlen = read_pstring(li, p.sym_name, sizeof(p.sym_name)); i += size + 1 + nlen; ea_t sea = getsea(p.PUB_segment); if ( sea != BADADDR ) { sea += p.PUB_offset; add_entry(sea, sea, p.sym_name, segtype(sea) == SEG_CODE); } } }
//---------------------------------------------------------------------- int idaapi emu(void) { if ( segtype(cmd.ea) == SEG_XTRN ) return 1; uint32 Feature = cmd.get_canon_feature(); 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 ) process_operand(cmd.Op1, flag1, 1); if ( Feature & CF_USE2 ) process_operand(cmd.Op2, flag2, 1); if ( Feature & CF_USE3 ) process_operand(cmd.Op3, flag3, 1); if ( Feature & CF_CHG1 ) process_operand(cmd.Op1, flag1, 0); if ( Feature & CF_CHG2 ) process_operand(cmd.Op2, flag2, 0); if ( Feature & CF_CHG3 ) process_operand(cmd.Op3, flag3, 0); fill_additional_args(); for ( int i=0; i < aa.nargs; i++ ) { op_t *x = aa.args[i]; for ( int j=0; j < 2; j++,x++ ) { if ( x->type == o_void ) break; process_operand(*x, 0, j==0); } } // // Determine if the next instruction should be executed // if ( Feature & CF_STOP ) flow = 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; if ( feature & CF_USE1 ) process_operand(cmd.Op1, 1); if ( feature & CF_USE2 ) process_operand(cmd.Op2, 1); if ( feature & CF_USE3 ) process_operand(cmd.Op3, 1); if ( feature & CF_CHG1 ) process_operand(cmd.Op1, 0); if ( feature & CF_CHG2 ) process_operand(cmd.Op2, 0); if ( feature & CF_CHG3 ) process_operand(cmd.Op3, 0); // check for CPL changes if ((cmd.itype == TMS320C54_rsbx1 || cmd.itype == TMS320C54_ssbx1) && cmd.Op1.type == o_reg && cmd.Op1.reg == CPL) splitSRarea1(get_item_end(cmd.ea), CPL, cmd.itype == TMS320C54_rsbx1 ? 0 : 1, SR_auto); // check for DP changes if (cmd.itype == TMS320C54_ld2 && cmd.Op1.type == o_imm && cmd.Op1.dtyp == dt_byte && cmd.Op2.type == o_reg && cmd.Op2.reg == DP) splitSRarea1(get_item_end(cmd.ea), DP, cmd.Op1.value & 0x1FF, SR_auto); // determine if the next instruction should be executed if ( segtype(cmd.ea) == SEG_XTRN ) flow = 0; if ( flow && delayed_stop() ) flow = 0; if ( flow ) ua_add_cref(0,cmd.ea+cmd.size,fl_F); if ( may_trace_sp() ) { if ( !flow ) recalc_spd(cmd.ea); // recalculate SP register for the next insn else trace_sp(); } return 1; }
//---------------------------------------------------------------------- static void process_symbol_class(uint32 ea, uchar sclass, const char *name) { switch ( sclass ) { case kPEFCodeSymbol : case kPEFGlueSymbol : add_entry(ea, ea, name, 1); break; case kPEFTVectSymbol: process_vector(ea, name); break; case kPEFTOCSymbol : if ( segtype(ea) == SEG_DATA && ea < toc_ea ) { toc_ea = ea; ph.notify(processor_t::idp_notify(ph.loader+1), toc_ea); } toc.charset(ea, XMC_TD+1, 1); /* fall thru */ case kPEFDataSymbol : set_name(ea, name); break; } }
//---------------------------------------------------------------------- int idaapi emu(void) { uint32 Feature = cmd.get_canon_feature(); 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 ) process_operand(cmd.Op1, flag1, 1); if ( Feature & CF_USE2 ) process_operand(cmd.Op2, flag2, 1); if ( Feature & CF_USE3 ) process_operand(cmd.Op3, flag3, 1); if ( Feature & CF_CHG1 ) process_operand(cmd.Op1, flag1, 0); if ( Feature & CF_CHG2 ) process_operand(cmd.Op2, flag2, 0); if ( Feature & CF_CHG3 ) process_operand(cmd.Op3, flag3, 0); // // Determine if the next instruction should be executed // if ( segtype(cmd.ea) == SEG_XTRN ) flow = false; // // Handle loads to segment registers // sel_t v = BADSEL; switch ( cmd.itype ) { case H8500_andc: if ( cmd.Op1.value == 0 ) v = 0; goto SPLIT; case H8500_orc: if ( cmd.Op1.value == 0xFF ) v = 0xFF; goto SPLIT; case H8500_ldc: if ( cmd.Op1.type == o_imm ) v = cmd.Op1.value; case H8500_xorc: SPLIT: if ( cmd.Op2.reg >= BR && cmd.Op2.reg <= TP ) split_srarea(cmd.ea+cmd.size, cmd.Op2.reg, v, SR_auto); break; } if ( (Feature & CF_CALL) != 0 ) { ea_t callee = find_callee(); if ( !handle_function_call(callee) ) flow = false; } // // Handle SP modifications // if ( may_trace_sp() ) { func_t *pfn = get_func(cmd.ea); if ( pfn != NULL ) { if ( (pfn->flags & FUNC_USERFAR) == 0 && (pfn->flags & FUNC_FAR) == 0 && is_far_ending() ) { pfn->flags |= FUNC_FAR; update_func(pfn); reanalyze_callers(pfn->startEA, 0); } if ( !flow ) recalc_spd(cmd.ea); // recalculate SP register for the next insn else trace_sp(); } } if ( flow ) ua_add_cref(0, cmd.ea+cmd.size, fl_F); return 1; }
//---------------------------------------------------------------------- int emu(void) { if ( segtype(cmd.ea) == SEG_XTRN ) return 1; //uint32 Feature = cmd.get_canon_feature(); int flag1 = is_forced_operand(cmd.ea, 0); int flag2 = is_forced_operand(cmd.ea, 1); int flag3 = is_forced_operand(cmd.ea, 2); // Determine if the next instruction should be executed flow = (InstrIsSet(cmd.itype, CF_STOP) != true); if ( InstrIsSet(cmd.itype,CF_USE1) ) process_operand(cmd.Op1, flag1, 1); if ( InstrIsSet(cmd.itype,CF_USE2) ) process_operand(cmd.Op2, flag2, 1); if ( InstrIsSet(cmd.itype,CF_USE3) ) process_operand(cmd.Op3, flag3, 1); if ( InstrIsSet(cmd.itype,CF_CHG1) ) process_operand(cmd.Op1, flag1, 0); if ( InstrIsSet(cmd.itype,CF_CHG2) ) process_operand(cmd.Op2, flag2, 0); if ( InstrIsSet(cmd.itype,CF_CHG3) ) process_operand(cmd.Op3, flag3, 0); // check for DP changes if ( cmd.itype == OAK_Dsp_lpg ) splitSRarea1(get_item_end(cmd.ea), PAGE, cmd.Op1.value & 0xFF, SR_auto); if ( ( cmd.itype == OAK_Dsp_mov ) && (cmd.Op1.type == o_imm) && (cmd.Op2.type == o_reg) && (cmd.Op2.reg == ST1) ) splitSRarea1(get_item_end(cmd.ea), PAGE, cmd.Op1.value & 0xFF, SR_auto); //Delayed Return insn_t saved = cmd; cycles = cmd.cmd_cycles; delayed = false; if ( decode_prev_insn(cmd.ea) != BADADDR ) { if ( (cmd.itype == OAK_Dsp_retd) || (cmd.itype == OAK_Dsp_retid) ) delayed = true; else cycles += cmd.cmd_cycles; if (!delayed) if ( decode_prev_insn(cmd.ea) != BADADDR ) if ( (cmd.itype == OAK_Dsp_retd) || (cmd.itype == OAK_Dsp_retid) ) delayed = true; } if (delayed && (cycles > 1) ) flow = 0; cmd = saved; //mov #imm, pc if ( ( cmd.itype == OAK_Dsp_mov ) && (cmd.Op2.type == o_reg) && (cmd.Op2.reg == PC) ) flow = 0; if ( flow ) ua_add_cref(0,cmd.ea+cmd.size,fl_F); if ( may_trace_sp() ) { if ( !flow ) recalc_spd(cmd.ea); // recalculate SP register for the next insn else trace_sp(); } return 1; }
//---------------------------------------------------------------------- int idaapi emu(void) { uint32 Feature = cmd.get_canon_feature(); 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 ) process_operand(cmd.Op1, flag1, 1); if ( Feature & CF_USE2 ) process_operand(cmd.Op2, flag2, 1); if ( Feature & CF_USE3 ) process_operand(cmd.Op3, flag3, 1); if ( Feature & CF_CHG1 ) process_operand(cmd.Op1, flag1, 0); if ( Feature & CF_CHG2 ) process_operand(cmd.Op2, flag2, 0); if ( Feature & CF_CHG3 ) process_operand(cmd.Op3, flag3, 0); // // Check for: // - the register bank changes // - PCLATH changes // - PCL changes // for ( int i=0; i < 3; i++ ) { int reg = 0; switch ( i ) { case 0: reg = BANK; if ( !is_bank() ) continue; break; case 1: reg = PCLATH; if ( !is_pclath() ) continue; break; case 2: reg = -1; if ( !is_pcl() ) continue; break; } sel_t v = (reg == -1) ? cmd.ip : getSR(cmd.ea, reg); if ( cmd.Op2.type == o_reg && cmd.Op2.reg == F ) { // split(reg, v); } else { switch ( cmd.itype ) { case PIC_bcf: case PIC_bcf3: case PIC_bsf: case PIC_bsf3: if ( ((ptype == PIC12) && (cmd.Op2.value == 5) ) // bank selector || ((ptype == PIC14) && ( (reg == BANK && (cmd.Op2.value == 5 || cmd.Op2.value == 6)) || (reg == PCLATH && (cmd.Op2.value == 3 || cmd.Op2.value == 4)))) || ((ptype == PIC16) && (sval_t(cmd.Op2.value) >= 0 && cmd.Op2.value <= 3))) { if ( v == BADSEL ) v = 0; int shift = 0; if ( ptype == PIC14 && reg == BANK ) shift = 5; if ( cmd.itype == PIC_bcf ) v = v & ~(1 << (cmd.Op2.value-shift)); else v = v | (1 << (cmd.Op2.value-shift)); split(reg, v); } break; case PIC_clrf: case PIC_clrf2: split(reg, 0); break; case PIC_swapf: case PIC_swapf3: split(reg, ((v>>4) & 15) | ((v & 15) << 4)); break; case PIC_movwf: case PIC_movwf2: case PIC_addlw: case PIC_andlw: case PIC_iorlw: case PIC_sublw: case PIC_xorlw: { insn_t saved = cmd; if ( decode_prev_insn(cmd.ea) != BADADDR && ( cmd.itype == PIC_movlw ) ) { switch ( saved.itype ) { case PIC_movwf: case PIC_movwf2: v = cmd.Op1.value; break; case PIC_addlw: v += cmd.Op1.value; break; case PIC_andlw: v &= cmd.Op1.value; break; case PIC_iorlw: v |= cmd.Op1.value; break; case PIC_sublw: v -= cmd.Op1.value; break; case PIC_xorlw: v ^= cmd.Op1.value; break; } } else { v = BADSEL; } cmd = saved; } split(reg, v); break; case PIC_movlw: split(reg, cmd.Op2.value); break; } } } // Such as , IDA doesn't seem to convert the following: // tris 6 // into // tris PORTB ( or whatever ) if ( cmd.itype == PIC_tris && !isDefArg0(uFlag) ) set_offset(cmd.ea, 0, dataseg); // movlw value // followed by a // movwf FSR // should convert value into an offset , because FSR is used as a pointer to // the INDF (indirect addressing file) if ( ptype == PIC12 || ptype == PIC14 && cmd.itype == PIC_movwf && cmd.Op1.type == o_mem && (cmd.Op1.addr & 0x7F) == 0x4 ) // FSR { insn_t saved = cmd; if ( decode_prev_insn(cmd.ea) != BADADDR && cmd.itype == PIC_movlw ) { set_offset(cmd.ea, 0, dataseg); } cmd = saved; } // Also - it seems to make sense to me that a // movlw value // followed by a // tris PORTn (or movwf TRISn) // should convert value into a binary , because the bits indicate whether a // port is defined for input or output. if ( is_load_tris_reg() ) { insn_t saved = cmd; if ( decode_prev_insn(cmd.ea) != BADADDR && cmd.itype == PIC_movlw ) { op_bin(cmd.ea, 0); } cmd = saved; } // Move litteral to BSR if ( cmd.itype == PIC_movlb1 ) split(BANK, cmd.Op1.value); // // Determine if the next instruction should be executed // if ( !flow ) flow = conditional_insn(); if ( segtype(cmd.ea) == SEG_XTRN ) flow = 0; if ( flow ) ua_add_cref(0,cmd.ea+cmd.size,fl_F); return 1; }