Example #1
0
void make_stack_var(op_t &x)
{
  if (may_create_stkvars())
  {
    adiff_t sp_off = x.value;
    if ( ua_stkvar2(x, sp_off, 0) )
      op_stkvar(cmd.ea, x.n);
  }
}
Example #2
0
File: emu.cpp Project: 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;

  }
}
Example #3
0
File: emu.cpp Project: 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()");
    }
}
Example #4
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);
  }
}
Example #5
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);
  }
}
Example #6
0
/*
#<pydoc>
def ua_stkvar2(op, outflags = 0):
    """
    Create or modify a stack variable in the function frame.
    Please check ua.hpp / ua_stkvar2()
    @param op: operand (of type op_t)
    @return: None
    """
    pass
#</pydoc>
*/
static bool py_ua_stkvar2(PyObject *x, adiff_t v, int flags)
{
  PYW_GIL_CHECK_LOCKED_SCOPE();
  op_t *op = op_t_get_clink(x);
  return op == NULL ? false : ua_stkvar2(*op, v, flags);
}
Example #7
0
File: emu.cpp Project: 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);
    }
}
Example #8
0
File: emu.cpp Project: 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);
  }
}
Example #9
0
File: emu.cpp Project: nealey/vera
// emulate operand
static void handle_operand(op_t &op, bool loading) {
    switch ( op.type ) {

        // Address
        case o_near:
            // branch label - create code reference (call or jump
            // according to the instruction)
            {
              ea_t ea = toEA(cmd.cs, op.addr);
              cref_t ftype = fl_JN;
              if ( cmd.itype == m32r_bl )
              {
                if ( !func_does_return(ea) )
                  flow = false;
                ftype = fl_CN;
              }
              ua_add_cref(op.offb, ea, ftype);
            }
            break;

        // Immediate
        case o_imm:
            if ( !loading ) {
                   interr1("handle_operand(): o_imm with CF_CHG");
            }
            handle_imm();
            // if the value was converted to an offset, then create a data xref:
            if ( op_adds_xrefs(uFlag, op.n) )
              ua_add_off_drefs2(op, dr_O, OOFW_IMM|OOF_SIGNED);

            // 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);
            }
            break;

        // Displ
        case o_displ:
            handle_imm();
            // if the value was converted to an offset, then create a data xref:
            if ( op_adds_xrefs(uFlag, op.n) )
              ua_add_off_drefs2(op, loading ? dr_R : dr_W, OOF_SIGNED|OOF_ADDR|OOFW_32);

            // create stack variables if required
            if ( may_create_stkvars() && !isDefArg(uFlag, op.n) ) {
                func_t *pfn = get_func(cmd.ea);
                if ( pfn != NULL && (op.reg == rFP || op.reg == rSP) && pfn->flags & FUNC_FRAME ) {
                      if ( ua_stkvar2(op, op.addr, STKVAR_VALID_SIZE) ) {
                        op_stkvar(cmd.ea, op.n);
                    }
                }
              }
            break;

        case o_phrase:
            /* create stack variables if required */
            if ( op.specflag1 == fRI && may_create_stkvars() && !isDefArg(uFlag, op.n) ) {
                func_t *pfn = get_func(cmd.ea);
                if ( pfn != NULL && (op.reg == rFP || op.reg == rSP) && pfn->flags & FUNC_FRAME ) {
                    if ( ua_stkvar2(op, 0, STKVAR_VALID_SIZE) ) {
                        op_stkvar(cmd.ea, op.n);
                    }
                }
            }
            break;

        // Phrase - register - void : do nothing
        case o_reg:
        case o_void:
            break;

        // Others types should never be called
        default:
            interr2("handle_operand(): unknown type %d", op.type);
            break;
    }
}
Example #10
0
File: emu.cpp Project: 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);
    }
}