Пример #1
0
//----------------------------------------------------------------------
// емулятер
int idaapi T900_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);

  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_JUMP) QueueSet(Q_jumps,cmd.ea );

  // поставим изменения
  if ( Feature & CF_CHG1) TouchArg(cmd.Op1, flag1, 0 );
  if ( Feature & CF_CHG2) TouchArg(cmd.Op2, flag2, 0 );
  // если не стоп - продолжим на след. инструкции
  if ( flow) ua_add_cref(0,cmd.ea+cmd.size,fl_F );

  return(1);
}
Пример #2
0
//----------------------------------------------------------------------
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);
      QueueSet(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);
  }
}
Пример #3
0
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 )   QueueSet( 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:
      split_srarea(cmd.ea, WSR,  BADSEL, SR_auto);
      split_srarea(cmd.ea, WSR1, BADSEL, SR_auto);
      break;
  }

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

  return 1;
}
Пример #4
0
void out_print_address(op_t &x, ea_t /*pc*/)
{
  if (!out_name_expr(x, x.addr))
  {
    OutValue(x, OOF_ADDR | OOF_NUMBER | OOFS_NOSIGN);
    QueueSet(Q_noName, cmd.ea);
  }
}
Пример #5
0
//----------------------------------------------------------------------
static void out_bad_address(ea_t addr)
{
  if ( !out_port_address(addr) )
  {
    out_tagon(COLOR_ERROR);
    OutLong(addr, 16);
    out_tagoff(COLOR_ERROR);
    QueueSet(Q_noName, cmd.ea);
  }
}
Пример #6
0
//----------------------------------------------------------------------
static void out_address(ea_t ea, op_t &x)
{
  segment_t *s = getseg(ea);
  ea_t value = s != NULL ? ea - get_segm_base(s) : ea;
  if ( !out_name_expr(x, ea, value) )
  {
    out_tagon(COLOR_ERROR);
    out_snprintf("%a", ea);
    out_tagoff(COLOR_ERROR);
    QueueSet(Q_noName, cmd.ea);
  }
}
Пример #7
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;
}
Пример #8
0
//----------------------------------------------------------------------
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);
    QueueSet(Q_noName, cmd.ea);
  }
}
Пример #9
0
//----------------------------------------------------------------------
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 )
      QueueSet(Q_noName, cmd.ea);
    return 0;
  }
  if ( chkOutLine(buf, tag_strlen(buf)) )
  {
    *rbad = 1;
    return 0;
  }
  return 1;
}
Пример #10
0
//----------------------------------------------------------------------
bool idaapi outop(op_t &x)
{
  uval_t v;

  switch ( x.type )
  {
    case o_imm:
      out_symbol('#');
      OutValue(x, OOFW_IMM);
      break;

    case o_ind_reg:
      out_symbol('@');

    case o_reg:
      OutReg(x.reg);
      break;

    case o_phrase:
//ig: лучше out_keyword, чем простой OutLine()
//    так цвет будет правильный
      out_keyword(phrases[x.phrase]);
      break;

    case o_displ:
      OutValue(x, OOF_ADDR | OOFW_IMM);  // x.addr
      out_symbol('(');
      OutReg(x.reg);
      out_symbol(')');
      break;

    case o_ind_mem:
      out_symbol('@');

    case o_mem:
    case o_near:
      v = map_addr(x.addr, x.n, x.type != o_near);
      if ( !out_name_expr(x, v, x.addr) )
      {
        const char *name = z8_find_ioport(v);
        if ( name != NULL )
        {
          out_line(name, COLOR_IMPNAME);
        }
        else
        {
          OutValue(x, OOF_ADDR | OOF_NUMBER | OOFS_NOSIGN | OOFW_16);
          QueueSet(Q_noName, cmd.ea);
        }
      }
      break;

    case o_void:
      return 0;

    default:
      warning("out: %a: bad optype %d", cmd.ea, x.type);
  }

  return 1;
}
Пример #11
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);
        }
      }