コード例 #1
0
ファイル: emu.cpp プロジェクト: Artorios/IDAplugins-1
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;
}
コード例 #2
0
ファイル: emu.cpp プロジェクト: nealey/vera
//----------------------------------------------------------------------
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;
}
コード例 #3
0
ファイル: emu.cpp プロジェクト: Artorios/IDAplugins-1
void LDD(insn_t &cmd)
{
  int DPR[]={ rDPR0, rDPR1, rDPR2, rDPR3 };

  if ( cmd.Op1.value==0x1 && cmd.Op1.value==0x2 && cmd.Op1.value==0x4 && cmd.Op1.value==0x8 )
  {
       switch ( cmd.Op1.value  )
       {
         case 0x1:
            splitSRarea1(cmd.ea+cmd.size, rDPR0, cmd.Operands[1+0].value, SR_auto);
          break;

         case 0x2:
            splitSRarea1(cmd.ea+cmd.size, rDPR1, cmd.Operands[1+1].value, SR_auto);
          break;

         case 0x4:
            splitSRarea1(cmd.ea+cmd.size, rDPR2, cmd.Operands[1+2].value, SR_auto);
          break;

         case 0x8:
            splitSRarea1(cmd.ea+cmd.size, rDPR3, cmd.Operands[1+3].value, SR_auto);
          break;


       }

  }
  else
  {

    for(int i=0; i<4; i++)
    {
       if( GETBIT(cmd.Op1.value, i) == 1 )
       {
          splitSRarea1(cmd.ea+cmd.size, DPR[i], cmd.Operands[1+i].value, SR_auto);
       } // if
    } //for

  }//else


}
コード例 #4
0
ファイル: emu.cpp プロジェクト: Artorios/IDAplugins-1
//----------------------------------------------------------------------
static void TouchArg( op_t &x, int isload )
{
  switch( x.type )
  {
    case o_imm:
      doImmd(cmd.ea);
      if ( isOff(uFlag, x.n) )
        ua_add_off_drefs2(x, dr_O, OOF_SIGNED);
      break;
    case o_indexed:                                 // addr[value]
      doImmd(cmd.ea);
      if ( x.value == 0 && !isDefArg(uFlag, x.n) )
        set_offset(cmd.ea, x.n, toEA(cmd.cs, 0));
      if ( isOff(uFlag, x.n) )                      // xref to addr
      {
        uval_t saved = x.value;
        x.value = x.addr;
        ua_add_off_drefs2(x, saved ? dr_O : isload ? dr_R : dr_W, OOF_SIGNED|OOF_ADDR);
        x.value = saved;
      }
      if ( x.value != 0 )                           // xref to value
      {                                             // no references to ZERO_REG
        ea_t ea = toEA(cmd.cs, x.value);
        ua_add_dref(x.offb, ea, isload ? dr_R : dr_W );
        ua_dodata2(x.offb, ea, x.dtyp);
      }
      break;
    case o_indirect:
    case o_indirect_inc:
    case o_mem:
      {
        ea_t dea = toEA( cmd.cs, x.addr );
        ua_dodata2(x.offb, dea, x.dtyp);
        if( !isload )
          doVar(dea);
        ua_add_dref( x.offb, dea, isload ? dr_R : dr_W );
        if ( !isload && (x.addr == 0x14 || x.addr == 0x15) )
        {
          sel_t wsrval = BADSEL;
          if ( cmd.Op2.type == o_imm ) wsrval = sel_t(cmd.Op2.value);
          splitSRarea1(cmd.ea, x.addr == 0x14 ? WSR : WSR1, wsrval, SR_auto);
        }
      }
      break;

    case o_near:
      ea_t ea = toEA( cmd.cs, x.addr );
      int iscall = InstrIsSet( cmd.itype, CF_CALL );
      ua_add_cref( x.offb, ea, iscall ? fl_CN : fl_JN );
      if ( flow && iscall )
        flow = func_does_return(ea);
  }
}
コード例 #5
0
ファイル: emu.cpp プロジェクト: nealey/vera
//----------------------------------------------------------------------
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;
}
コード例 #6
0
ファイル: emu.cpp プロジェクト: nealey/vera
//----------------------------------------------------------------------
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;
}
コード例 #7
0
ファイル: emu.cpp プロジェクト: nealey/vera
//----------------------------------------------------------------------
// change value of virtual register "BANK" and switch to another bank
static void split(int reg, sel_t v)
{
    if ( reg == -1 )
    {
        flow = 0;
        if ( v != BADSEL )
        {
            sel_t pclath = getSR(cmd.ea, PCLATH) & 0x1F;
            ea_t ea = calc_code_mem(uchar(v) | (pclath<<8));
            ua_add_cref(0, ea, fl_JN);
        }
    }
    else
    {
        if ( v == BADSEL ) v = 0;     // assume bank0 if bank is unknown
        if ( reg == BANK )
        {
            if ( ptype != PIC16 ) v &= 3;
            else v &= 0xF;
        }
        splitSRarea1(get_item_end(cmd.ea), reg, v, SR_auto);
    }
}
コード例 #8
0
ファイル: emu.cpp プロジェクト: nealey/vera
// 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, (feature & CF_CHG1) != 0 );
    if ( cmd.Op2.type != o_void) handle_operand(cmd.Op2, (feature & CF_CHG2) != 0 );
    if ( cmd.Op3.type != o_void) handle_operand(cmd.Op3, (feature & CF_CHG3) != 0 );

    if ( flow )
        ua_add_cref(0, cmd.ea + cmd.size, fl_F);

    //  Following code will update the current value of the two virtual
    //  segment registers: RW (register window) and RP (register page).

    bool rw_has_changed = false;
    bool rp_has_changed = false;

    switch ( cmd.itype ) {
        case st9_srp:
            {
                sel_t val = cmd.Op1.value;
                if ( val % 2 ) val--;     // even reduced
                splitSRarea1(cmd.ea, rRW, val | (val << 8), SR_auto);
            }
            rw_has_changed = true;
            break;

        case st9_srp0:
            {
                sel_t RW = getSR(cmd.ea, rRW);
                splitSRarea1(cmd.ea, rRW, cmd.Op1.value | (RW & 0xFF00), SR_auto);
            }
            rw_has_changed = true;
            break;

        case st9_srp1:
            {
                sel_t RW = getSR(cmd.ea, rRW);
                splitSRarea1(cmd.ea, rRW, (cmd.Op1.value << 8) | (RW & 0x00FF), SR_auto);
            }
            rw_has_changed = true;
            break;

        case st9_spp:
            splitSRarea1(cmd.ea, rRP, cmd.Op1.value, SR_auto);
            rp_has_changed = true;
            break;
    }

    // If RW / RP registers have changed, print a comment which explains the new mapping of
    // the general registers.

    if ( rw_has_changed && !has_cmt(uFlag) ) {
        char buf[MAXSTR];
        sel_t RW = getSR(cmd.ea, rRW);
        int low = RW & 0x00FF;
        int high = (RW & 0xFF00) >> 8;

        low *= 8;
        high *= 8;

        const char *fmt =
            "r0 -> R%d, r1 -> R%d, r2 -> R%d, r3 -> R%d, r4 -> R%d, r5 -> R%d, r6 -> R%d, r7 -> R%d,\n"
            "r8 -> R%d, r9 -> R%d, r10 -> R%d, r11 -> R%d, r12 -> R%d, r13 -> R%d, r14 -> R%d, r15 -> R%d";

        qsnprintf(buf, sizeof buf, fmt,
            0 + low,
            1 + low,
            2 + low,
            3 + low,
            4 + low,
            5 + low,
            6 + low,
            7 + low,
            8 + high,
            9 + high,
            10 + high,
            11 + high,
            12 + high,
            13 + high,
            14 + high,
            15 + high
        );

        set_cmt(cmd.ea, buf, false);
    }
コード例 #9
0
ファイル: emu.cpp プロジェクト: nealey/vera
//----------------------------------------------------------------------
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 )
        splitSRarea1(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;
}
コード例 #10
0
ファイル: emu.cpp プロジェクト: nealey/vera
//----------------------------------------------------------------------
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;
}