示例#1
0
//----------------------------------------------------------------------
static void process_operand(op_t &x, bool isload)
{
  ea_t ea;
  dref_t dref;
  if ( is_forced_operand(cmd.ea, x.n) ) return;
  switch ( x.type )
  {
    case o_reg:
    case o_phrase:
      break;

    case o_imm:
      if ( !isload ) interr("emu1");
      process_immediate_number(x.n);
      if ( isOff(uFlag, x.n) )
        ua_add_off_drefs2(x, dr_O, OOFS_IFSIGN|OOFW_IMM);
      break;

    case o_mem:
      ea = calc_mem(x.addr);
      ua_dodata2(x.offb, ea, x.dtyp);
      dref = cmd.itype == I960_lda ? dr_O : isload ? dr_R : dr_W;
      ua_add_dref(x.offb, ea, dref);
      break;

    case o_near:
      {
        cref_t ftype = fl_JN;
        ea = calc_mem(x.addr);
        if ( InstrIsSet(cmd.itype, CF_CALL) )
        {
          flow = func_does_return(ea);
          ftype = fl_CN;
        }
        ua_add_cref(x.offb, ea, ftype);
      }
      break;

    case o_displ:
      dref = cmd.itype == I960_lda ? dr_O : isload ? dr_R : dr_W;
      process_immediate_number(x.n);
      if ( x.reg == IP )
      {
        ea_t ea = cmd.ea + 8 + x.addr;
        ua_add_dref(x.offb, ea, dref);
      }
      else
      {
        if ( isOff(uFlag, x.n) )
          ua_add_off_drefs2(x, dref, OOFS_IFSIGN|OOF_SIGNED|OOF_ADDR|OOFW_32);
      }
      break;

    default:
      interr("emu");
  }
}
示例#2
0
//----------------------------------------------------------------------
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);
  }
}
示例#3
0
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 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;
      }
  }
}
示例#5
0
//----------------------------------------------------------------------
static void fixup(uint32 ea, uint32 delta, int extdef)
{
  fixup_data_t fd;
  fd.type = FIXUP_OFF32;
  if ( extdef ) fd.type |= FIXUP_EXTDEF;
  segment_t *s = getseg(delta);
  fd.displacement = get_long(ea);
  if ( s == NULL ) {
    fd.sel = 0;
    fd.off = delta;
  } else {
    fd.sel = (ushort)s->sel;
    fd.off = delta - get_segm_base(s);
  }
  set_fixup(ea, &fd);
  uint32 target = get_long(ea) + delta;
  put_long(ea, target);
  set_offset(ea, 0, 0);
  cmd.ea = ea; ua_add_dref(0, target, dr_O); cmd.ea = BADADDR;
  if ( target != toc_ea
    && !has_name(get_flags_novalue(ea))
    && has_name(get_flags_novalue(target)) )
  {
    char buf[MAXSTR];
    if ( get_true_name(BADADDR, target, &buf[3], sizeof(buf)-3) != NULL )
    {
      buf[0] = 'T';
      buf[1] = 'C';
      buf[2] = '_';
      do_name_anyway(ea, buf);
      make_name_auto(ea);
    }
  }
//  toc.charset(ea,XMC_TC+1,1);
}
示例#6
0
//------------------------------------------------------------------------
// Конвертирование в данные(указан адресс) по указанному типу,
// добавить крос референсы для текущей инструкции
void DataSet(op_t &x, ea_t EA, int isload)
{
// Конвертирование в данные(указан адресс) по указанному типу
ua_dodata2(x.offb, EA, x.dtyp);
//добавить крос референсы для текущей инструкции
ua_add_dref(x.offb, EA, isload ? dr_R : dr_W);
}
示例#7
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;
  }
}
示例#8
0
文件: emu.cpp 项目: nealey/vera
static void handle_operand(op_t &op) {
    switch (op.type) {

        // code address
        case o_near:
            {
                ea_t ea = toEA(cmd.cs, op.addr);
                cref_t mode = fl_JN;
                if (cmd.itype == m740_jsr)
                {
                  if ( !func_does_return(ea) )
                    flow = false;
                  mode = fl_CN;
                }
                ua_add_cref(op.offb, ea, mode);
            }
            break;

        // data address
        case o_mem:
            {
                enum dref_t mode = dr_U;

                if (is_addr_ind(op))            mode = dr_R;    /* NOT dr_O */
                else if (is_addr_read(op))      mode = dr_R;
                else if (is_addr_write(op))     mode = dr_W;

                ua_add_dref(op.offb, toEA(cmd.cs, op.addr), mode);
                ua_dodata2(op.offb, op.addr, op.dtyp);
            }
            break;

        // immediate
        case o_imm:
            handle_imm(op);
            // if the value was converted to an offset, then create a data xref:
            if (isOff(uFlag, op.n))
              ua_add_off_drefs2(op, dr_O, 0);
            break;

        // displ
        case o_displ:
            if (isOff(uFlag, op.n)) {
                ua_add_off_drefs2(op, dr_O, OOF_ADDR);
                ua_dodata2(op.offb, op.addr, op.dtyp);
            }
            break;

        // reg - do nothing
        case o_reg:
        case o_void:
            break;

        default:
            IDA_ERROR("Invalid op.type in handle_operand()");
    }
}
示例#9
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);
        }
