Beispiel #1
0
// 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;
}
Beispiel #2
0
// Emulate an instruction.
int idaapi emu(void) {
    bool flow = !is_stop() || (cmd.auxpref & INSN_DELAY_SHOT);
    if ( flow )
    {
      insn_t cmd_backup = cmd;
      if ( decode_prev_insn(cmd.ea) != BADADDR ) {
          flow = !(is_stop() && (cmd.auxpref & INSN_DELAY_SHOT));
      }
      cmd = cmd_backup;
    }

    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 );
    if ( cmd.Op4.type != o_void)            handle_operand(cmd.Op4 );

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

    return 1;
}
Beispiel #3
0
int parse_ld_line(ld_line_t line) {
    int rv = PLC_OK;
    if(line == (ld_line_t)NULL)
        return PLC_ERR;    
    
    int c = LD_AND; //default character = '-'
    BYTE n_mode = FALSE;
    
    while (line->status == STATUS_UNRESOLVED 
    && c != LD_NODE) {	//loop	    
		c = read_char(line->buf, line->cursor);
		switch (c) {
		    case LD_NODE://PAUSE
				break;	
			case ERR_BADCHAR:
			case (BYTE)PLC_ERR:
				rv = PLC_ERR;
				line->status = STATUS_ERROR;
				break;
            case OP_END:/*this should happen only if line ends without 
                           a valid coil*/
				line->status = STATUS_RESOLVED;
				line->stmt = NULL;//clear_tree(line->stmt);
				break;
            case LD_OR:
            case LD_BLANK://if blank or '|', empty value for the line.
				line->cursor++;
				line->stmt = NULL;//clear_tree(line->stmt);
				break;
		    case LD_NOT:
				n_mode = TRUE;	//normally closed mode
            case LD_AND:
				line->cursor++;
				break;
			case LD_COIL://see if it is a coil: ()[] 
            case LD_SET:
            case LD_RESET:
            case LD_DOWN:
				rv = handle_coil(c, line);
				break;
            default://otherwise operand is expected(i,q,f,r,m,t,c,b)
                rv = handle_operand(c, n_mode, line);
                n_mode = FALSE;
                break;
        }
    }
    if(rv < PLC_OK)
        line->stmt = clear_tree(line->stmt);
    return rv;
}
Beispiel #4
0
int
idaapi emu(void)
{
        int  features;

        //
        // Determine the current instruction's features.
        //
        features = cmd.get_canon_feature();
        bool flow = (features & CF_STOP) == 0;

        //
        // Examine each operand and determine what effect, if any,
        // it makes on the environment.
        //
        // Operands that are read
        if ( features & CF_USE1 )
                flow &= handle_operand(cmd.Op1, hop_READ);
        if ( features & CF_USE2 )
                flow &= handle_operand(cmd.Op2, hop_READ);
        if ( features & CF_USE3 )
                flow &= handle_operand(cmd.Op3, hop_READ);
        // Operands that are written
        if ( features & CF_CHG1 )
                flow &= handle_operand(cmd.Op1, hop_WRITE);
        if ( features & CF_CHG2 )
                flow &= handle_operand(cmd.Op2, hop_WRITE);
        if ( features & CF_CHG3 )
                flow &= handle_operand(cmd.Op3, hop_WRITE);

        //
        // Determine whether the instruction stops the execution flow.
        //
        if ( flow ) {
                //
                // This instruction doesn't stop execution flow.
                // Add a cross reference to the next instrction.
                //
                ua_add_cref(0,cmd.ea+cmd.size,fl_F);
        }

        //
        // If the instruction makes a branch, let the IDA kernel
        // know.
        //
        if ( features & CF_JUMP )
                QueueSet(Q_jumps, cmd.ea);

        return 1;
}
Beispiel #5
0
// 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;
}
Beispiel #6
0
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
}
Beispiel #7
0
// 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);
    }
Beispiel #8
0
//----------------------------------------------------------------------
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_CHG1 ) handle_operand(cmd.Op1, 0);
  if ( Feature & CF_CHG2 ) handle_operand(cmd.Op2, 0);
  if ( Feature & CF_JUMP )
    QueueSet(Q_jumps, cmd.ea);

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

  uint8 code = get_byte(cmd.ea);
  const struct opcode_info_t &opinfo = get_opcode_info(code);

  if ( opinfo.itype == M65816_jmp || opinfo.itype == M65816_jsr )
  {
    if ( opinfo.addr == ABS_INDIR
      || opinfo.addr == ABS_INDIR_LONG
      || opinfo.addr == ABS_IX_INDIR )
    {
      QueueSet(Q_jumps,cmd.ea);
    }
  }

