예제 #1
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;
      }
  }
}
예제 #2
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;
      }
  }
}
예제 #3
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");
  }
}
예제 #4
0
//----------------------------------------------------------------------
static void add_code_xref(op_t &x, ea_t ea)
{
  cref_t ftype = fl_JN;
  if ( InstrIsSet(cmd.itype, CF_CALL) )
  {
    if ( !func_does_return(ea) )
      flow = false;
    ftype = fl_CN;
  }
  ua_add_cref(x.offb, ea, ftype);
}
예제 #5
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);
  }
}
예제 #6
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;
  }
}
예제 #7
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;
}
예제 #8
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);
  }
}
예제 #9
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;
}
예제 #10
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_imm:
    {
    //Установить для данного байта признак 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_drefs(x, dr_O);
        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_bit:
  case o_mem:
    // Конвертирование в данные(указан адресс) по указанному типу,
    //добавить крос референсы для текущей инструкции
    DataSet(x, toEA(codeSeg(x.addr,x.n), x.addr), isload);
    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 ( iscall )  flow = func_does_return(ea);
    } break;

  default:
    warning("%a: %s,%d: bad optype %d", cmd.ea, cmd.get_canon_mnem(), x.n, x.type);
    break;
  }
}
예제 #11
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);
  }
}
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);
}
예제 #13
0
파일: emu.cpp 프로젝트: nealey/vera
//----------------------------------------------------------------------
int emu(void)
{
  if ( segtype(cmd.ea) == SEG_XTRN ) return 1;

  //uint32 Feature = cmd.get_canon_feature();
  int flag1 = is_forced_operand(cmd.ea, 0);
  int flag2 = is_forced_operand(cmd.ea, 1);
  int flag3 = is_forced_operand(cmd.ea, 2);

//      Determine if the next instruction should be executed
  flow = (InstrIsSet(cmd.itype, CF_STOP) != true);



  if ( InstrIsSet(cmd.itype,CF_USE1) ) process_operand(cmd.Op1, flag1, 1);
  if ( InstrIsSet(cmd.itype,CF_USE2) ) process_operand(cmd.Op2, flag2, 1);
  if ( InstrIsSet(cmd.itype,CF_USE3) ) process_operand(cmd.Op3, flag3, 1);

  if ( InstrIsSet(cmd.itype,CF_CHG1) ) process_operand(cmd.Op1, flag1, 0);
  if ( InstrIsSet(cmd.itype,CF_CHG2) ) process_operand(cmd.Op2, flag2, 0);
  if ( InstrIsSet(cmd.itype,CF_CHG3) ) process_operand(cmd.Op3, flag3, 0);


  // check for DP changes
  if ( cmd.itype == OAK_Dsp_lpg )
                splitSRarea1(get_item_end(cmd.ea), PAGE, cmd.Op1.value & 0xFF, SR_auto);
  if ( ( cmd.itype == OAK_Dsp_mov ) && (cmd.Op1.type == o_imm) && (cmd.Op2.type == o_reg) && (cmd.Op2.reg == ST1) )
                splitSRarea1(get_item_end(cmd.ea), PAGE, cmd.Op1.value & 0xFF, SR_auto);


  //Delayed Return

  insn_t saved = cmd;
  cycles = cmd.cmd_cycles;
  delayed = false;

  if ( decode_prev_insn(cmd.ea) != BADADDR )
  {
          if  ( (cmd.itype == OAK_Dsp_retd) || (cmd.itype == OAK_Dsp_retid) )
                  delayed = true;
          else
                  cycles += cmd.cmd_cycles;

          if (!delayed)
                if ( decode_prev_insn(cmd.ea) != BADADDR )
                        if ( (cmd.itype == OAK_Dsp_retd) || (cmd.itype == OAK_Dsp_retid) )
                                delayed = true;
  }

  if (delayed && (cycles > 1) )
          flow = 0;

  cmd = saved;

  //mov #imm, pc

  if ( ( cmd.itype == OAK_Dsp_mov ) && (cmd.Op2.type == o_reg) && (cmd.Op2.reg == PC) )
     flow = 0;

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

  if ( may_trace_sp() )
  {
    if ( !flow )
      recalc_spd(cmd.ea);     // recalculate SP register for the next insn
    else
      trace_sp();
  }

  return 1;
}
예제 #14
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);
  }
}
예제 #15
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;
}
예제 #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
//----------------------------------------------------------------------
// поставим использование/изменение операндов
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);
    }
}