示例#10
0
//----------------------------------------------------------------------
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;
  }
}
示例#11
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;

  }
}
示例#12
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;
}
示例#13
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;
  }
}
示例#14
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;
  }
}
示例#15
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);
  }
}
示例#16
0
//----------------------------------------------------------------------
static void TouchArg(op_t &x,int isAlt,int isload) {

  switch ( x.type ) {

    case o_phrase:
           //Добавляем в список ошибок(выводим сообщение)
           //ошибку и адресс где это случилось
           //QueueMark(Q_jumps, cmd.ea);
    case o_void:
    case o_reg:

      break;


    case o_sr:
    case o_displ:
       //Установить для данного байта признак immedia
      doImmd(cmd.ea);
      //Получить флаг для указанного линейного адресса
      if ( !isAlt ) {
        uint32 offb;
        ushort addr = ushort(x.addr);
        if ( x.type == o_displ  ) {
          addr += (ushort)cmd.ip;
          addr += cmd.size;
          //Получить линейный адресс
          offb = (uint32)toEA(codeSeg(addr,x.n), 0);
          DataSet(x, offb+addr, isload);
        } else if ( isOff(uFlag, x.n) ) {
reref:
          ua_add_off_drefs2(x, dr_O, x.type == o_displ ? OOF_ADDR : 0);
          if ( x.type == o_displ )
            //Преобразовать данные по указанному линейному адрессу в указанный тип
            ua_dodata2(x.offb, calc_target(cmd.ea+x.offb, cmd.ea, x.n, x.addr), x.dtyp);
        } else if ( x.type == o_displ && !x.reg && !isDefArg(uFlag, x.n ) &&
                 set_offset(cmd.ea, x.n, toEA(cmd.cs,0))) goto reref;
      }
      break;

   case o_stk:
   case o_imm:
       {
         //Установить для данного байта признак immedia
         doImmd(cmd.ea);
         if ( isOff(get_flags_novalue(cmd.ea), x.n) )
           ua_add_off_drefs2(x, dr_O, 0);
       }
       break;


   case o_ab:
       {
            if ( x.TypeOper == TAB_INDIRECTED_ABS_X )
            {
               ea_t ea = toEA(cmd.cs, x.addr);
               ua_dodata2(x.offb, ea, dt_word);
               //добавить крос референсы для текущей инструкции
               ua_add_dref(x.offb, ea, isload ? dr_R : dr_W);

               //получить данные
               uint32 Addr;
               Addr = get_word(ea);
               Addr = uint32( Addr | (getPG<<16));
               //добавить крос референсы для текущей инструкции
               ua_add_cref(2, Addr, fl_JF);
             }
            else
               DataSet(x, toEA(codeSeg(x.addr,x.n), x.addr), isload);
       }
       break;

   case o_mem:
   {
       // Конвертирование в данные(указан адресс) по указанному типу,
       //добавить крос референсы для текущей инструкции
     switch ( x.TypeOper )
     {
       case TDIR_DIR_Y:
       case TDIR_DIR_X:
       case TDIR_DIR:
       case TDIR_INDIRECT_DIR:
       case TDIR_INDIRECT_DIR_X:
       case TDIR_INDIRECT_DIR_Y:
       case TDIR_L_INDIRECT_DIR:
       case TDIR_L_INDIRECT_DIR_Y:
        {
          if ( getDPReg == 1 )
          {
             uint32 d = x.addr & 0xC;
             x.addr &= 0xFF3F;
             DataSet(x, toEA(codeSeg(x.addr,x.n), x.addr), isload);
             x.addr |=d;
          }
          else
             DataSet(x, toEA(codeSeg(x.addr,x.n), x.addr), isload);

        }
        break;

       default:
          DataSet(x, toEA(codeSeg(x.addr,x.n), x.addr), isload);

      }//end switch
   }
      break;


    case o_near:
      {
        //Получить линейный адресс
        ea_t ea = toEA(cmd.cs, x.addr);

        switch ( cmd.itype )
        {

           case m7900_jsr:
                {
                   //добавить крос референсы для текущей инструкции
                   ua_add_cref(x.offb, ea, fl_CN );
                   if ( !func_does_return(ea) )
                      flow = false;
                }
               break;

           case m7900_jsrl:
                 //добавить крос референсы для текущей инструкции
                 ua_add_cref(x.offb, ea, fl_CF);
                 if ( !func_does_return(ea) )
                   flow = false;
               break;

           case m7900_jmpl:
                 //добавить крос референсы для текущей инструкции
                 ua_add_cref(x.offb, ea, fl_JF);
               break;


            default:
                   ua_add_cref(x.offb, ea, fl_JN);
                break;
        }
      }
      break;

    default:
//      warning("%a: %s,%d: bad optype %d", cmd.ea, cmd.get_canon_mnem(), x.n, x.type);
      break;
  }
}
示例#17
0
bool
handle_operand(const op_t &op, enum opRefType ref_type)
{
        ea_t       ea;
        sel_t      data_selector;
        bool       flow = true;

        switch ( op.type ) {
        case o_reg:
                //
                // Register operand.
                //
                //
                // Nothing needs to be calculated or examined for this
                // operand.
                //
                break;
        case o_imm:
                //
                // Immediate operand.
                //
                // Make sure that this operand reference isn't a write reference.
                // (Writing to an immediate value is not allowed and is a sure
                // sign of a badly decoded instruction).
                //
                if ( ref_type == hop_WRITE ) {
                        //
                        // Attempt to write to an immediate value.
                        // Error.
                        //
                        warning("%a: %s,%d: bad optype %d", cmd.ea, cmd.get_canon_mnem(), op.n, op.type);
                        break;
                }
                //
                // SPECIAL INSTRUCTION CASE:
                //
                // The LDPK instruction is decoded by ana() to have an immediate
                // value as an operand.  However, this immediate value is to be
                // the new data page pointer, which we must track for proper
                // memory referencing.
                //
                if ( cmd.itype == I_LDPK ) {
                        //
                        // This is an LDPK instruction.  Let the kernel know that
                        // we are changing the current data page pointer.  We track
                        // this bit as though it were a virtual segment register named
                        // I_VDS, although it is not a true register in the CPU.
                        //
                        // Determine into which data page the instruction is attempting
                        // to point.
                        //
                        if ( op.value == 0 ) {
                                //
                                // Data page 0 is being loaded.
                                //
                                data_selector = tms320c1x_dpage0;
                        } else {
                                //
                                // Data page 1 is being loaded.
                                //
                                data_selector = tms320c1x_dpage1;
                        }
                        //
                        // Notify the IDA kernel of the change.
                        //
                        split_srarea(
                                cmd.ea,          // The current instruction's address
                                IREG_VDS,        // The segment register being modified
                                data_selector,   // The new selector value being loaded
                                SR_auto          // How the new value was determined
                        );
                }
                //
                // Let the kernel know that the instruction's address should
                // be marked with a 'has immediate value' flag.
                // (Useful during search?)
                //
                doImmd(cmd.ea);
                break;
        case o_phrase:
                //
                // Processor-specific phrase.
                //
                // These operands have no currently trackable side effect.
                //
                break;
        case o_mem:
                //
                // Direct memory reference.
                //

                //
                // Ask the IDA kernel for the current data page pointer selector.
                //
                data_selector = get_segreg(cmd.ea, IREG_VDS);

                //
                // Is it known?
                //
                if ( data_selector == BADSEL ) {
                        //
                        // The current data page pointer is unknown.
                        // There is nothing to do.
                        //
                } else {
                        //
                        // The current data page pointer is known.
                        // Calculate the full effective address being referenced
                        // by this operand.
                        //
                        ea = sel2ea(data_selector) + op.addr;

                        //
                        // Generate a data cross reference from this instruction
                        // to the target address.
                        //
                        ua_add_dref(op.offb, ea, ref_type == hop_READ ? dr_R : dr_W);
                }

                //
                // TODO: DMOV, ...
                // These instructions read from the address in their operands
                // and write to the address ADJACENT to it.
                //
                break;
        case o_near:
                //
                // Code reference in current segment.
                //
                //
                // Determine the effective address of the reference.
                //
                ea = toEA(cmd.cs, op.addr);

                //
                // Is this a 'CALL' type reference, or a branch type reference?
                //
                if ( InstrIsSet(cmd.itype, CF_CALL) ) {
                        //
                        // This is a CALL type reference.  Make a cross reference
                        // that notes it.
                        //
                        ua_add_cref(op.offb, ea, fl_CN);
                        if ( !func_does_return(ea) )
                           flow = false;
                } else {
                        //
                        // This is a branch type reference.  Make a cross reference
                        // that notes it.
                        //
                        ua_add_cref(op.offb, ea, fl_JN);
                }
                break;
        default:
                //
                // Unhandled operand type.
                // Error.
                //
                warning("%a: %s,%d: bad optype %d", cmd.ea, cmd.get_canon_mnem(), op.n, op.type);
                break;
        }
        return flow;
}
示例#18
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);
  }
}
示例#19
0
文件: emu.cpp 项目: nealey/vera
// Emulate an operand.
static void handle_operand(op_t &op, bool write) {
    switch ( op.type ) {
        // Code address
        case o_near:
            {
                cref_t mode;
                ea_t ea = toEA(cmd.cs, op.addr);

                // call or jump ?
                if ( cmd.itype == st9_call || cmd.itype == st9_calls )
                {
                  if ( !func_does_return(ea) )
                    flow = false;
                  mode = fl_CN;
                }
                else
                {
                  mode = fl_JN;
                }
                ua_add_cref(op.offb, ea, mode);
            }
            break;

        // Memory address
        case o_mem:
            {
                enum dref_t mode;

                mode = write ? dr_W: dr_R;

                ua_add_dref(op.offb, toEA(cmd.cs, op.addr), mode);
                ua_dodata2(op.offb, op.addr, op.dtyp);
            }
            break;

        // Immediate value
        case o_imm:
            doImmd(cmd.ea);
            // create a comment if this immediate is represented in the .cfg file
            {
                const ioport_t * port = find_sym(op.value);

                if ( port != NULL && !has_cmt(uFlag) ) {
                    set_cmt(cmd.ea, port->cmt, false);
                }
            }
            // if the value was converted to an offset, then create a data xref:
            if ( isOff(uFlag, op.n) )
              ua_add_off_drefs2(op, dr_O, 0);
            break;

        // Displacement
        case o_displ:
            doImmd(cmd.ea);
            if ( isOff(uFlag, op.n) ) {
                ua_add_off_drefs2(op, dr_O, OOF_ADDR);
                ua_dodata2(op.offb, op.addr, op.dtyp);
            }

            // create stack variables if required
            if ( may_create_stkvars() && !isDefArg(uFlag, op.n) ) {
                func_t *pfn = get_func(cmd.ea);
                if ( pfn != NULL && pfn->flags & FUNC_FRAME ) {
                    if ( ua_stkvar2(op, op.addr, STKVAR_VALID_SIZE) ) {
                        op_stkvar(cmd.ea, op.n);
                        if ( cmd.Op2.type == o_reg ) {
                            regvar_t *r = find_regvar(pfn, cmd.ea, ph.regNames[cmd.Op2.reg]);
                            if ( r != NULL ) {
                                struc_t *s = get_frame(pfn);
                                member_t *m = get_stkvar(op, op.addr, NULL);
                                char b[20];
                                qsnprintf(b, sizeof b, "%scopy", r->user);
                                set_member_name(s, m->soff, b);
                            }
                        }
                    }
                }
            }
            break;

        // Register - Phrase - Void: do nothing
        case o_reg:
        case o_phrase:
        case o_void:
            break;

        default:
            IDA_ERROR("Invalid op.type in handle_operand()");
    }
}
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);
}
int idaapi emu()
{
    char szLabel[MAXSTR];
    insn_t saved;
    segment_t* pSegment;
    ea_t ea, length, offset;
    flags_t flags;
    uint32 dwFeature, i;

    dwFeature = cmd.get_canon_feature();
    fFlow = !(dwFeature & CF_STOP);

    if (dwFeature & CF_USE1) op_emu(cmd.Op1, 1);
    if (dwFeature & CF_USE2) op_emu(cmd.Op2, 1);

    if (dwFeature & CF_CHG1) op_emu(cmd.Op1, 0);
    if (dwFeature & CF_CHG2) op_emu(cmd.Op2, 0);

    saved = cmd;
    switch (cmd.itype)
    {
    case M8B_MOV:
        if (!cmd.Op1.is_reg(rPSP))
            break;
    case M8B_SWAP:
        if (cmd.itype == M8B_SWAP && !cmd.Op2.is_reg(rDSP))
            break;

        for (i = 0; i < 5; ++i)
        {
            ea = decode_prev_insn(cmd.ea);
            if (ea == BADADDR) break;
            if (cmd.itype == M8B_MOV && cmd.Op1.is_reg(rA) && cmd.Op2.type == o_imm)
            {
                ea = toRAM(cmd.Op2.value);
                if (ea != BADADDR)
                {
                    qsnprintf(szLabel, sizeof(szLabel), "%s_%0.2X", cmd.itype == M8B_MOV ? "psp" : "dsp", cmd.Op2.value);
                    ua_add_dref(cmd.Op2.offb, ea, dr_O);
                    set_name(ea, szLabel, SN_NOWARN);
                }
                break;
            }
        }
        break;
    case M8B_JACC:
        pSegment = getseg(cmd.ea);
        if (!pSegment) break;
        length = pSegment->endEA - cmd.ea;
        if (length > 256) length = 256;
        for (offset = 2; offset < length; offset += 2)
        {
            ea = toROM(saved.Op1.addr + offset);
            if (ea == BADADDR) break;
            flags = getFlags(ea);
            if (!hasValue(flags) || (has_any_name(flags) || hasRef(flags)) || !create_insn(ea)) break;
            switch (cmd.itype)
            {
            case M8B_JMP:
            case M8B_RET:
            case M8B_RETI:
            case M8B_IPRET:
                add_cref(saved.ea, ea, fl_JN);
                break;
            default:
                offset = length;
            }
        }
        break;
    case M8B_IORD:
    case M8B_IOWR:
    case M8B_IOWX:
        for (i = 0; i < 5; ++i)
        {
            ea = (saved.itype == M8B_IORD) ? decode_insn(cmd.ea + cmd.size) : decode_prev_insn(cmd.ea);
            if (ea == BADADDR) break;
            if (cmd.Op1.is_reg(rA) && cmd.Op2.type == o_imm)
            {
                qsnprintf(szLabel, sizeof(szLabel), "[A=%0.2Xh] ", cmd.Op2.value);
                if (get_portbits_sym(szLabel + qstrlen(szLabel), saved.Op1.addr, cmd.Op2.value))
                    set_cmt(saved.ea, szLabel, false);
                break;
            }
        }
    }
    cmd = saved;

    if ((cmd.ea & 0xFF) == 0xFF)
    {
        switch (cmd.itype)
        {
        case M8B_RET:
        case M8B_RETI:
        case M8B_XPAGE:
            break;
        default:
            QueueMark(Q_noValid, cmd.ea);
        }
    }

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

    return 1;
}
示例#22
0
//----------------------------------------------------------------------
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);
  }
}
示例#23
0
文件: emu.cpp 项目: nealey/vera
//------------------------------------------------------------------------
static void TouchArg(op_t &x,int isAlt,int isload) {
  ea_t jmpa;
  switch ( x.type ) {
  case o_near:       // Jcc/ [jmp/call 37/67]
  case o_mem:        // 37/67/77
  case o_far:
      jmpa = toEA(x.type == o_far ? x.segval : codeSeg(x.addr16,x.n), x.addr16);
      if ( x.phrase == 0) { ua_add_cref(x.offb,jmpa,fl_JN ); break; } //Jcc
extxref:
      if ( (x.phrase & 070) == 070 ) goto xrefset;
      if ( cmd.itype == pdp_jmp) ua_add_cref(x.offb,jmpa,fl_JF );
      else if ( cmd.itype == pdp_jsr || cmd.itype == pdp_call ) {
             ua_add_cref(x.offb,jmpa,fl_CF);
             if ( !func_does_return(jmpa) )
               flow = false;
           } else {
xrefset:
             ua_dodata2(x.offb, jmpa, x.dtyp);
             ua_add_dref(x.offb, jmpa, isload ? dr_R : dr_W);
           }
      break;
  case o_displ:     // 6x/7x (!67/!77)
      doImmdValue();
      if ( !isload && x.phrase == (060 + rR0) && x.addr16 <= 1 )
                                                  loadR0data(&x, x.addr16);
      if ( !isAlt && isOff(emuFlg,x.n ) &&
         (jmpa = get_offbase(cmd.ea, x.n)) != BADADDR) {
        jmpa += x.addr16;
        goto extxref;
      }
      break;
  case o_imm:        // 27
      if ( !x.ill_imm )
      {
         doImmdValue();
         if ( op_adds_xrefs(uFlag, x.n) )
           ua_add_off_drefs2(x, dr_O, OOF_SIGNED);
      }
      break;
  case o_number:      // EMT/TRAP/MARK/SPL
      if ( cmd.itype == pdp_emt && get_cmt(cmd.ea, false, NULL, 0) <= 0 ) {
         if ( x.value >= 0374 && x.value <= 0375 ) {
           cmd.Op2.value = (x.value == 0375) ? emuR0data.b[1] : (emuR0 >> 8);
           cmd.Op2.type = o_imm;
         }
         char buf[MAXSTR];
         if ( get_predef_insn_cmt(cmd, buf, sizeof(buf)) > 0 )
           set_cmt(cmd.ea, buf, false);
        cmd.Op2.type = o_void;
      }
      break;
  case o_reg:        // 0
      if ( x.reg == rR0 ) {
        if ( cmd.Op2.type == o_void ) { // one operand cmd
          if ( cmd.itype != pdp_clr ) {
            goto undefall;
          } else {
            if ( cmd.bytecmd ) emuR0 &= 0xFF00;
            else            emuR0 = 0;
            goto undefdata;
          }
        }
        if ( &x == &cmd.Op2 ) {
          if ( cmd.itype != pdp_mov ) {
            if ( cmd.bytecmd ) { emuR0 |= 0xFF; goto undefdata; }
            else            goto undefall;
          }
          if ( cmd.bytecmd ) goto undefall;
          if ( cmd.Op1.type == o_imm ) {
            if ( (emuR0 = (ushort)cmd.Op1.value) & 1 ) goto undefdata;
            emuR0data.w = get_word(toEA(cmd.cs, emuR0));
          } else {
undefall:
            emuR0 = 0xFFFF;
undefdata:
            emuR0data.w = 0xFFFF;
          }
        }
      }
      break;
  case o_phrase:     // 1x/2x/3x/4x/5x (!27/!37)
      if ( (x.phrase & 7) == rR0 )
      {
        if ( !isload && x.phrase == (010 + rR0)) loadR0data(&x, 0 );
        else if ( cmd.Op2.type == o_void || &x == &cmd.Op2 ) goto undefall;
      }
  case o_fpreg:      // FPP
    break;
  default:
    warning("%" FMT_EA "o (%s): bad optype %d", cmd.ip, cmd.get_canon_mnem(), x.type);
    break;
  }
示例#24
0
文件: emu.cpp 项目: nealey/vera
// Emulate an operand.
static void handle_operand(op_t &op) {
    bool offset = false;
    switch ( op.type ) {
        case o_near:
            ua_add_cref(op.offb, toEA(cmd.cs, op.addr), (cmd.itype == fr_call) ? fl_CN : fl_JN);
            break;

        case o_mem:
            {
                enum dref_t mode = dr_U;

                if ( op.specflag1 & OP_ADDR_R )           mode = dr_R;
                else if ( op.specflag1 & OP_ADDR_W )      mode = dr_W;

                ea_t ea = toEA(cmd.cs, op.addr);
                ua_add_dref(op.offb, ea, mode);
                ua_dodata2(op.offb, ea, op.dtyp);
            }
            break;

        case o_imm:
            // if current insn is ldi:32 #imm, r1
            // and next insn is call @r1,
            // replace the immediate value with an offset.
            if (cmd.itype == fr_ldi_32 &&
                cmd.Op1.type == o_imm &&
                cmd.Op2.type == o_reg)
            {
                const int callreg = cmd.Op2.reg;
                insn_t cmd_backup = cmd;
                if ( next_insn(cmd.ea + cmd.size ) > 0 &&
                    cmd.itype == fr_call &&
                    cmd.Op1.type == o_phrase &&
                    cmd.Op1.specflag2 == fIGR &&
                    cmd.Op1.reg == callreg)
                {
                    offset = true;
                }
                const ea_t from = cmd.ea;
                cmd = cmd_backup;
                if ( !isDefArg(uFlag, 0) && offset && set_offset(cmd.ea, 0, 0) )
                    add_cref(from, toEA(cmd.cs, cmd.Op1.value), fl_CN);
            }
            doImmd(cmd.ea);
            if ( !offset )
                // if the value was converted to an offset, then create a data xref:
                if ( isOff(uFlag, op.n) )
                  ua_add_off_drefs2(op, dr_O, 0);

            // create stack variables if necessary
            {
                bool ok = false;
                // ldi8 #our_value, R1
                // extsb R1
                // addn R14, R1
                if (cmd.itype == fr_ldi_8 &&
                    cmd.Op2.type == o_reg &&
                    cmd.Op2.reg == rR1)
                {
                    insn_t current_insn = cmd;
                    next_insn(cmd.ea + cmd.size);
                    if (cmd.itype == fr_extsb &&
                        cmd.Op1.type == o_reg &&
                        cmd.Op1.reg == rR1)
                    {
                        ok = true;
                    }
                    if ( ok ) {
                        ok = false;
                        next_insn(cmd.ea + cmd.size);
                        if (cmd.itype == fr_addn &&
                            cmd.Op1.type == o_reg &&
                            cmd.Op1.reg == rR14 &&
                            cmd.Op2.type == o_reg &&
                            cmd.Op2.reg == rR1)
                        {
                            ok = true;
                        }
                    }
                    cmd = current_insn;
                }
                // ldi32 #our_value, Ri
                // addn R14, Ri
                //
                // (where Ri is either R1 or R2)
                else if (cmd.itype == fr_ldi_32 &&
                    cmd.Op2.type == o_reg &&
                    (cmd.Op2.reg == rR1 || cmd.Op2.reg == rR2))
                {
                    ushort the_reg = cmd.Op2.reg;
                    insn_t current_insn = cmd;
                    next_insn(cmd.ea + cmd.size);
                    if (cmd.itype == fr_addn &&
                        cmd.Op1.type == o_reg &&
                        cmd.Op1.reg == rR14 &&
                        cmd.Op2.type == o_reg &&
                        cmd.Op2.reg == the_reg)
                    {
                        ok = true;
                    }
                    cmd = current_insn;
                }

                if ( ok && may_create_stkvars() && !isDefArg(uFlag, op.n) ) {
                    func_t *pfn = get_func(cmd.ea);
                    if ( pfn != NULL && pfn->flags & FUNC_FRAME ) {
                        if ( ua_stkvar2(op, op.value, 0) ) {
                            op_stkvar(cmd.ea, op.n);
                        }
                    }
                }
            }
            break;

        case o_displ:
        case o_phrase:  // XXX
        case o_reglist:
        case o_void:
        case o_reg:
            break;

        default:
            INTERR(10017);
    }
}
示例#25
0
//----------------------------------------------------------------------
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);
  }
}
示例#26
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);
  }
}
示例#27
0
文件: emu.cpp 项目: nealey/vera
//----------------------------------------------------------------------
static int LoadArg(op_t &x)
{
  dref_t xreftype;
  switch ( x.type ) {
  case o_reg:
    {
      if ( x.reg == R_sp ) goto Undefined;
//      AbstractRegister *in = &i5_getreg(x.reg);
//      if ( ! in->isDef() ) goto Undefined;
//      r.doInt(in->value());
      return 1;
    }
  case o_imm:
//    r.doInt(unsigned(x.value));
    xreftype = dr_O;
MakeImm:
    doImmdValue(x.n);
    if ( isOff(uFlag, x.n) )
      ua_add_off_drefs2(x, xreftype, 0);
    return 1;
  case o_displ:
//    r.undef();
    xreftype = dr_R;
    goto MakeImm;
  case o_mem:
    {
      ea_t ea = toEA(dataSeg_op(x.n),x.addr);
      ua_add_dref(x.offb,ea,dr_R);
      ua_dodata2(x.offb, ea, x.dtyp);
      if ( !isVar(get_flags_novalue(ea)) && isLoaded(ea) )
      {
//        r.doInt( x.dtyp != dt_byte ? get_word(ea) : char(get_byte(ea)) );
        return 1;
      }
    }
  case o_phrase:
Undefined:
//    r.undef();
    break;

  case o_near:
    {
      ea_t segbase = codeSeg(x.addr,x.n);
      ea_t ea = toEA(segbase,x.addr);
      ea_t thisseg = cmd.cs;
      int iscall = InstrIsSet(cmd.itype,CF_CALL);
      ua_add_cref(x.offb,
                  ea,
                  iscall ? ((segbase == thisseg) ? fl_CN : fl_CF)
                         : ((segbase == thisseg) ? fl_JN : fl_JF));
      if ( iscall && !func_does_return(ea) )
        flow = false;
//      r.doInt(unsigned(x.addr));
    }
    return 1;
  default:
//  warning("%a: %s,%d: bad load optype %d", cmd.ea, cmd.get_canon_mnem(), x.n, x.type);
    break;
  }
  return 0;
}
示例#28
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);
        }
      }
示例#29
0
//----------------------------------------------------------------------
// поставим использование/изменение операндов
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;
  }
}
示例#30
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;
  }
}