#if 0
  switch ( opinfo.addr )
  {
    case ABS_LONG_IX:
      {
        ea_t orig_ea = cmd.Op1.addr;
        ea_t ea = xlat(orig_ea);

        bool read_access;
        if ( cmd.itype == M65816_sta )
          read_access = false;
        else
          read_access = true;

        if ( !read_access )
          doVar(ea);
        ua_add_dref(cmd.Op1.offb, ea, read_access ? dr_R : dr_W);
        break;
      }

    case DP:
      {
        bool read_access;
        if ( cmd.itype == M65816_tsb || cmd.itype == M65816_asl || cmd.itype == M65816_trb
          || cmd.itype == M65816_rol || cmd.itype == M65816_lsr || cmd.itype == M65816_ror
          || cmd.itype == M65816_dec || cmd.itype == M65816_inc )
          read_access = false;
        else
          read_access = true;

        int32 val = backtrack_value(cmd.ea, 2, BT_DP);
        if ( val != -1 )
        {
          ea_t orig_ea = val + cmd.Op1.addr;
          ea_t ea = xlat(orig_ea);

          ua_dodata2(cmd.Op1.offb, ea, cmd.Op1.dtyp);
          if ( !read_access )
            doVar(ea);
          ua_add_dref(cmd.Op1.offb, ea, read_access ? dr_R : dr_W);
        }
      }
      break;
  }
#endif

  switch ( cmd.itype )
  {
    case M65816_sep:
    case M65816_rep:
      {
        // Switching 8 -> 16 bits modes.
        uint8 flag_data = get_byte(cmd.ea + 1);
        uint8 m_flag = flag_data & 0x20;
        uint8 x_flag = flag_data & 0x10;
        uint8 val    = (cmd.itype == M65816_rep) ? 0 : 1;

        if ( m_flag )
          split_srarea(cmd.ea + 2, rFm, val, SR_auto);
        if ( x_flag )
          split_srarea(cmd.ea + 2, rFx, val, SR_auto);
      }
      break;

    case M65816_xce:
      {
        // Switching to native mode?
        uint8 prev = get_byte(cmd.ea - 1);
        const struct opcode_info_t &opinf = get_opcode_info(prev);
        if ( opinf.itype == M65816_clc )
          split_srarea(cmd.ea + 1, rFe, 0, SR_auto);
        else if ( opinf.itype == M65816_sec )
          split_srarea(cmd.ea + 1, rFe, 1, SR_auto);
      }
      break;

    case M65816_jmp:
    case M65816_jml:
    case M65816_jsl:
    case M65816_jsr:
      {
        if ( cmd.Op1.full_target_ea )
        {
          ea_t ftea = cmd.Op1.full_target_ea;
          if ( cmd.itype != M65816_jsl && cmd.itype != M65816_jml )
            ftea = toEA(codeSeg(ftea, 0), ftea);
          else
            ftea = xlat(ftea);

          split_srarea(ftea, rFm,  get_segreg(cmd.ea, rFm),  SR_auto);
          split_srarea(ftea, rFx,  get_segreg(cmd.ea, rFx),  SR_auto);
          split_srarea(ftea, rFe,  get_segreg(cmd.ea, rFe),  SR_auto);
          split_srarea(ftea, rPB,  ftea >> 16,               SR_auto);
          split_srarea(ftea, rB,   get_segreg(cmd.ea, rB),   SR_auto);
          split_srarea(ftea, rDs,  get_segreg(cmd.ea, rDs),  SR_auto);
          split_srarea(ftea, rD,   get_segreg(cmd.ea, rD),   SR_auto);
        }
      }
      break;

    case M65816_plb:
      {
        int32 val = backtrack_value(cmd.ea, 1, BT_STACK);
        if ( val != -1 )
        {
          split_srarea(cmd.ea + cmd.size, rB, val, SR_auto);
          split_srarea(cmd.ea + cmd.size, rDs, val << 12, SR_auto);
        }
      }
      break;

    case M65816_pld:
      {
        int32 val = backtrack_value(cmd.ea, 2, BT_STACK);
        if ( val != -1 )
          split_srarea(cmd.ea + cmd.size, rD, val, SR_auto);
      }
      break;

    case M65816_plp:
      {
        // Ideally, should pass another parameter, specifying when to stop
        // backtracking.
        // For example, in order to avoid this:
        //     PHP
        //     PLP <-- this one is causing interference
        //             (dunno if that even happens, though)
        //     PLP
        ea_t ea = backtrack_prev_ins(cmd.ea, M65816_php);
        if ( ea != BADADDR )
        {
          uint16 p = get_cpu_status(ea);
          split_srarea(cmd.ea + cmd.size, rFm, (p >> 5) & 0x1, SR_auto);
          split_srarea(cmd.ea + cmd.size, rFx, (p >> 4) & 0x1, SR_auto);
        }
      }