示例#1
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()");
    }
}
示例#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 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;
  }
}
示例#4
0
文件: emu.cpp 项目: nealey/vera
ea_t calc_io_mem(op_t &op)
{
    ea_t addr = op.addr;
    sel_t pdp = 0;
    if (op.tms_regP == PDP)
    {
        pdp = getSR(toEA(cmd.cs, cmd.ip), PDP);
        if ( pdp == BADSEL ) return BADSEL;
        addr &= 0x7F;
    }
    ea_t ea = ((pdp & 0x1FF) << 7) | addr;
    return toEA(cmd.cs, ea);
}
示例#5
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;
      }
  }
}
示例#6
0
	/* outputs an operand 'x' */
bool outop(op_t &x)
{
// const char *ptr;
  ea_t v;
	switch (x.type)
	{
	case o_reg:
		out_register(ph.regNames[x.reg]);
		break;
	case o_imm:
		OutValue(x, OOFS_IFSIGN | OOFW_IMM);
		break;
	case o_mem:
	case o_near:
		v=toEA(cmd.cs, x.addr);
		if ( !out_name_expr(x, v, x.addr) )
		{
			OutValue(x, OOF_ADDR | OOF_NUMBER | OOFS_NOSIGN | OOFW_32);
			QueueMark(Q_noName, cmd.ea);
			break;
		}
		break;
	default:
		out_symbol('?');
		break;
	}
	return 1;
}
示例#7
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;
      }
  }
}
示例#8
0
文件: emu.cpp 项目: nealey/vera
//----------------------------------------------------------------------
int find_ar(ea_t *res)
{
  ea_t ea = cmd.ea;
  for ( int i=0; i < lookback; i++ )
  {
    ea = prevInstruction(ea);
    if ( !isCode(get_flags_novalue(ea)) ) break;
    ushort code = (ushort)get_full_byte(ea);
    if ( isC2() )
    {
      switch ( code >> 11 )
      {
        case 6:                 // LAR
          return 0;
        case 0x18:              // LARK
          *res = toEA(dataSeg(),(code & 0xFF));
          return 1;
        case 0x1A:              // LRLK
          if ( (code & 0xF8FF) == 0xD000 )
          {
            ushort b = (ushort)get_full_byte(ea+1);
            *res = toEA(dataSeg(), b);
            return 1;
          }
      }
      continue;
    }
    switch ( code >> 11 )
    {
      case 0:                   // Load AR from addressed data
        return 0;               // LAR found, unknown address
      case 0x16:                // Load AR short immediate
        *res = toEA(dataSeg(), code & 0xFF);
        return 1;
      case 0x17:                // Load AR long immediate
        if ( (code & ~7) == 0xBF08 )
        {
          ushort b = (ushort)get_full_byte(ea+1);
          *res = toEA(dataSeg(),b);
          return 1;
        }
    }
  }
  return 0;
}
示例#9
0
文件: emu.cpp 项目: nealey/vera
//----------------------------------------------------------------------
// Calculate the target data address
ea_t map_addr(asize_t off, int opnum, bool isdata)
{
  if ( isdata )
  {
    if ( isOff(uFlag, opnum) ) return get_offbase(cmd.ea, opnum) >> 4;
    return ((off >= 0x80 && off < 0x100) ? sfrmem : intmem) + off;
  }
  return toEA(codeSeg(off, opnum), off);
}
示例#10
0
文件: out.cpp 项目: nealey/vera
//----------------------------------------------------------------------
bool outop( op_t &x )
{
    uval_t v, v1;
//  const char *ptr;

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

    case o_indexed:
        OutValue( x, OOF_ADDR|OOF_SIGNED|(is_ext_insn() ? OOFW_32 : OOFW_16) ); //.addr
        v = x.value;
        out_symbol( '[' );
        if ( v != 0 ) goto OUTPHRASE;
        out_symbol( ']' );
        break;

    case o_indirect:
    case o_indirect_inc:
        out_symbol( '[' );

    case o_mem:
    case o_near:
        v = x.addr;
OUTPHRASE:
        v1 = toEA( getSR(cmd.ea, (x.type == o_near) ? rVcs : rVds), v);
        if( !out_name_expr( x, v1, v ) )
        {
            OutValue( x, (x.type == o_indexed ? 0 : OOF_ADDR) | OOF_NUMBER|OOFS_NOSIGN|
                      ((x.type == o_near) ? (is_ext_insn() ? OOFW_32 : OOFW_16) : OOFW_8) );
            QueueMark( Q_noName, cmd.ea );
        }

        if( x.type == o_indirect || x.type == o_indirect_inc ||
                x.type == o_indexed )
        {
            out_symbol( ']' );
            if( x.type == o_indirect_inc )    out_symbol( '+' );
        }
        break;

    case o_void:
        return 0;

    case o_bit:
        out_symbol( char('0' + x.reg) );
        break;

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

    return 1;
}
示例#11
0
文件: emu.cpp 项目: nealey/vera
//------------------------------------------------------------------------
ea_t calc_data_mem(op_t &op)
{
    ea_t addr = op.addr;
    sel_t dph = 0;
    if (op.tms_regH == DPH)
    {
        dph = getSR(toEA(cmd.cs, cmd.ip), DPH);
        if ( dph == BADSEL ) return BADSEL;
        addr &= 0xFFFF;
    }
    sel_t dp = 0;
    if (op.tms_regP == DP)
    {
        dp = getSR(toEA(cmd.cs, cmd.ip), DP);
        if ( dp == BADSEL ) return BADSEL;
        addr &= 0xFFFF;
    }
    return (((dph & 0x7F) << 16) | (dp + addr)) << 1;
}
示例#12
0
文件: emu.cpp 项目: nealey/vera
//------------------------------------------------------------------------
ea_t calc_code_mem(ea_t ea, bool is_near)
{
  if (is_near)
  {
    sel_t xpc = getSR(cmd.ea, XPC);
    if ( xpc == BADSEL ) xpc = 0;
    return ((xpc & 0x7F) << 16) | (ea & 0xFFFF);
  }
  return toEA(cmd.cs, ea);
}
示例#13
0
//----------------------------------------------------------------------
// Calculate the target data address
ea_t map_addr(asize_t off, int opnum, bool isdata)
{
  if ( isdata )
  {
    if ( isOff(uFlag, opnum) )
      return get_offbase(cmd.ea, opnum) >> 4;
    return intmem + off;
  }
  return toEA(codeSeg(off, opnum), off);
}
示例#14
0
文件: jptcmn.cpp 项目: nealey/vera
// This function finds and creates a 32-bit jump table
static bool check_for_table_jump2(is_pattern_t * const patterns[],
                                  size_t qty,
                                  void (*create_table)(jump_table_type_t jtt,
                                                       switch_info_ex_t &si),
                                  switch_info_ex_t &si)
{
  jump_table_type_t jtt = JT_NONE;
  insn_t saved = cmd;
  for ( int i=0; jtt == JT_NONE && i < qty; i++ )
  {
    jmsg("%a: check pattern %d ----\n", cmd.ea, i);
    si.clear();
    jtt = patterns[i](si);
    cmd = saved;
  }
  if ( jtt == JT_NONE )
    return false;

  jmsg("jumps=%a lowcase=%d. ncases=%d. elbase=%a defjump=%a\n",
       si.jumps, si.lowcase, si.ncases, si.elbase, si.defjump);
  if ( si.jumps != BADADDR )
    si.jumps = toEA(cmd.cs, si.jumps);
  if ( si.elbase != BADADDR )
  {
    si.elbase = toEA(cmd.cs, si.elbase);
    si.flags |=SWI_ELBASE;
  }
  if ( si.defjump != BADADDR )
    si.defjump = toEA(cmd.cs, si.defjump);

  if ( create_table == NULL )
    create_table = check_and_create_flat32;

  create_table(jtt, si);

  char buf[MAXSTR];
  qsnprintf(buf, sizeof(buf), "def_%a", cmd.ip);
  set_name(si.defjump, buf, SN_NOWARN|SN_LOCAL);
  qsnprintf(buf, sizeof(buf), "jpt_%a", cmd.ip);
  set_name(si.jumps, buf, SN_NOWARN);
//  msg("final size=%d.\n", size);
  return true;
}
示例#15
0
//--------------------------------------------------------------------------
static void declare_class(ea_t ea, const char *entryname)
{
  static const char class_name[] = "ClassStruct";
  struc_t *sptr = get_struc(get_struc_id(class_name));
  if ( sptr == NULL )
  {
    sptr = get_struc(add_struc(BADADDR, class_name));
    if ( sptr == NULL )
      return;
    opinfo_t mt;
    mt.ri.flags = REF_OFF32;
    mt.ri.target = BADADDR;
    mt.ri.base = 0;
    mt.ri.tdelta = 0;
    add_struc_member(sptr, "superClass",   BADADDR, offflag()|dwrdflag(), &mt,  4);
    add_struc_member(sptr, "masterOffset", BADADDR, wordflag(), NULL, 2);
    add_struc_member(sptr, "methodCount",  BADADDR, decflag()|wordflag(), NULL, 2);
    add_struc_member(sptr, "instanceSize", BADADDR, decflag()|wordflag(), NULL, 2);
    add_struc_member(sptr, "vdRelocTable", BADADDR, wordflag(), NULL, 2);
    add_struc_member(sptr, "relocTable",   BADADDR, wordflag(), NULL, 2);
    mt.ec.tid = get_class_struct_flags_enum();
    mt.ec.serial = 0;
    add_struc_member(sptr, "flags",        BADADDR, enumflag()|byteflag(), &mt, 1);
    add_struc_member(sptr, "masterMethods",BADADDR, byteflag(), NULL, 1);
  }
  asize_t size = get_struc_size(sptr);
  doStruct(ea, size, sptr->id);
  int count = get_word(ea+6);
//  bool c_handlers = get_byte(ea+14) & (1<<6);
  ea += size;
  ea_t messages = ea;
  doWord(ea, count*2);
  op_dec(ea, 0);
  ea += 2*count;
  doDwrd(ea, count*4);
  set_offset(ea, 0, 0);
  for ( int i=0; i < count; i++ )
  {
    ea_t idx = ea + 4*i;
    ea_t pea = toEA(get_word(idx+2), get_word(idx));
    auto_make_proc(pea);
    char name[MAXSTR];
    qsnprintf(name, sizeof(name), "%s_%u", entryname, get_word(messages+2*i));
    add_entry(pea, pea, name, true);
  }
// commented out because it doesn't work properly
// see geoplan.geo, entry number 1 for example
//  if ( c_handlers )
//    declare_parameter_types(ea+count*4, count);
}
示例#16
0
//----------------------------------------------------------------------
static int OutVarName(op_t &x, int iscode, int relative)
{
//char *ptr;
ushort addr = ushort(x.addr);
if(relative)
  {
  addr += (ushort)cmd.ip;
  addr += cmd.size;           // ig: this is tested only for 6809
  }
//Получить линейный адресс
ea_t toea = toEA((iscode || relative) ? codeSeg(addr,x.n) : dataSeg_op(x.n), addr);
//Получть строку для данного лин. адресса
return out_name_expr(x, toea, addr);
}
示例#17
0
static void OutVarNameVal(op_t &x)
{
ushort addr = x.value;
ulong toea = toEA(codeSeg(addr,x.n), addr);
#if IDP_INTERFACE_VERSION > 37
	if(out_name_expr(x,toea,addr))return;
#else
	const char *ptr;
	if((ptr=get_name_expr(cmd.ea+x.offb, toea, addr)) != NULL){
		//вывод имен переменных и меток перехода
	    OutLine(ptr);
	}
#endif
else OutValue(x, OOFW_16);
}
示例#18
0
// output an address
static void outaddr(op_t &op, const bool replace_with_label = true) {
    bool ind = is_addr_ind(op);      // is operand indirect ?
    bool sp = is_addr_sp(op);        // is operand special page ?

    int size = 16;  // operand is 16 bits long

    if ( ind)    out_symbol('(' );
    if ( sp)     { out_symbol('\\' ); size = 8; /* just display the first 8 bits */ }

    if ( !out_name_expr(op, toEA(cmd.cs, op.addr), op.addr) || !replace_with_label)
    {
        if ( replace_with_label) out_tagon(COLOR_ERROR );
        OutValue(op, OOF_ADDR | OOFS_NOSIGN | (size < 16 ? OOFW_8 : OOFW_16) );
        if ( replace_with_label) out_tagoff(COLOR_ERROR );
    }

    if ( ind)    out_symbol(')' );
}
示例#19
0
文件: emu.cpp 项目: nealey/vera
//----------------------------------------------------------------------
int emu(void)
{
  uint32 feature = cmd.get_canon_feature();
  flow = (feature & CF_STOP) == 0;

  if ((cmd.auxpref & DBrFlag) == 0)   // У отложенных переходов не надо обрабатывать операнды, т.к.
                                      // регистры и так не обрабатываются, а адр. перехода будет обработан через 3 команды
  {
        if ( feature & CF_USE1 ) process_operand(cmd.Op1, 1);
        if ( feature & CF_USE2 ) process_operand(cmd.Op2, 1);
        if ( feature & CF_USE3 ) process_operand(cmd.Op3, 1);

        if ( feature & CF_CHG1 ) process_operand(cmd.Op1, 0);
        if ( feature & CF_CHG2 ) process_operand(cmd.Op2, 0);
        if ( feature & CF_CHG3 ) process_operand(cmd.Op3, 0);
  }


  if  (GetDelayedBranchAdr() != BADADDR)  // добавить ссылку по отложенному переходу
        ua_add_cref(0, toEA(cmd.cs, GetDelayedBranchAdr()), fl_JN);

  if  (cmd.itype == TMS320C3X_RETScond)  // добавить ссылку по условному выходу
        ua_add_cref(0, cmd.ea, fl_JN);

  // check for DP changes
  if ( ((cmd.itype == TMS320C3X_LDIcond) || (cmd.itype == TMS320C3X_LDI)) && (cmd.Op1.type == o_imm)
    && (cmd.Op2.type == o_reg) && (cmd.Op2.reg == dp))
      splitSRarea1(get_item_end(cmd.ea), dp, cmd.Op1.value & 0xFF, SR_auto);

  // determine if the next instruction should be executed
  if ( segtype(cmd.ea) == SEG_XTRN ) flow = 0;
  if ( flow && delayed_stop() ) 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;
}
示例#20
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;
  }
}
示例#21
0
//----------------------------------------------------------------------
//      This is jump table pattern #2
//      (*1* may be omitted...IE, this logic is located above jump table sizing instructions)
//0100    *1*          sub.b   r0h, r0h
//0102                 add.w   r0, r0
//0104                 mov.w   @(jpt_108:16,r0), r0
//0108                 jmp     @r0
//----------------------------------------------------------------------
static bool is_jump_pattern2(ea_t *base, ea_t *table, ea_t *defea, int *size, int *elsize)
{
  int reg = cmd.Op1.phrase;
  if ( decode_prev_insn(cmd.ea) == BADADDR
    || cmd.itype != H8_mov                      // mov.w   @(table:16,r0), r0
    || (cmd.auxpref & aux_word) == 0
    || cmd.Op1.type != o_displ
    || cmd.Op2.reg  != reg    ) return false;
  *table  = cmd.Op1.addr;
  int rx  = cmd.Op1.reg;
  *base   = 0;
  ea_t bea = toEA(cmd.cs, 0);
  set_offset(cmd.ea, 0, bea);

  if ( decode_prev_insn(cmd.ea) == BADADDR
    || cmd.itype != H8_add                      // add.w r0, r0
    || (cmd.auxpref & aux_word) == 0
    || cmd.Op1.type != o_reg
    || cmd.Op1.reg  != rx
    || cmd.Op2.reg  != rx     ) return false;
  int rhx = rx + 16;
  int rlx = rhx + 8;

  ea_t oldea = cmd.ea;
  ea_t oldip = cmd.ip;
  if ( decode_prev_insn(cmd.ea) == BADADDR
    || (cmd.itype != H8_sub && cmd.itype != H8_xor) // sub.b rhx, rhx
    || (cmd.auxpref & aux_byte) == 0
    || cmd.Op1.type != o_reg
    || cmd.Op2.type != o_reg
    || cmd.Op1.reg  != rhx
    || cmd.Op2.reg  != rhx    ) // return false;
  {
    cmd.ea = oldea; // forgive this...
    cmd.ip = oldip;
  }

  // the jump table is found, try to determine its size
  *elsize = 2;
  return find_table_size(defea, size, rlx, cmd.ip);
}
示例#22
0
文件: emu.cpp 项目: nealey/vera
//----------------------------------------------------------------------
ea_t calc_mem(op_t &x)
{
  uint xaddr;

  if ( x.amode & amode_x )
  {
          if (x.amode & amode_short)
          {
                sel_t dpage = getSR(cmd.ea, PAGE);
                if ( dpage == BADSEL ) return BADSEL;
                xaddr = ((dpage & 0xFF) << 8) | uint(x.addr);
          }
          else
                xaddr = (uint)x.addr;

          return xmem == BADADDR ? BADADDR : xmem + xaddr;
  }

  return toEA(cmd.cs, x.addr);

}
示例#23
0
static void OutVarName(op_t &x)
{
ea_t addr = x.addr;
ea_t toea = toEA(codeSeg(addr,x.n), addr);
#if IDP_INTERFACE_VERSION > 37
//      msg("AT:%a target=%lx, segm=%lx, Result=%lx\n",
//                      cmd.ea,addr, codeSeg(addr,x.n),toea);
        if ( out_name_expr(x,toea,addr) )return;
#else
        const char *ptr;
        if ( (ptr=get_name_expr(cmd.ea+x.offb, toea, addr)) != NULL ){
                //вывод имен переменных и меток перехода
            OutLine(ptr);
        }
#endif
        else{
                OutValue(x, OOF_ADDR | OOF_NUMBER |
                                        OOFS_NOSIGN | OOFW_32);
                // пометим проблему - нет имени
                QueueMark(Q_noName,cmd.ea);
        }
}
示例#24
0
//----------------------------------------------------------------------
ea_t calc_mem(op_t &x)
{
  if ( x.type == o_near )
    return toEA(cmd.cs, x.addr);

// Before this was simply toEA, now we do it like this:
// (if someone complains, both methods should be retained)
  ea_t ea = x.addr;
  switch ( calc_sizer(x) )
  {
    case 8:
      if ( cmd.auxpref & aux_page )
      {
        ea &= 0xFF;
        sel_t br = getSR(cmd.ea, BR);
        if ( br != BADSEL )
          ea |= br << 8;
        else
          ea = BADADDR;
      }
      break;
    case 16:
      ea &= 0xFFFF;
      if ( x.type == o_mem )
      {
        sel_t dp = getSR(cmd.ea, DP);
        if ( dp != BADSEL )
          ea |= dp << 16;
        else
          ea = BADADDR;
      }
      else
      {
        ea |= cmd.ea & ~0xFFFF;
      }
      break;
  }
  return ea;
}
示例#25
0
文件: emu.cpp 项目: nealey/vera
//----------------------------------------------------------------------
static void TouchArg(op_t &x,int isload)
{
  switch ( x.type )
  {
    case o_regpair:
    case o_reg:
    case o_phrase:
    case o_spmask:
    case o_stgcyc:
      break;
    case o_imm:
      if ( !isload )
        goto badTouch;
      /* no break */
    case o_displ:
      doImmdValue(x.n);
      if ( op_adds_xrefs(uFlag, x.n) )
      {
        int outf = x.type != o_imm ? OOF_ADDR : 0;
        if ( x.dtyp == dt_word )
          outf |= OOF_SIGNED;
        ua_add_off_drefs2(x, dr_O, outf);
      }
      break;
    case o_near:
      {
        ea_t ea = toEA(cmd.cs,x.addr);
        ea_t ref = find_first_insn_in_packet(ea);
        ua_add_cref(x.offb, ref, fl_JN);
      }
      break;
    default:
badTouch:
      warning("%a: %s,%d: bad optype %d", cmd.ea, cmd.get_canon_mnem(), x.n, x.type);
      break;
  }
}
示例#26
0
//----------------------------------------------------------------------
static void TouchArg(op_t &x,int isload)
{
  switch ( x.type )
  {
    case o_regpair:
    case o_reg:
    case o_phrase:
      break;
    case o_imm:
      if ( !isload ) goto badTouch;
      /* no break */
    case o_displ:
      doImmdValue(x.n);
      if ( isOff(uFlag, x.n) ) ua_add_off_drefs(x, dr_O);
      break;
    case o_near:
      ua_add_cref(x.offb,toEA(cmd.cs,x.addr),fl_JN);
      break;
    default:
badTouch:
      warning("%a: %s,%d: bad optype %d", cmd.ea, cmd.get_canon_mnem(), x.n, x.type);
      break;
  }
}
示例#27
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;
  }
}
示例#28
0
文件: reg.cpp 项目: nealey/vera
static int notify(processor_t::idp_notify msgid, ...)   // Various messages
{
  va_list va;
  va_start(va, msgid);

// A well behaving processor module should call invoke_callbacks()
// in his notify() function. If this function returns 0, then
// the processor module should process the notification itself
// Otherwise the code should be returned to the caller:

  int code = invoke_callbacks(HT_IDP, msgid, va);
  if ( code ) return code;

  switch ( msgid )
  {
    case processor_t::newfile:
      {
// ig: вообще у меня теперь такая точка зрения:
//     не надо в коде задавать вид имен.
//     при желании это можно сделать в ida.cfg:
//      #ifdef __80196__
//        DUMMY_NAMES_TYPE = NM_SHORT
//      #endif

        segment_t *sptr = get_first_seg();
        if( sptr != NULL )    set_segm_class( sptr, "CODE" );

        ea_t ea, ea1;

        for( int i = 0; i < qnumber(entries); i++ )
        {
          ea = toEA( inf.baseaddr, entries[i].off );

          if( isEnabled(ea) )
          {
            switch( entries[i].type )
            {
              case I196F_BTS:
                doByte( ea, entries[i+1].off-entries[i].off );
                set_cmt( ea, entries[i].cmt, 0 );
                break;

              case I196F_CMT:
                if( entries[i].cmt )
                  add_long_cmt( ea, 1, "%s", entries[i].cmt );
                else
                  describe( ea, 1, "" );
                break;

              case I196F_OFF:
                doWord( ea, 2 );
                set_offset( ea, 0, toEA( inf.baseaddr, 0 ) );

                ea1 = toEA( inf.baseaddr, get_word( ea ) );
                auto_make_proc( ea1 );
//dash: long_cmt здесь не смотрится, так как рисуется до заголовка
//      хорошо бы поставить func_cmt, но к этому моменту функций еще нет
//      как быть?
//ig: воспользоваться простым комментарием
//    при создании функции комментарий перетащится
                set_cmt( ea1, entries[i].cmt, 1 );
            }

            set_name( ea, entries[i].name );
          }
        }

        ea = toEA( inf.baseaddr, 0x2080 );
        if( isEnabled( ea ) )
        {
          inf.beginEA = ea;
          inf.startIP = 0x2080;
        }

        segment_t s;
        s.startEA = toEA( inf.baseaddr, 0 );
        s.endEA   = toEA( inf.baseaddr, 0x400 );
        s.sel     = inf.baseaddr;
        s.type    = SEG_IMEM;                         // internal memory
// ig: лучше искать дырку не от нуля, а от базы загрузки
//      ea_t bottom = toEA( inf.baseaddr, 0 );
//      intmem    = s.startEA = freechunk( bottom, 1024, 0xF );
//      s.endEA   = s.startEA + 1024;
//      s.sel     = ushort(s.startEA >> 4);
// dash: дырку искать не пришлось, но я оставил это как пример на будущее
        add_segm_ex( &s, "INTMEM", NULL, ADDSEG_OR_DIE);

        predefined_t *ptr;
        for( ptr = iregs; ptr->name != NULL; ptr++ )
        {
          ea_t ea = toEA( inf.baseaddr, ptr->addr );
          ea_t oldea = get_name_ea( BADADDR, ptr->name );
          if( oldea != ea )
          {
            if( oldea != BADADDR )    set_name( oldea, NULL );
            do_unknown( ea, DOUNK_EXPAND );
            set_name( ea, ptr->name );
          }
          if( ptr->cmt != NULL )      set_cmt( ea, ptr->cmt, 1 );
        }
      }
//      do16bit( 0x18, 2 );           // SP always word
      break;

    case processor_t::oldfile:
      for ( segment_t *s=get_first_seg(); s != NULL; s=get_next_seg(s->startEA) )
      {
        if ( getSRarea(s->startEA) == NULL )
        {
          segreg_t sr;
          sr.startEA = s->startEA;
          sr.endEA   = s->endEA;
          sr.reg(WSR)  = 0;
          sr.reg(WSR1) = 0;
          sr.reg(rVds) = inf.baseaddr;
          sr.settags(SR_autostart);
          SRareas.create_area(&sr);
        }
      }
      break;

    case processor_t::newseg:
                      // default DS is equal to Base Address
      (va_arg(va, segment_t *))->defsr[rVds-ph.regFirstSreg] = inf.baseaddr;
      break;

    case processor_t::newprc:
      extended = va_arg(va,int) != 0;
      if ( !extended )
        ph.flag &= ~PR_SEGS;
      else
        ph.flag |= PR_SEGS;
    default:
      break;
  }
  va_end(va);

  return(1);
}
示例#29
0
文件: out.cpp 项目: nealey/vera
// Output an operand as an address
inline void out_addr(op_t &op, bool find_label = true) {
    if ( !find_label || !out_name_expr(op, toEA(cmd.cs, op.addr), op.addr) )
        OutValue(op, OOF_ADDR | OOFS_NOSIGN);
}
示例#30
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;
}