コード例 #1
0
ファイル: emu.cpp プロジェクト: nealey/vera
//----------------------------------------------------------------------
static void process_operand(op_t &x,int isAlt,int isload)
{
  switch ( x.type )
  {
    case o_reg:
      break;
    default:
//      interr("emu");
      break;
    case o_imm:

//      if ( !isload ) interr("emu2");
        process_immediate_number(x.n);
        if ( isOff(uFlag, x.n) )
          ua_add_off_drefs2(x, dr_O, x.amode & amode_signed ? OOF_SIGNED : 0);
        break;

    case o_phrase:
      if ( !isAlt && isOff(uFlag, x.n) )
      {
        ua_add_off_drefs2(x, isload ? dr_R : dr_W, OOF_ADDR);
        ea_t ea = calc_target(cmd.ea+x.offb, cmd.ea, x.n, x.addr);
        ua_dodata2(x.offb, ea, x.dtyp);
        if ( !isload ) doVar(ea);
      }
      break;
    case o_mem:
      {
        ea_t ea = calc_mem(x);
        ua_add_dref(x.offb, ea, isload ? dr_R : dr_W);
        ua_dodata2(x.offb, ea, x.dtyp);
        if ( !isload ) doVar(ea);
      }
      break;
    case o_near:
      add_near_ref(x, calc_mem(x));
      break;
    case o_textphrase:
      break;

    case o_local: // local variables
      if ( may_create_stkvars() )
      {
         func_t *pfn = get_func(cmd.ea);
         if ( (pfn != NULL) && (pfn->flags & FUNC_FRAME) && ua_stkvar2(x, x.addr, STKVAR_VALID_SIZE) )
                        op_stkvar(cmd.ea, x.n);
      }
      break;

  }
}
コード例 #2
0
ファイル: emu.cpp プロジェクト: trietptm/usefulres
static void TouchArg( op_t &x, int isload )
{
  switch( x.type )
  {
    case o_imm:
    case o_displ:
      if ( isOff(uFlag, x.n) ) ua_add_off_drefs(x, dr_O);
      break;

    case o_mem:
    case o_ind_mem:
      {
        ulong dea = intmem + x.addr;
        ua_dodata( dea, x.dtyp );
        if( !isload )   doVar( dea );
        ua_add_dref( x.offb, dea, isload ? dr_R : dr_W );
      }
      break;

    case o_near:
      ulong 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 )
      {
        if ( !func_does_return(ea) )
          flow = false;
      }
  }
}
コード例 #3
0
ファイル: emu.cpp プロジェクト: Artorios/IDAplugins-1
static void TouchArg( op_t &x, int isload )
{
  switch( x.type )
  {
    case o_displ:
    case o_imm:
      if ( isOff(uFlag, x.n) )
      {
        int outf = x.type != o_imm ? OOF_ADDR : 0;
        ua_add_off_drefs2(x, dr_O, outf|OOF_SIGNED);
      }
      break;

    case o_mem:
    case o_ind_mem:
      {
        ea_t dea = intmem + x.addr;
        ua_dodata2(x.offb, dea, x.dtyp);
        if( !isload )
          doVar( dea );
        ua_add_dref( x.offb, dea, isload ? dr_R : dr_W );
      }
      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 )
      {
        if ( !func_does_return(ea) )
          flow = false;
      }
  }
}
コード例 #4
0
//----------------------------------------------------------------------
static void process_operand(op_t &x,int isAlt,int isload)
{
  switch ( x.type )
  {
    case o_reg:
      break;
    default:
//      interr("emu");
      break;
    case o_imm:
      process_immediate_number(x.n);
      if ( op_adds_xrefs(uFlag, x.n) )
        ua_add_off_drefs2(x, dr_O, OOFS_IFSIGN);
      break;
    case o_phrase:
      if ( !isAlt && op_adds_xrefs(uFlag, x.n) )
      {
        ea_t ea = ua_add_off_drefs2(x, isload ? dr_R : dr_W, OOF_ADDR);
        if ( ea != BADADDR )
        {
          ua_dodata2(x.offb, ea, x.dtyp);
          if ( !isload )
            doVar(ea);
        }
      }
      break;
    case o_mem:
      {
        ea_t ea = calc_mem(x);
        ua_add_dref(x.offb, ea, isload ? dr_R : dr_W);
        ua_dodata2(x.offb, ea, x.dtyp);
        if ( !isload )
          doVar(ea);
        if ( x.amode & amode_l )
        {
          ea = ymem + x.addr;
          ua_add_dref(x.offb, ea, isload ? dr_R : dr_W);
          ua_dodata2(x.offb, ea, x.dtyp);
        }
      }
      break;
    case o_near:
      add_near_ref(x, calc_mem(x));
      break;
  }
}
コード例 #5
0
//----------------------------------------------------------------------
static void TouchArg(op_t &x, int isload)
{
  switch ( x.type )
  {
    case o_displ:
    case o_imm:
      if ( op_adds_xrefs(uFlag, x.n) )
      {
        int outf = x.type != o_imm ? OOF_ADDR : 0;
        ua_add_off_drefs2(x, dr_O, outf|OOF_SIGNED);
      }
      break;

    case o_mem:
    case o_ind_mem:
    case o_reg:
    case o_ind_reg:
      {
        ea_t dea;
        if ( x.type == o_mem || x.type == o_ind_mem )
        {
          dea = map_addr(x.addr, x.n, true);
        }
        else
        {
          if ( x.reg >= rRR0 )
            dea = map_addr(x.reg - rRR0, x.n, true);
          else
            dea = map_addr(x.reg - rR0, x.n, true);
        }
        ua_dodata2(x.offb, dea, x.dtyp);
        if ( !isload )
          doVar(dea);
        ua_add_dref(x.offb, dea, isload ? dr_R : dr_W);
        if ( !has_user_name(get_flags_novalue(dea)) && dea > intmem)
        {
          char buf[10];
          int num = dea - intmem;
          if ( num < 0x100 )
          {
            qsnprintf(buf, sizeof(buf), "R%d", num);
          }
          else if ( num < 0x1000 )
          {
            qsnprintf(buf, sizeof(buf), "ERF_%X_%d", num >> 8, num & 0xFF);
          }
          else
          {
            int reg_no     = ((num >> 4) & 0xF0) + (num & 0xF);
            int subbank_no = ((num >> 4) & 0xF) + 1;
            qsnprintf(buf, sizeof(buf), "R%d_%X", reg_no, subbank_no);
          }
          set_name(dea, buf, SN_NOWARN);
        }
コード例 #6
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);
  }
}
コード例 #7
0
ファイル: emu.cpp プロジェクト: awesome-security/vera
//----------------------------------------------------------------------
static void TouchArg(op_t &x,int isAlt,int isload)
{
  switch ( x.type )
  {
    case o_reg:
    case o_phrase:
    case o_port:
      break;
    case o_imm:
      if ( !isload ) goto badTouch;
      doImmdValue(x.n);
      if ( isOff(uFlag, x.n) )
        ua_add_off_drefs2(x, dr_O, OOF_SIGNED);
      break;
    case o_displ:
      doImmdValue(x.n);
      if ( isAlt ) break;
      if ( isOff(uFlag, x.n) )
      {
        ua_add_off_drefs2(x, isload ? dr_R : dr_W, OOF_ADDR);
        ea_t ea = calc_target(cmd.ea+x.offb, cmd.ea, x.n, x.addr);
        ua_dodata2(x.offb, ea, x.dtyp);
        if ( !isload )
          doVar(ea);
      }
      break;
    case o_near:
      {
        cref_t ftype = fl_JN;
        ea_t ea = toEA(cmd.cs, x.addr);
        if ( InstrIsSet(cmd.itype, CF_CALL) )
        {
          if ( !func_does_return(ea) )
            flow = false;
          ftype = fl_CN;
        }
        ua_add_cref(x.offb, ea, ftype);
      }
      break;
    case o_mem:
      {
        ea_t ea = toEA(dataSeg(), x.addr);
        ua_add_dref(x.offb, ea, isload ? dr_R : dr_W);
      }
      break;
    default:
badTouch:
      if ( cmd.itype != AVR_lpm && cmd.itype != AVR_elpm )
        warning("%a: %s,%d: bad optype %d", cmd.ea, cmd.get_canon_mnem(), x.n, x.type);
      break;
  }
}
コード例 #8
0
ファイル: emu.cpp プロジェクト: nealey/vera
//----------------------------------------------------------------------
static bool TouchArg(op_t &x,int isload)
{
  dref_t xreftype;
  uchar outf;
  switch ( x.type )
  {
  case o_phrase:                // 2 registers
  case o_reg:
    break;
  case o_imm:
    if ( !isload )
      goto badTouch;
    xreftype = dr_O;
    outf = OOF_SIGNED;
    goto makeImm;
  case o_displ:
    xreftype = isload ? dr_R : dr_W;
    outf = OOF_SIGNED|OOF_ADDR;
makeImm:
    doImmdValue();
    if ( op_adds_xrefs(uFlag, x.n) )
      ua_add_off_drefs2(x, xreftype, outf);
    break;
  case o_mem:
    ua_dodata2(x.offb, x.addr, x.dtyp);
    if ( !isload )
      doVar(x.addr);
    ua_add_dref(x.offb,x.addr,isload ? dr_R : dr_W);
    break;
  case o_near:
    {
      int iscall = InstrIsSet(cmd.itype,CF_CALL);
      ua_add_cref(x.offb,x.addr,iscall ? fl_CN : fl_JN);
      if ( iscall && !func_does_return(x.addr) )
        return false;
    }
    break;
  default:
badTouch:
    warning("%a: %s,%d: bad optype %d", cmd.ea, cmd.get_canon_mnem(), x.n, x.type);
    break;
  }
  return true;
}
コード例 #9
0
ファイル: emu.cpp プロジェクト: nealey/vera
//----------------------------------------------------------------------
static void SaveArg(op_t &x)
{
  switch ( x.type )
  {
    case o_reg:
      {
//        if ( x.reg == R_sp ) return;
//        AbstractRegister *out = &i5_getreg(x.reg);
//        if ( ! isDef(r) ) {
//          out->undef();
//        } else {
//          out->doInt(r.value());
//        }
        return;
      }
    case o_mem:
      {
        ea_t ea = toEA(dataSeg_op(x.n),x.addr);
        ua_dodata2(x.offb, ea, x.dtyp);
        doVar(ea);
        ua_add_dref(x.offb,ea,dr_W);
      }
      break;
    case o_displ:
      doImmdValue(x.n);
      if ( isOff(uFlag, x.n) )
        ua_add_off_drefs2(x, dr_W, OOF_ADDR);
    case o_phrase:
      break;
    default:
      switch ( cmd.itype )
      {
        case Z80_in0:
        case Z80_outaw:
          break;
        default:
//        warning("%a: %s,%d: bad save optype %d", cmd.ea, cmd.get_canon_mnem(), x.n, x.type);
          break;
      }
      break;
  }
}
コード例 #10
0
//----------------------------------------------------------------------
static void process_operand(op_t &x,int isAlt,int isload)
{
  switch ( x.type )
  {
    case o_reg:
    case o_reglist:
      return;
    case o_imm:
      QASSERT(10090, isload);
      process_immediate_number(x.n);
      if ( op_adds_xrefs(uFlag, x.n) )
        ua_add_off_drefs2(x, dr_O, calc_opimm_flags());
      break;
    case o_phrase:
    case o_displ:
      process_immediate_number(x.n);
      if ( isAlt ) break;
      if ( op_adds_xrefs(uFlag, x.n) )
      {
        ea_t ea = ua_add_off_drefs2(x, isload ? dr_R : dr_W, calc_opdispl_flags());
        if ( ea != BADADDR )
        {
          ua_dodata2(x.offb, ea, x.dtyp);
          if ( !isload )
            doVar(ea);
        }
      }
      // create stack variables if required
      if ( x.type == o_displ
        && may_create_stkvars()
        && !isDefArg(uFlag, x.n) )
      {
        func_t *pfn = get_func(cmd.ea);
        if ( pfn != NULL
          && (issp(x.phrase)
              || isbp(x.phrase) && (pfn->flags & FUNC_FRAME) != 0) )
        {
          if ( ua_stkvar2(x, x.addr, STKVAR_VALID_SIZE) )
            op_stkvar(cmd.ea, x.n);
        }
      }
      break;
    case o_near:
    case o_far:
      {
        cref_t ftype = x.type == o_near ? fl_JN : fl_JF;
        ea_t ea = calc_mem(x);
        if ( InstrIsSet(cmd.itype, CF_CALL) )
        {
          if ( !func_does_return(ea) )
            flow = false;
          ftype = x.type == o_near ? fl_CN : fl_CF;
        }
        ua_add_cref(x.offb, ea, ftype);
      }
      break;
    case o_mem:
      {
        ea_t ea = calc_mem(x);
        ua_add_dref(x.offb, ea, isload ? dr_R : dr_W);
        ua_dodata2(x.offb, ea, x.dtyp);
        if ( !isload ) doVar(ea);
      }
      break;
    default:
      INTERR(10091);
  }
}
コード例 #11
0
ファイル: emu.cpp プロジェクト: IDA-RE-things/ida-H8
//----------------------------------------------------------------------
static void process_operand(op_t &x,int isAlt,int isload)
{
  switch ( x.type )
  {
    case o_reg:
    case o_phrase:
    case o_reglist:
      return;
    case o_imm:
      QASSERT(10094, isload);
      process_immediate_number(x.n);
      if ( op_adds_xrefs(uFlag, x.n) )
        ua_add_off_drefs2(x, dr_O, OOFS_IFSIGN|OOFW_IMM);
      break;
    case o_displ:
      process_immediate_number(x.n);
      if ( isAlt )
        break;
      if ( op_adds_xrefs(uFlag, x.n) )
      {
        ea_t ea = ua_add_off_drefs2(x, isload ? dr_R : dr_W, get_displ_outf(x));
        if ( ea != BADADDR )
        {
          ua_dodata2(x.offb, ea, x.dtyp);
          if ( !isload )
            doVar(ea);
        }
      }
      // create stack variables if required
      if ( may_create_stkvars() && !isDefArg(uFlag, x.n) )
      {
        func_t *pfn = get_func(cmd.ea);
        if ( pfn != NULL
          && (issp(x.phrase)
              || isbp(x.phrase) && (pfn->flags & FUNC_FRAME) != 0) )
        {
          if ( ua_stkvar2(x, x.addr, STKVAR_VALID_SIZE) )
            op_stkvar(cmd.ea, x.n);
        }
      }
      break;
    case o_near:
      add_code_xref(x, calc_mem(x.addr));
      break;
    case o_mem:
    case o_memind:
      {
        ea_t ea = calc_mem(x.addr);
        if ( !isEnabled(ea) && find_sym(ea) ) break;    // address not here
        ua_add_dref(x.offb, ea, isload ? dr_R : dr_W);
        ua_dodata2(x.offb, ea, x.dtyp);
        if ( x.type == o_memind )
        {
          ssize_t size = get_dtyp_size(x.dtyp);
          flags_t F = getFlags(ea);
          if ( (isWord(F) || isDwrd(F))
            && (!isDefArg0(F) || isOff0(F)) )
          {
            ea_t target = calc_mem(size == 2
                                ? get_word(ea)
                                : (get_long(ea) & 0xFFFFFFL));
            if ( isEnabled(target) ) add_code_xref(x, target);
            if ( !isOff0(F) )
              set_offset(ea, 0, calc_mem(0));
          }
          break;
        }
        if ( !isload ) doVar(ea);
      }
      break;
    default:
      INTERR(10095);
  }
}
コード例 #12
0
ファイル: emu.cpp プロジェクト: Aliandrana/ida-65816-module
//----------------------------------------------------------------------
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);
        }
      }
