IDA C++ SDK 9.2
|
A microinstruction operand. More...
#include <hexrays.hpp>
Public Member Functions | |
void | set_impptr_done () |
void | set_udt () |
void | set_undef_val () |
void | set_lowaddr () |
void | set_for_abi () |
bool | is_impptr_done () const |
bool | is_udt () const |
bool | probably_floating () const |
bool | is_undef_val () const |
bool | is_lowaddr () const |
bool | is_for_abi () const |
bool | is_ccflags () const |
bool | is_pcval () const |
bool | is_glbaddr_from_fixup () const |
mop_t () | |
mop_t (const mop_t &rop) | |
mop_t (mreg_t _r, int _s) | |
mop_t & | operator= (const mop_t &rop) |
mop_t &hexapi | assign (const mop_t &rop) |
~mop_t () | |
HEXRAYS_MEMORY_ALLOCATION_FUNCS () void zero() | |
void hexapi | swap (mop_t &rop) |
void hexapi | erase () |
void | erase_but_keep_size () |
void hexapi | print (qstring *vout, int shins_flags=SHINS_SHORT|SHINS_VALNUM) const |
const char *hexapi | dstr () const |
bool hexapi | create_from_mlist (mba_t *mba, const mlist_t &lst, sval_t fullsize) |
Create operand from mlist_t. | |
bool hexapi | create_from_ivlset (mba_t *mba, const ivlset_t &ivs, sval_t fullsize) |
Create operand from ivlset_t. | |
void hexapi | create_from_vdloc (mba_t *mba, const vdloc_t &loc, int _size) |
Create operand from vdloc_t. | |
void hexapi | create_from_scattered_vdloc (mba_t *mba, const char *name, tinfo_t type, const vdloc_t &loc) |
Create operand from scattered vdloc_t. | |
void hexapi | create_from_insn (const minsn_t *m) |
Create operand from an instruction. | |
void hexapi | make_number (uint64 _value, int _size, ea_t _ea=BADADDR, int opnum=0) |
Create an integer constant operand. | |
bool hexapi | make_fpnum (const void *bytes, size_t _size) |
Create a floating point constant operand. | |
void | _make_reg (mreg_t reg) |
Create a register operand without erasing previous data. | |
void | _make_reg (mreg_t reg, int _size) |
void | make_reg (mreg_t reg) |
Create a register operand. | |
void | make_reg (mreg_t reg, int _size) |
void | _make_lvar (mba_t *mba, int idx, sval_t off=0) |
Create a local variable operand. | |
void hexapi | _make_gvar (ea_t ea) |
Create a global variable operand without erasing previous data. | |
void hexapi | make_gvar (ea_t ea) |
Create a global variable operand. | |
void | _make_stkvar (mba_t *mba, sval_t off) |
Create a stack variable operand. | |
void | make_stkvar (mba_t *mba, sval_t off) |
void hexapi | make_reg_pair (int loreg, int hireg, int halfsize) |
Create pair of registers. | |
void | _make_insn (minsn_t *ins) |
Create a nested instruction without erasing previous data. | |
void | make_insn (minsn_t *ins) |
Create a nested instruction. | |
void | _make_blkref (int blknum) |
Create a block reference operand without erasing previous data. | |
void | make_blkref (int blknum) |
Create a global variable operand. | |
void hexapi | make_helper (const char *name) |
Create a helper operand. | |
void | _make_strlit (const char *str) |
Create a constant string operand. | |
void | _make_strlit (qstring *str) |
void | _make_callinfo (mcallinfo_t *fi) |
Create a call info operand without erasing previous data. | |
void | _make_cases (mcases_t *_cases) |
Create a 'switch cases' operand without erasing previous data. | |
void | _make_pair (mop_pair_t *_pair) |
Create a pair operand without erasing previous data. | |
bool | empty () const |
bool | is_glbvar () const |
Is a global variable? | |
bool | is_stkvar () const |
Is a stack variable? | |
bool | is_reg () const |
Is a register operand? | |
bool | is_reg (mreg_t _r) const |
Is the specified register? | |
bool | is_reg (mreg_t _r, int _size) const |
Is the specified register of the specified size? | |
bool | is_arglist () const |
Is a list of arguments? | |
bool | is_cc () const |
Is a condition code? | |
bool | is_bit_reg () const |
bool | is_kreg () const |
Is a kernel register? | |
bool | is_mblock () const |
Is a block reference? | |
bool | is_mblock (int serial) const |
Is a block reference to the specified block? | |
bool | is_scattered () const |
Is a scattered operand? | |
bool | is_glbaddr () const |
Is address of a global memory cell? | |
bool | is_glbaddr (ea_t ea) const |
Is address of the specified global memory cell? | |
bool | is_stkaddr () const |
Is address of a stack variable? | |
bool | is_insn () const |
Is a sub-instruction? | |
bool | is_insn (mcode_t code) const |
Is a sub-instruction with the specified opcode? | |
bool | has_side_effects (bool include_ldx_and_divs=false) const |
Has any side effects? | |
bool hexapi | may_use_aliased_memory () const |
Is it possible for the operand to use aliased memory? | |
bool hexapi | is01 () const |
Are the possible values of the operand only 0 and 1? | |
bool hexapi | is_sign_extended_from (int nbytes) const |
Does the high part of the operand consist of the sign bytes? | |
bool hexapi | is_zero_extended_from (int nbytes) const |
Does the high part of the operand consist of zero bytes? | |
bool | is_extended_from (int nbytes, bool is_signed) const |
Does the high part of the operand consist of zero or sign bytes? | |
bool hexapi | equal_mops (const mop_t &rop, int eqflags) const |
Compare operands. | |
bool | operator== (const mop_t &rop) const |
bool | operator!= (const mop_t &rop) const |
bool | operator< (const mop_t &rop) const |
Lexographical operand comparison. | |
int hexapi | lexcompare (const mop_t &rop) const |
int hexapi | for_all_ops (mop_visitor_t &mv, const tinfo_t *type=nullptr, bool is_target=false) |
Visit the operand and all its sub-operands. | |
int hexapi | for_all_scattered_submops (scif_visitor_t &sv) const |
Visit all sub-operands of a scattered operand. | |
uint64 | value (bool is_signed) const |
Retrieve value of a constant integer operand. | |
int64 | signed_value () const |
uint64 | unsigned_value () const |
void | update_numop_value (uint64 val) |
bool hexapi | is_constant (uint64 *out=nullptr, bool is_signed=true) const |
Retrieve value of a constant integer operand. | |
bool | is_equal_to (uint64 n, bool is_signed=true) const |
bool | is_zero () const |
bool | is_one () const |
bool | is_positive_constant () const |
bool | is_negative_constant () const |
ssize_t | get_stkvar (udm_t *udm=nullptr, uval_t *p_idaoff=nullptr) const |
Retrieve the referenced stack variable. | |
bool hexapi | get_stkoff (sval_t *p_vdoff) const |
Get the referenced stack offset. | |
const minsn_t * | get_insn (mcode_t code) const |
Get subinstruction of the operand. | |
minsn_t * | get_insn (mcode_t code) |
bool hexapi | make_low_half (int width) |
Make the low part of the operand. | |
bool hexapi | make_high_half (int width) |
Make the high part of the operand. | |
bool hexapi | make_first_half (int width) |
Make the first part of the operand. | |
bool hexapi | make_second_half (int width) |
Make the second part of the operand. | |
bool hexapi | shift_mop (int offset) |
Shift the operand. | |
bool hexapi | change_size (int nsize, side_effect_t sideff=WITH_SIDEFF) |
Change the operand size. | |
bool | double_size (side_effect_t sideff=WITH_SIDEFF) |
bool hexapi | preserve_side_effects (mblock_t *blk, minsn_t *top, bool *moved_calls=nullptr) |
Move subinstructions with side effects out of the operand. | |
void hexapi | apply_ld_mcode (mcode_t mcode, ea_t ea, int newsize) |
Apply a unary opcode to the operand. | |
void | apply_xdu (ea_t ea, int newsize) |
void | apply_xds (ea_t ea, int newsize) |
Static Public Member Functions | |
static bool hexapi | is_bit_reg (mreg_t reg) |
Is a bit register? |
Public Attributes | |
mopt_t | t |
Operand type. | |
uint8 | oprops |
Operand properties. | |
uint16 | valnum |
Value number. | |
int | size |
Operand size. | |
union { | |
mreg_t r | |
mnumber_t * nnn | |
minsn_t * d | |
stkvar_ref_t * s | |
ea_t g | |
int b | |
mcallinfo_t * f | |
lvar_ref_t * l | |
mop_addr_t * a | |
char * helper | |
char * cstr | |
mcases_t * c | |
fnumber_t * fpc | |
mop_pair_t * pair | |
scif_t * scif | |
}; | |
The following union holds additional details about the operand. |
Friends | |
int | lexcompare (const mop_t &a, const mop_t &b) |
A microinstruction operand.
This is the smallest building block of our microcode. Operands will be part of instructions, which are then grouped into basic blocks. The microcode consists of an array of such basic blocks + some additional info.
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
|
inline |
Create operand from mlist_t.
Example: if LST contains 4 bits for R0.4, our operand will be (t=mop_r, r=R0, size=4)
mba | pointer to microcode |
lst | list of locations |
fullsize | mba->fullsize |
Create operand from ivlset_t.
Example: if IVS contains [glbvar..glbvar+4), our operand will be (t=mop_v, g=&glbvar, size=4)
mba | pointer to microcode |
ivs | set of memory intervals |
fullsize | mba->fullsize |
Create operand from vdloc_t.
Example: if LOC contains (type=ALOC_REG1, r=R0), our operand will be (t=mop_r, r=R0, size=_SIZE)
mba | pointer to microcode |
loc | location |
_size | operand size Note: this function cannot handle scattered locations. |
|
inline |
Create operand from scattered vdloc_t.
Example: if LOC is (ALOC_DIST, {EAX.4, EDX.4}) and TYPE is _LARGE_INTEGER, our operand will be (t=mop_sc, scif={EAX.4, EDX.4})
mba | pointer to microcode |
name | name of the operand, if available |
type | type of the operand, must be present |
loc | a scattered location |
Create operand from an instruction.
This function creates a nested instruction that can be used as an operand. Example: if m="add x,y,z", our operand will be (t=mop_d,d=m). The destination operand of 'add' (z) is lost.
m | instruction to embed into operand. may not be nullptr. |
Create an integer constant operand.
_value | value to store in the operand |
_size | size of the value in bytes (1,2,4,8) |
_ea | address of the processor instruction that made the value |
opnum | operand number of the processor instruction |
Create a floating point constant operand.
bytes | pointer to the floating point value as used by the current processor (e.g. for x86 it must be in IEEE 754) |
_size | number of bytes occupied by the constant. |
Create a register operand without erasing previous data.
reg | micro register number Note: this function does not erase the previous contents of the operand; call erase() if necessary |
Create a local variable operand.
mba | pointer to microcode |
idx | index into mba->vars |
off | offset from the beginning of the variable Note: this function does not erase the previous contents of the operand; call erase() if necessary |
Create a global variable operand without erasing previous data.
ea | address of the variable Note: this function does not erase the previous contents of the operand; call erase() if necessary |
Create a stack variable operand.
mba | pointer to microcode |
off | decompiler stkoff Note: this function does not erase the previous contents of the operand; call erase() if necessary |
|
inline |
Create pair of registers.
loreg | register holding the low part of the value |
hireg | register holding the high part of the value |
halfsize | the size of each of loreg/hireg |
Create a nested instruction without erasing previous data.
ins | pointer to the instruction to encapsulate into the operand Note: this function does not erase the previous contents of the operand; call erase() if necessary See also create_from_insn, which is higher level |
|
inline |
Create a block reference operand without erasing previous data.
blknum | block number Note: this function does not erase the previous contents of the operand; call erase() if necessary |
|
inline |
Create a global variable operand.
|
inline |
Create a helper operand.
A helper operand usually keeps a built-in function name like "va_start" It is essentially just an arbitrary identifier without any additional info.
|
inline |
Create a constant string operand.
|
inline |
Create a call info operand without erasing previous data.
fi | callinfo Note: this function does not erase the previous contents of the operand; call erase() if necessary |
Create a 'switch cases' operand without erasing previous data.
Note: this function does not erase the previous contents of the operand; call erase() if necessary
|
inline |
Create a pair operand without erasing previous data.
Note: this function does not erase the previous contents of the operand; call erase() if necessary
|
inline |
|
inline |
Is a global variable?
|
inline |
Is a stack variable?
|
inline |
Is a register operand?
See also get_mreg_name()
Is the specified register of the specified size?
|
inline |
Is a list of arguments?
|
inline |
Is a condition code?
Is a bit register?
This includes condition codes and eventually other bit registers
|
inline |
|
inline |
Is a kernel register?
|
inline |
Is a block reference?
|
inline |
Is a block reference to the specified block?
|
inline |
Is a scattered operand?
|
inline |
Is address of a global memory cell?
|
inline |
Is address of a stack variable?
|
inline |
Is a sub-instruction?
Has any side effects?
include_ldx_and_divs | consider ldx/div/mod as having side effects? |
|
inline |
Is it possible for the operand to use aliased memory?
|
inline |
Are the possible values of the operand only 0 and 1?
This function returns true for 0/1 constants, bit registers, the result of 'set' insns, etc.
|
inline |
Does the high part of the operand consist of the sign bytes?
nbytes | number of bytes that were sign extended. the remaining size-nbytes high bytes must be sign bytes Example: is_sign_extended_from(xds.4(op.1), 1) -> true because the high 3 bytes are certainly sign bits |
|
inline |
Does the high part of the operand consist of zero bytes?
nbytes | number of bytes that were zero extended. the remaining size-nbytes high bytes must be zero Example: is_zero_extended_from(xdu.8(op.1), 2) -> true because the high 6 bytes are certainly zero |
Does the high part of the operand consist of zero or sign bytes?
Compare operands.
This is the main comparison function for operands.
rop | operand to compare with |
eqflags | combination of comparison bits bits |
Lexographical operand comparison.
It can be used to store mop_t in various containers, like std::set
|
inline |
|
inline |
Visit the operand and all its sub-operands.
This function visits the current operand as well.
mv | visitor object |
type | operand type |
is_target | is a destination operand? |
|
inline |
Visit all sub-operands of a scattered operand.
This function does not visit the current operand, only its sub-operands. All sub-operands are synthetic and are destroyed after the visitor. This function works only with scattered operands.
sv | visitor object |
Retrieve value of a constant integer operand.
These functions can be called only for mop_n operands. See is_constant() that can be called on any operand.
|
inline |
|
inline |
Retrieve value of a constant integer operand.
out | pointer to the output buffer |
is_signed | should treat the value as signed |
|
inline |
|
inline |
|
inline |
|
inline |
Retrieve the referenced stack variable.
[out] | udm | stkvar, may be nullptr |
p_idaoff | if specified, will hold IDA stkoff after the call. |
Get the referenced stack offset.
This function can also handle mop_sc if it is entirely mapped into a continuous stack region.
p_vdoff | the output buffer |
Get subinstruction of the operand.
If the operand has a subinstruction with the specified opcode, return it.
code | desired opcode |
|
inline |
Make the low part of the operand.
This function takes into account the memory endianness (byte sex)
width | the desired size of the operand part in bytes |
|
inline |
Make the high part of the operand.
This function takes into account the memory endianness (byte sex)
width | the desired size of the operand part in bytes |
|
inline |
Make the first part of the operand.
This function does not care about the memory endianness
width | the desired size of the operand part in bytes |
|
inline |
Make the second part of the operand.
This function does not care about the memory endianness
width | the desired size of the operand part in bytes |
|
inline |
Shift the operand.
This function shifts only the beginning of the operand. The operand size will be changed. Examples: shift_mop(AH.1, -1) -> AX.2 shift_mop(qword_00000008.8, 4) -> dword_0000000C.4 shift_mop(xdu.8(op.4), 4) -> #0.4 shift_mop(#0x12345678.4, 3) -> #12.1
offset | shift count (the number of bytes to shift) |
|
inline |
Change the operand size.
Examples: change_size(AL.1, 2) -> AX.2 change_size(qword_00000008.8, 4) -> dword_00000008.4 change_size(xdu.8(op.4), 4) -> op.4 change_size(#0x12345678.4, 1) -> #0x78.1
nsize | new operand size |
sideff | may modify the database because of the size change? |
|
inline |
|
inline |
Move subinstructions with side effects out of the operand.
If we decide to delete an instruction operand, it is a good idea to call this function. Alternatively we should skip such operands by calling mop_t::has_side_effects() For example, if we transform: jnz x, x, @blk => goto @blk then we must call this function before deleting the X operands.
blk | current block |
top | top level instruction that contains our operand |
moved_calls | pointer to the boolean that will track if all side effects get handled correctly. must be false initially. |
Apply a unary opcode to the operand.
mcode | opcode to apply. it must accept 'l' and 'd' operands but not 'r'. examples: m_low/m_high/m_xds/m_xdu |
ea | value of minsn_t::ea for the newly created insruction |
newsize | new operand size Example: apply_ld_mcode(m_low) will convert op => low(op) |
mopt_t mop_t::t |
Operand type.
uint8 mop_t::oprops |
Operand properties.
uint16 mop_t::valnum |
Value number.
Zero means unknown. Operands with the same value number are equal.
int mop_t::size |
Operand size.
Usually it is 1,2,4,8 or NOSIZE but for UDTs other sizes are permitted
mreg_t mop_t::r |
mnumber_t* mop_t::nnn |
minsn_t* mop_t::d |
stkvar_ref_t* mop_t::s |
ea_t mop_t::g |
int mop_t::b |
mcallinfo_t* mop_t::f |
lvar_ref_t* mop_t::l |
mop_addr_t* mop_t::a |
char* mop_t::helper |
char* mop_t::cstr |
mcases_t* mop_t::c |
fnumber_t* mop_t::fpc |
mop_pair_t* mop_t::pair |
scif_t* mop_t::scif |
union { ... } mop_t |
The following union holds additional details about the operand.
Depending on the operand type different kinds of info are stored. You should access these fields only after verifying the operand type. All pointers are owned by the operand and are freed by its destructor.