コード例 #13
0
ファイル: emu.cpp プロジェクト: Aliandrana/ida-65816-module
//----------------------------------------------------------------------
static void handle_operand(op_t &x, bool read_access)
{
  ea_t ea;
  dref_t dreftype;
  switch ( x.type )
  {
    case o_void:
    case o_reg:
      break;

    case o_imm:
      QASSERT(557, read_access);
      dreftype = dr_O;
MAKE_IMMD:
      doImmdValue();
      if ( isOff(uFlag, x.n) )
        ua_add_off_drefs(x, dreftype);
      break;

    case o_displ:
      dreftype = read_access ? dr_R : dr_W;
      switch ( x.phrase )
      {
        case rD:        // "dp"
        case rDX:       // "dp, X"
        case rDY:       // "dp, Y"
        case riDX:      // "(dp, X)"
        case rDi:       // "(dp,n)"
        case rDiL:      // "long(dp,n)"
        case rDiY:      // "(dp,n), Y"
        case rDiLY:     // "long(dp,n), Y"
          {
            sel_t dp = get_segreg(cmd.ea, rD);
            if ( dp != BADSEL )
            {
              ea_t orig_ea = dp + x.addr;
              ea = xlat(orig_ea);
              goto MAKE_DREF;
            }
            else
            {
              goto MAKE_IMMD;
            }
          }

        case rAbsi:     // "(abs)"
        case rAbsX:     // "abs, X"
        case rAbsY:     // "abs, Y"
        case rAbsiL:    // "long(abs)"
          ea = toEA(dataSeg_op(x.n), x.addr);
          goto MAKE_DREF;

        case rAbsXi:    // "(abs,X)"
          ea = toEA(codeSeg(cmd.ea, x.n), x.addr); // jmp, jsr
          goto MAKE_DREF;

        case rAbsLX:    // "long abs, X"
          ea = x.addr;
          goto MAKE_DREF;

        default:
          goto MAKE_IMMD;
      }

    case o_mem:
    case o_mem_far:
      ea = calc_addr(x);
MAKE_DREF:
      ua_dodata2(x.offb, ea, x.dtyp);
      if ( !read_access )
        doVar(ea);
      ua_add_dref(x.offb, ea, read_access ? dr_R : dr_W);
      break;

    case o_near:
    case o_far:
      {
        ea_t orig_ea;
        ea = calc_addr(x, &orig_ea);
        if ( cmd.itype == M65816_per )
        {
          ua_add_dref(x.offb, ea, dr_O);
        }
        else
        {
          bool iscall = InstrIsSet(cmd.itype, CF_CALL);
          cref_t creftype = x.type == o_near
                          ? iscall ? fl_CN : fl_JN
                          : iscall ? fl_CF : fl_JF;
          ua_add_cref(x.offb, ea, creftype);
          if ( flow && iscall )
            flow = func_does_return(ea);
        }
      }
      break;

    default:
      INTERR(558);
  }
}
コード例 #14
0
static void op_emu(op_t& x, int fIsLoad)
{
    char szLabel[128];
    cref_t ftype;
    ea_t ea;

    switch (x.type)
    {
    case o_reg:
    case o_phrase:
        return;
    case o_imm:
        if (!fIsLoad) break;
        op_imm(cmd.ea);
        return;
    case o_displ:
    case o_mem:
        switch (cmd.itype)
        {
        case M8B_IORD:
        case M8B_IOWR:
        case M8B_IOWX:
        case M8B_IPRET:
            ea = toIOP(x.addr);
            if (ea != BADADDR)
            {
                ua_dodata2(x.offb, ea, x.dtyp);
                if (!fIsLoad) doVar(ea);
                ua_add_dref(x.offb, ea, cmd.itype == M8B_IORD ? dr_R : dr_W);
            }
            break;
        default:
            ea = toRAM(x.addr);
            if (ea != BADADDR)
            {
                if (!has_any_name(get_flags_novalue(ea)))
                {
                    qsnprintf(szLabel, sizeof(szLabel), "ram_%0.2X", x.addr);
                    set_name(ea, szLabel, SN_NOWARN);
                }
                ua_dodata2(x.offb, ea, x.dtyp);
                if (!fIsLoad) doVar(ea);
                ua_add_dref(x.offb, ea, cmd.itype == M8B_IORD ? dr_R : dr_W);
            }
        }
        return;
    case o_near:
        ea = toROM(x.addr);
        if (ea != BADADDR)
        {
            switch (cmd.itype)
            {
            case M8B_INDEX:
                if (!has_any_name(get_flags_novalue(ea)))
                {
                    qsnprintf(szLabel, sizeof(szLabel), "tbl_%0.4X", x.addr);
                    set_name(ea, szLabel, SN_NOWARN);
                }
                ua_add_dref(x.offb, ea, dr_R);
                break;
            default:
                ftype = fl_JN;
                if (InstrIsSet(cmd.itype, CF_CALL))
                {
                    if (!func_does_return(ea))
                        fFlow = false;
                    ftype = fl_CN;
                }
                ua_add_cref(x.offb, ea, ftype);
            }
        }
        return;
    }

    warning("%a: %s,%d: bad optype %d", cmd.ea, cmd.get_canon_mnem(), x.n, x.type);
}
コード例 #15
0
ファイル: emu.cpp プロジェクト: nealey/vera
//----------------------------------------------------------------------
static void process_operand(op_t &x, int use)
{
  switch ( x.type )
  {
    case o_bit:
    case o_reg:
    case o_cond8:
    case o_cond2:
      return;

    case o_near:
    case o_far:
      {
        if (cmd.itype != TMS320C54_rptb && cmd.itype != TMS320C54_rptbd)
        {
          cref_t ftype = fl_JN;
          ea_t ea = calc_code_mem(x.addr, x.type == o_near);
          if ( InstrIsSet(cmd.itype, CF_CALL) )
          {
            if ( !func_does_return(ea) )
              flow = false;
            ftype = fl_CN;
          }
#ifndef TMS320C54_NO_NAME_NO_REF
          if ( x.dtyp == dt_byte )
            ua_add_dref(x.offb, ea, dr_R);
          else
            ua_add_cref(x.offb, ea, ftype);
#endif
        }
#ifndef TMS320C54_NO_NAME_NO_REF
        else // evaluate RPTB[D] loops as dref
          ua_add_dref(x.offb, calc_code_mem(x.addr), dr_I);
#endif
      }
      break;

    case o_imm:
      if ( !use ) error("interr: emu");
      process_imm(x);
#ifndef TMS320C54_NO_NAME_NO_REF
      if ( isOff(uFlag, x.n) )
        ua_add_off_drefs2(x, dr_O, x.Signed ? OOF_SIGNED : 0);
#endif
      break;

    case o_mem:
    case o_farmem:
    case o_mmr:
      {
        ea_t ea = calc_data_mem(x.addr, x.type == o_mem);
        if (ea != BADADDR)
        {
#ifndef TMS320C54_NO_NAME_NO_REF
          ua_add_dref(x.offb, ea, use ? dr_R : dr_W);
#endif
          ua_dodata2(x.offb, ea, x.dtyp);
          if ( !use )
            doVar(ea);
        }
      }
      break;

    case o_local: // local variables
      if ( may_create_stkvars()
        && (get_func(cmd.ea) != NULL)
        && ua_stkvar2(x, x.addr, STKVAR_VALID_SIZE) )
      {
        op_stkvar(cmd.ea, x.n);
      }
      break;

    case o_displ:
      doImmd(cmd.ea);
      break;

    default:
      warning("interr: emu2 address:%a operand:%d type:%d", cmd.ea, x.n, x.type);
  }
}
コード例 #16
0
ファイル: emu.cpp プロジェクト: nealey/vera
//----------------------------------------------------------------------
static void process_operand(op_t &x, int use)
{
  switch ( x.type )
  {
    case o_reg:
      return;

    case o_near:
      {
        if (cmd.itype != TMS320C3X_RPTB )
        {
          cref_t ftype = fl_JN;
          ea_t ea = calc_code_mem(x);
          if ( InstrIsSet(cmd.itype, CF_CALL) )
          {
            if ( !func_does_return(ea) )
              flow = false;
            ftype = fl_CN;
          }
          ua_add_cref(x.offb, ea, ftype);
        }
        else // evaluate RPTB loops as dref
          ua_add_dref(x.offb, calc_code_mem(x), dr_I);
      }
      break;

    case o_imm:
      if ( !use ) error("interr: emu");
      process_imm(x);
      if ( isOff(uFlag, x.n) )
        ua_add_off_drefs2(x, dr_O, 0);
      break;

    case o_mem:
      {
        ea_t ea = calc_data_mem(x);
        if (ea != BADADDR)
        {
          ua_add_dref(x.offb, ea, use ? dr_R : dr_W);
          ua_dodata2(x.offb, ea, x.dtyp);
          if ( !use )
            doVar(ea);
        }
      }
      break;

    case o_phrase:
      break;

    case o_displ:
      doImmd(cmd.ea);
      break;

    default:
      if ( x.type == o_void )
      {
        if ( cmd.itype == TMS320C3X_ABSF )
          break;
        if ( cmd.itype == TMS320C3X_ABSI )
          break;
      }
      warning("interr: emu2 address:%a operand:%d type:%d", cmd.ea, x.n, x.type);
  }
}
コード例 #17
0
ファイル: emu.cpp プロジェクト: nealey/vera
//----------------------------------------------------------------------
static void TouchArg(op_t &x,int isload)
{
  ea_t ea;
  switch ( x.type )
  {
  case o_phrase:                // 2 registers or indirect addressing
    if ( cmd.itype != TMS_mar && cmd.itype != TMS2_mar
                && find_ar(&ea) ) goto set_dref;
  case o_reg:
  case o_bit:
  case o_cond:
    break;
  case o_imm:
    if ( ! isload ) goto badTouch;
    doImmdValue();
    if ( isOff(uFlag, x.n) )
      ua_add_off_drefs2(x, dr_O, is_mpy() ? OOF_SIGNED : 0);
    break;
  case o_mem:
    ea = toEA(dataSeg_op(x.n),x.addr);
set_dref:
    ua_dodata2(x.offb, ea, x.dtyp);
    if ( ! isload )
      doVar(ea);
    ua_add_dref(x.offb,ea,isload ? dr_R : dr_W);
    if ( x.type == o_mem )
      if ( cmd.itype == TMS_dmov  ||
           cmd.itype == TMS_ltd   ||
           cmd.itype == TMS_macd  ||
           cmd.itype == TMS_madd  ||
           cmd.itype == TMS2_dmov ||
           cmd.itype == TMS2_macd  ) ua_add_dref(x.offb,ea+1,dr_W);
    break;
  case o_near:
    {
      ea_t segbase = codeSeg(x.addr, x.n);
      ea = toEA(segbase, x.addr);
      if ( cmd.itype == TMS_blpd ||
           cmd.itype == TMS_mac  ||
           cmd.itype == TMS_macd ||
           cmd.itype == TMS2_blkp ||
           cmd.itype == TMS2_mac  ||
           cmd.itype == TMS2_macd
         ) goto set_dref;
      uval_t thisseg = cmd.cs;
      int iscall = InstrIsSet(cmd.itype,CF_CALL);
      if ( cmd.itype == TMS_rptb && isTail(get_flags_novalue(ea)) )
      {
        // small hack to display end_loop-1 instead of before_end_loop+1
        ea++;
      }

      ua_add_cref(x.offb,
                  ea,
                  iscall ? ((segbase == thisseg) ? fl_CN : fl_CF)
                         : ((segbase == thisseg) ? fl_JN : fl_JF));
      if ( iscall )
      {
        if ( !func_does_return(ea) )
          flow = false;
      }
    }
    break;
  default:
badTouch:
    warning("%a: %s,%d: bad optype %d", cmd.ea, cmd.get_canon_mnem(), x.n, x.type);
    break;
  }
}
コード例 #18
0
ファイル: emu.cpp プロジェクト: nealey/vera
static void handle_operand(op_t &x,int loading)
{
  switch ( x.type )
  {
    case o_phrase:              // no special hanlding for these types
    case o_reg:
      break;

    case o_imm:                         // an immediate number as an operand
      if ( !loading ) goto BAD_LOGIC;   // this can't happen!
      doImmdValue();                    // handle immediate number

      // if the value was converted to an offset, then create a data xref:
      if ( isOff(uFlag, x.n) )
        ua_add_off_drefs2(x, dr_O, OOFS_IFSIGN);

      break;

    case o_displ:
      doImmdValue();                    // handle immediate number

      // if the value was converted to an offset, then create a data xref:
      if ( isOff(uFlag, x.n) )
        ua_add_off_drefs2(x, loading?dr_R:dr_W, OOFS_IFSIGN|OOF_ADDR);
      break;

    case o_bit:                         // 8051 specific operand types - bits
    case o_bitnot:
      x.addr = (x.reg & 0xF8);
      if( (x.addr & 0x80) == 0 ) x.addr = x.addr/8 + 0x20;
      attach_bit_comment(x.addr, x.reg & 7);  // attach a comment if necessary
      goto MEM_XREF;

    case o_bit251:
      attach_bit_comment(x.addr, x.b251_bit);
      /* no break */

    case o_mem:                         // an ordinary memory data reference
MEM_XREF:
      {
        ea_t dea = map_addr(x.addr, x.n, true);
        ua_dodata2(x.offb, dea, x.dtyp);
        if ( !loading )
          doVar(dea);     // write access
        ua_add_dref(x.offb, dea, loading ? dr_R : dr_W);
      }
      break;

    case o_near:                        // a code reference
      {
        ea_t ea = map_addr(x.addr, x.n, false);
        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);
      }
      break;

    default:
BAD_LOGIC:
      warning("%a: %s,%d: bad optype %d", cmd.ea, cmd.get_canon_mnem(), x.n, x.type);
      break;
  }
}
コード例 #19
0
ファイル: emu.cpp プロジェクト: awesome-security/vera
//----------------------------------------------------------------------
// поставим использование/изменение операндов
static void near TouchArg(op_t &x,int isAlt,int isload)
{
ea_t ea = toEA(codeSeg(x.addr,x.n), x.addr);
  switch ( x.type ) {
  // эта часть не используется !
  case o_void:	break;
  // тут тоже нечего делать
  case o_reg:	break;

  // непосредственный операнд
  case o_imm:   // непосредственный не может меняться
                if ( ! isload ) goto badTouch;
                // поставим флажок непосредственного операнда
                doImmd(cmd.ea);
                // если не форсирован и помечен смещением
                if ( !isAlt && isOff(uFlag,x.n) )
                        // это смещение !
						ua_add_dref(x.offb,ea,dr_O);
                break;

  // переход или вызов
  case o_near:	// это вызов ? (или переход)
				if(InstrIsSet(cmd.itype,CF_CALL)){
					// поставим ссылку на код
					ua_add_cref(x.offb,ea,fl_CN);
					// это функция без возврата ?
#if IDP_INTERFACE_VERSION > 37
					flow = func_does_return(ea);
#else
                    // получим описатель функции
					func_t *pfn = get_func(ea);
					// если функция описана и не имеет возврата - остановим
					if(pfn != NULL && (pfn->flags & FUNC_NORET) ) flow = false;
#endif
                }
				else ua_add_cref(x.offb,ea,fl_JN);
                break;

  // ссылка на ячейку памяти
  case o_mem:	// сделаем данные по указанному адресу
				ua_dodata2(x.offb, ea, x.dtyp);
				// если изменяется - поставим переменную
				if ( ! isload ) doVar(ea);
				// добавим ссылку на память
				ua_add_dref(x.offb,ea,isload ? dr_R : dr_W);
                break;

  // прочее - сообщим ошибку
  default:
badTouch:
#if IDP_INTERFACE_VERSION > 37
		warning("%a %s,%d: bad optype %d",
				cmd.ea, cmd.get_canon_mnem(),
#else
		warning("%08lX %s,%d: bad optype (%x)",
				cmd.ea,(char far *)Instructions[cmd.itype].name,
#endif
				x.n, x.type);
		break;
  }
}
コード例 #20
0
ファイル: emu.cpp プロジェクト: nealey/vera
//----------------------------------------------------------------------
static void process_operand(op_t &x,int ,int isload)
{
    if ( cmd.Op2.type == o_reg && cmd.Op2.reg == F || cmd.itype == PIC_swapf ) isload = 0;
    switch ( x.type )
    {
    case o_reg:
        return;
    case o_imm:
        if ( !isload ) error("interr: emu");
        process_immediate_number(x.n);
        if ( isOff(uFlag, x.n) )
            ua_add_off_drefs2(x, dr_O, calc_outf(x));
        break;
    case o_near:
    {
        cref_t ftype = fl_JN;
        ea_t ea = calc_code_mem(x.addr);
        if ( InstrIsSet(cmd.itype, CF_CALL) )
        {
            if ( !func_does_return(ea) )
                flow = false;
            ftype = fl_CN;
        }
        ua_add_cref(x.offb, ea, ftype);
    }
    break;
    case o_mem:
    {
        ea_t ea = calc_data_mem(x.addr);
        destroy_if_unnamed_array(ea);
        ua_add_dref(x.offb, ea, isload ? dr_R : dr_W);
        ua_dodata2(x.offb, ea, x.dtyp);
        if ( !isload )
            doVar(ea);
        if ( may_create_stkvars())
        {
            if ( x.addr == PIC16_INDF2 )
            {
                func_t *pfn = get_func(cmd.ea);
                if ( pfn != NULL && (pfn->flags & FUNC_FRAME) != 0 )
                {
                    ua_stkvar2(cmd.Op1, 0, STKVAR_VALID_SIZE);
                }
            }
            else if ( x.addr == PIC16_PLUSW2 )
            {
                insn_t saved = cmd;
                if ( decode_prev_insn(cmd.ea) != BADADDR && cmd.itype == PIC_movlw )
                {
                    func_t *pfn = get_func(cmd.ea);
                    if ( pfn != NULL && (pfn->flags & FUNC_FRAME) != 0 )
                    {
                        if ( ua_stkvar2(cmd.Op1, cmd.Op1.value, STKVAR_VALID_SIZE) )
                            op_stkvar(cmd.ea, cmd.Op1.n);
                    }
                }
                cmd = saved;
            }
        }




    }
    break;
    default:
        warning("interr: emu2 %a", cmd.ea);
    }
}