52struct reg_value_def_t;
53#define DECLARE_REG_VALUE_DEF_HELPERS(decl)\
54decl void ida_export reg_value_def_dstr(const reg_value_def_t *_this, qstring *vout, int how, const procmod_t *pm);
65 ea_t def_ea = BADADDR;
69#define DEF_BIT static constexpr uint16
70 DEF_BIT SHORT_INSN = 0x0001;
71 DEF_BIT PC_BASED = 0x0010;
73 DEF_BIT LIKE_GOT = 0x0020;
76 static bool is_short_insn(
const insn_t &insn)
78 return insn.Op2.type ==
o_imm && insn.Op3.type ==
o_void;
83 : val(_val), def_ea(ea), flags(_flags) {}
84 reg_value_def_t(
uint64 _val,
const insn_t &insn,
uint16 _flags = 0)
87 def_itype(insn.itype),
88 flags(_flags | (is_short_insn(insn) ? SHORT_INSN : 0)) {}
90 bool is_short_insn()
const {
return (flags & SHORT_INSN) != 0; }
91 bool is_pc_based()
const {
return (flags & PC_BASED) != 0; }
92 bool is_like_got()
const {
return (flags & LIKE_GOT) != 0; }
94 bool operator==(
const reg_value_def_t &r)
const
96 return def_ea == r.def_ea && val == r.val;
98 bool operator<(
const reg_value_def_t &r)
const
100 if ( def_ea < r.def_ea )
102 if ( def_ea > r.def_ea )
119 reg_value_def_dstr(
this, &out, how, pm);
131struct reg_value_base_t;
132#define DECLARE_REG_VALUE_BASE_HELPERS(decl)\
133decl int ida_export reg_value_base_vals_union(reg_value_base_t *_this, const reg_value_base_t *r);\
134decl void ida_export reg_value_base_dstr(const reg_value_base_t *_this, qstring *vout, const procmod_t *pm);
140struct reg_value_base_t
143 using val_def_t = reg_value_def_t;
144 friend struct reg_finder_block_t;
146 friend struct reg_value_info93_t;
191 state_t state = UNDEF;
193 explicit reg_value_base_t(
200 vals.
push_back(val_def_t(_val, def_ea, val_flags));
202 explicit reg_value_base_t(
209 vals.
push_back(val_def_t(_val, insn, val_flags));
213 reg_value_base_t() {}
221 bool empty()
const {
return state == UNDEF; }
223 void swap(reg_value_base_t &r)
noexcept
225 std::swap(state, r.state);
231 static reg_value_base_t make_dead_end(
ea_t dead_end_ea)
233 return reg_value_base_t(DEADEND, dead_end_ea);
238 static reg_value_base_t make_aborted(
240 int aborting_depth = -1)
242 return reg_value_base_t(ABORTED, bblk_ea,
uint32(aborting_depth));
247 static reg_value_base_t make_badinsn(
ea_t insn_ea)
249 return reg_value_base_t(BADINSN, insn_ea);
254 static reg_value_base_t make_unkinsn(
const insn_t &insn)
256 return reg_value_base_t(UNKINSN, insn);
261 static reg_value_base_t make_unkfunc(
ea_t func_ea)
263 return reg_value_base_t(UNKFUNC, func_ea);
268 static reg_value_base_t make_unkloop(
ea_t bblk_ea)
270 return reg_value_base_t(UNKLOOP, bblk_ea);
275 static reg_value_base_t make_unkmult(
ea_t bblk_ea)
277 return reg_value_base_t(UNKMULT, bblk_ea);
282 static reg_value_base_t make_unkxref(
ea_t bblk_ea)
284 return reg_value_base_t(UNKXREF, bblk_ea);
289 static reg_value_base_t make_unkvals(
ea_t bblk_ea)
291 return reg_value_base_t(UNKVALS, bblk_ea);
301 return reg_value_base_t(NUMINSN, insn, rval, val_flags);
310 return reg_value_base_t(NUMADDR, val_ea, rval, val_flags);
315 static reg_value_base_t make_initial_sp(
ea_t func_ea)
317 return reg_value_base_t(SPDADDR, func_ea, 0);
324 bool is_dead_end()
const {
return state == DEADEND; }
326 bool aborted()
const {
return state == ABORTED; }
328 bool is_special()
const {
return is_dead_end() || aborted(); }
331 bool is_badinsn()
const {
return state == BADINSN; }
333 bool is_unkinsn()
const {
return state == UNKINSN; }
335 bool is_unkfunc()
const {
return state == UNKFUNC; }
337 bool is_unkloop()
const {
return state == UNKLOOP; }
340 bool is_unkmult()
const {
return state == UNKMULT; }
342 bool is_unkxref()
const {
return state == UNKXREF; }
345 bool is_unkvals()
const {
return state == UNKVALS; }
349 return state == BADINSN
359 bool is_num()
const {
return state == NUMINSN || state == NUMADDR; }
361 bool is_spd()
const {
return state == SPDINSN || state == SPDADDR; }
363 bool is_known()
const {
return is_num() || is_spd(); }
366 ea_t get_def_ea()
const
368 return vals.
size() != 1 ? BADADDR : vals.
begin()->def_ea;
371 uint16 get_def_itype()
const
373 return vals.
size() != 1 ? 0 : vals.
begin()->def_itype;
376 int get_aborting_depth()
const
378 if ( !aborted() || vals.
size() != 1 )
386 bool set_def_itype_for_mov(
const insn_t &insn)
388 if ( vals.
size() != 1
389 || vals.
begin()->def_ea != insn.ea
390 || vals.
begin()->def_itype != 0 )
394 if ( state == NUMADDR )
396 else if ( state == SPDADDR )
400 vals.
begin()->def_itype = insn.itype;
405 const reg_value_def_t *vals_begin()
const {
return vals.
begin(); }
407 const reg_value_def_t *vals_end()
const {
return vals.
end(); }
409 size_t vals_size()
const {
return vals.
size(); }
412 bool is_value_unique()
const
416 if ( vals.
size() == 1 )
418 auto p = vals.
begin();
420 for ( ++p; p != vals.
end(); ++p )
427 bool have_all_vals_flag(
uint16 val_flags)
const
429 for (
auto p : vals )
430 if ( (p.flags & val_flags) == 0 )
434 bool has_any_vals_flag(
uint16 val_flags)
const
436 for (
auto p : vals )
437 if ( (p.flags & val_flags) != 0 )
441 bool is_all_vals_pc_based()
const
443 return have_all_vals_flag(val_def_t::PC_BASED);
445 bool is_any_vals_pc_based()
const
447 return has_any_vals_flag(val_def_t::PC_BASED);
449 bool is_all_vals_like_got()
const
451 return have_all_vals_flag(val_def_t::LIKE_GOT);
453 bool is_any_vals_like_got()
const
455 return has_any_vals_flag(val_def_t::LIKE_GOT);
459 void set_all_vals_flag(
uint16 val_flags)
461 for (
auto &p : vals )
462 p.flags |= val_flags;
464 void set_all_vals_pc_based()
466 return set_all_vals_flag(val_def_t::PC_BASED);
468 void set_all_vals_got_based()
470 return set_all_vals_flag(val_def_t::LIKE_GOT);
478 void set_dead_end(
ea_t dead_end_ea)
482 vals.
push_back(val_def_t(BADADDR, dead_end_ea));
487 void set_badinsn(
ea_t insn_ea)
491 vals.
push_back(val_def_t(BADADDR, insn_ea));
496 void set_unkinsn(
const insn_t &insn)
500 vals.
push_back(val_def_t(BADADDR, insn));
505 void set_unkfunc(
ea_t func_ea)
509 vals.
push_back(val_def_t(BADADDR, func_ea));
514 void set_unkloop(
ea_t bblk_ea)
518 vals.
push_back(val_def_t(BADADDR, bblk_ea));
523 void set_unkmult(
ea_t bblk_ea)
527 vals.
push_back(val_def_t(BADADDR, bblk_ea));
532 void set_unkxref(
ea_t bblk_ea)
536 vals.
push_back(val_def_t(BADADDR, bblk_ea));
541 void set_unkvals(
ea_t bblk_ea)
545 vals.
push_back(val_def_t(BADADDR, bblk_ea));
550 void set_aborted(
ea_t bblk_ea,
int aborting_depth = -1)
559 void set_num(
uint64 rval,
const insn_t &insn,
uint16 val_flags = 0)
563 vals.
push_back(val_def_t(rval, insn, val_flags));
568 void set_num(
uvalvec_t *rvals,
const insn_t &insn)
570 set_multivals(rvals, insn);
579 vals.
push_back(val_def_t(rval, val_ea, val_flags));
583 enum set_compare_res_t
596 set_compare_res_t vals_union(
const reg_value_base_t &r)
598 return set_compare_res_t(reg_value_base_vals_union(
this, &r));
605 OR, AND, XOR, AND_NOT,
613 inline void add(
const reg_value_base_t &r,
const insn_t &insn);
616 inline void sub(
const reg_value_base_t &r,
const insn_t &insn);
619 inline void bor(
const reg_value_base_t &r,
const insn_t &insn);
622 inline void band(
const reg_value_base_t &r,
const insn_t &insn);
625 inline void bxor(
const reg_value_base_t &r,
const insn_t &insn);
628 inline void bandnot(
const reg_value_base_t &r,
const insn_t &insn);
631 inline void sll(
const reg_value_base_t &r,
const insn_t &insn);
634 inline void slr(
const reg_value_base_t &r,
const insn_t &insn);
637 inline void sar(
const reg_value_base_t &r,
const insn_t &insn);
641 inline void movt(
const reg_value_base_t &r,
const insn_t &insn);
643 inline void neg(
const insn_t &insn);
645 inline void bnot(
const insn_t &insn);
648 inline void add_num(
uint64 r,
const insn_t &insn);
653 inline void add_num(
uint64 r);
656 inline void shift_left(
uint64 r);
665 inline void extend(
int width,
bool is_signed);
671 reg_value_base_dstr(
this, &out, pm);
679 inline bool get_num(
uint64 *uval,
int slotsize)
const;
681 inline bool get_addr(
ea_t *addr,
int addrsize)
const;
688 inline void truncate(
int width,
int slotsize,
int addrsize);
694 set_compare_res_t vals_union_impl(
const reg_value_base_t &r);
701 inline bool perform_binary_op(
702 const reg_value_base_t &r,
707 inline void perform_binary_op_for_nums(
708 const reg_value_base_t &r,
713 inline void set_multivals(V *rvals,
const insn_t &insn);
715 inline void sort_multivals();
720 if ( !is_num() || !is_value_unique() )
723 return is_pow2(mask + 1) && mask <= 0x1F;
741 const reg_value_base_t &base,
744 : reg_value_base_t(base),
748 reg_value_base_t &&base,
751 : reg_value_base_t(base),
769 return reg_value_base_t::get_num(uval,
slotsize);
776 return reg_value_base_t::get_addr(addr,
addrsize);
786 return reg_value_base_t::get_spd(sval,
addrsize);
809 for (
auto &p : vals )
810 p.val = pm.trunc_uval(p.val);
817struct reg_finder_op_t
828 static constexpr uint32 REG = 0;
829 static constexpr uint32 STKVAR = 1 << 31;
830 static constexpr int WIDTH_SHIFT = 29;
831 static constexpr uint32 WIDTH_MASK = 0x3 << WIDTH_SHIFT;
832 static constexpr uint32 SIGNED = 1 << 28;
833 static constexpr int STKOFF_SIGNBIT = 1 << 27;
834 static constexpr uint32 STKOFF_MASK = STKOFF_SIGNBIT - 1;
836 static constexpr uint32 BADREG = 0x10000;
850 bool empty()
const {
return packed == BADREG; }
855 return reg >= 0 && reg < BADREG;
861 return stkoff >= -
sval_t(STKOFF_MASK) && stkoff <=
sval_t(STKOFF_MASK);
870 bool is_reg()
const {
return (packed & STKVAR) == 0; }
871 bool is_stkvar()
const {
return (packed & STKVAR) != 0; }
872 bool is_signed()
const {
return (packed & SIGNED) != 0; }
875 return 1 << ((packed & WIDTH_MASK) >> WIDTH_SHIFT);
881 sval_t stkoff = packed & STKOFF_MASK;
882 return (packed & STKOFF_SIGNBIT) == 0 ? stkoff : -stkoff;
891 return r.empty() ? 0 : -1;
894 return ::compare(packed, r.packed);
902struct reg_value_ud_chain_t;
904 reg_value_base_t *v1,
905 reg_value_base_t *v2,
909#define DECLARE_REG_FINDER_HELPERS(decl)\
910decl void ida_export reg_finder_invalidate_cache(reg_finder_t *_this, ea_t to, ea_t from, cref_t cref);\
911decl void ida_export reg_finder_invalidate_xrefs_cache(reg_finder_t *_this, ea_t ea, dref_t dref);\
912decl void ida_export reg_finder_find(reg_finder_t *_this, reg_value_base_t *out, ea_t ea, ea_t ds, reg_finder_op_t op, int max_depth, size_t linear_insns);\
913decl void ida_export reg_finder94_make_rfop(reg_finder_t *_this, reg_finder_op_t *rfop, const op_t *op, const insn_t *insn, ea_t func_ea);\
914decl bool ida_export reg_finder_calc_op_addr(reg_finder_t *_this, reg_value_base_t *addr, const op_t *memop, const insn_t *insn, ea_t ea, ea_t ds, int max_depth);\
915decl bool ida_export reg_finder_emulate_mem_read(reg_finder_t *_this, reg_value_base_t *value, const reg_value_base_t *addr, int width, bool is_signed, const insn_t *insn);\
916decl void ida_export reg_finder_emulate_binary_op(reg_finder_t *_this, reg_value_base_t *value, int aop, const op_t *op1, const op_t *op2, const insn_t *insn, ea_t ea, ea_t ds, reg_finder_binary_ops_adjust_fun adjust, void *ud);\
917decl void ida_export reg_finder_emulate_unary_op(reg_finder_t *_this, reg_value_base_t *value, int aop, int reg, const insn_t *insn, ea_t ea, ea_t ds);\
918decl void ida_export reg_finder_emulate_binary_op_shifted(reg_finder_t *_this, reg_value_base_t *value, int aop, const op_t *op1, const op_t *op2, int width, bool is_signed, int shift, uint8 shift_count, const insn_t *insn, ea_t ea, ea_t ds);\
919decl bool ida_export reg_finder_may_modify_stkvar(reg_finder_t *_this, reg_value_base_t *value, reg_finder_op_t op, const insn_t *insn);\
920decl bool ida_export reg_finder_can_resolve_mem(const reg_finder_t *_this, ea_t ea);\
921decl void ida_export reg_finder_ctr(reg_finder_t *_this);\
922decl void ida_export reg_finder_dtr(reg_finder_t *_this);
928struct reg_finder_block_t;
929struct reg_finder_pred_t;
1008 static constexpr uint32 COND_MASK = 0x0F;
1009 static constexpr int KIND_SHIFT = 4;
1010 static constexpr uint32 KIND_MASK = 0xF;
1042 : packed((cond & COND_MASK) | ((kind & KIND_MASK) << KIND_SHIFT)) {}
1054 return cnd == rcnd || rcnd ==
AL;
1059 return uchar((packed >> KIND_SHIFT) & KIND_MASK);
1066 using udc_t = reg_value_ud_chain_t;
1076 DECLARE_COMPARISONS(addr_t)
1080 code = rfop.compare(r.rfop);
1092 : chain_num(_chain_num), delta(_delta) {}
1095 bool operator==(
const vref_t &r)
1097 return chain_num == r.chain_num && delta == r.delta;
1116 bool in_invalidate =
false;
1117 bool debug_on =
true;
1126 int _proc_maxop = 3,
1134 reg_finder_ctr(
this);
1145 if ( _slotsize == 0 )
1146 _slotsize = _addrsize;
1147 else if ( _slotsize != 4 && _slotsize != 8 || _slotsize < _addrsize )
1159 reg_finder_invalidate_cache(
this, to, from, cref);
1164 reg_finder_invalidate_cache(
this, BADADDR, BADADDR,
fl_U);
1171 reg_finder_invalidate_xrefs_cache(
this, ea, dref);
1193 size_t linear_insns = 0)
1197 reg_finder_find(
this, &ret,
1198 flow.
ea, flow.
ds, rfop,
1199 max_depth, linear_insns);
1208 size_t linear_insns = 10)
1210 if ( reg[0] == reg[1] )
1213 if ( rvi->is_known() )
1216 if ( rvi->is_known() )
1219 if ( rvi->is_known() )
1222 if ( rvi->is_known() )
1263 reg_finder94_make_rfop(
this, &res, &op, &insn, func_ea);
1285 reg_finder_calc_op_addr(
this, &ret,
1287 &insn, flow.
ea, flow.
ds, max_depth);
1308 reg_finder_emulate_mem_read(
this, value, &addr,
1316 return reg_finder_can_resolve_mem(
this, ea);
1377 bool is_func_start)
const
1381 qnotused(is_func_start);
1410 return can_track_op(op, insn, pfn !=
nullptr ? pfn->start_ea : BADADDR);
1447 qnotused(move_desc);
1475 value->set_unkinsn(insn);
1498 reg_finder_find(
this, &ret, flow.
ea, flow.
ds, rfop, 0, 0);
1509 reg_finder_find(
this, &ret, flow.
ea, flow.
ds, rfop, 0, 0);
1521 reg_finder_calc_op_addr(
this, addr,
1523 &insn, flow.
ea, flow.
ds, 0);
1532 rvb_t::arith_op_t aop,
1540 reg_finder_emulate_binary_op(
this, value,
1542 &insn, flow.
ea, flow.
ds,
1549 rvb_t::arith_op_t aop,
1554 reg_finder_emulate_unary_op(
this, value,
1556 &insn, flow.
ea, flow.
ds);
1562 rvb_t::arith_op_t aop,
1567 rvb_t::arith_op_t shift,
1572 reg_finder_emulate_binary_op_shifted(
this, value,
1576 &insn, flow.
ea, flow.
ds);
1585 return reg_finder_may_modify_stkvar(
this, value, rfop, &insn);
1590 rvb_t find_chain(
const flow_t flow,
const rfop_t rfop);
1591 void create_initial_block(
const flow_t flow,
const rfop_t rfop);
1593 bool create_new_block(vref_t *res_vref,
const pred_t &pred);
1594 bool handle_block_pred(
size_t chain_num, vref_t pred_vref);
1595 vref_t finalize_block();
1598 bool collect_predecessors(
qvector<flow_t> *pred_addrs, flow_t flow)
const;
1599 bool analyze_linear_flow(
1602 ea_t initial_ea)
const;
1603 bool merge_loop_blocks(
const block_t *loop_block,
sval_t delta);
1604 bool decode_and_emulate_insn(
1615 rvb_t make_aborted();
1616 bool set_aborted_or_unkinsn(
rvb_t *value,
const insn_t &insn);
1619 enum handle_move_res_t
1634 handle_move_res_t handle_move(
1637 const insn_t &insn);
1642 enum overlap_res_t { SAME, OVERLAPS, DIFFERENT };
1643 overlap_res_t does_rfop_overlap_with_op(
1646 const insn_t &insn);
1650 bool calc_stkvar_off(
1657 reg_value_ud_chain_t &get_chain(
size_t chain_num);
1658 const reg_value_ud_chain_t &get_chain(
size_t chain_num)
const;
1659 void erase_block(
size_t chain_num);
1662 size_t from_chain_num,
1663 size_t to_chain_num,
1665 void adjust_deltas(
const qvector<addr_t> &addrs,
sval_t delta);
1666 void trim_cache(
ea_t ea,
int max_cache_size);
1668 bool is_rfop_changed(
1673 DECLARE_REG_FINDER_HELPERS(
friend)
1677 void invalidate_xrefs_cache_impl(
ea_t ea,
dref_t dref);
1681 rvb_t find_impl(
flow_t flow,
int reg,
int max_depth = 0)
1685 rfop_t make_rfop_impl(
const op_t &op,
const insn_t &insn,
ea_t func_ea);
1686 bool calc_op_addr_impl(
1692 bool emulate_mem_read_impl(
1697 const insn_t &insn);
1698 void emulate_binary_op_impl(
1700 rvb_t::arith_op_t aop,
1706 void *ud =
nullptr);
1707 void emulate_unary_op_impl(
1709 rvb_t::arith_op_t aop,
1713 void emulate_binary_op_shifted_impl(
1715 rvb_t::arith_op_t aop,
1720 rvb_t::arith_op_t shift,
1724 bool may_modify_stkvar_impl(
1727 const insn_t &insn);
1728 bool can_resolve_mem_impl(
ea_t ea)
const;
1788#ifndef IDA_REGFINDER_LEGACY_COMPAT
1820 const char *regname,
1832#ifndef IDA_REGFINDER_LEGACY_COMPAT
1849 ea_t from = BADADDR,
1863inline bool reg_value_base_t::perform_binary_op(
1864 const reg_value_base_t &r,
1868 const reg_value_base_t *mv;
1870 if ( r.is_value_unique() )
1873 sv = r.vals.begin()->val;
1875 else if ( is_value_unique() )
1878 sv = vals.begin()->val;
1884 qvector<uint64> rvals;
1885 rvals.
reserve(mv->vals.size());
1886 for (
const auto &p : mv->vals )
1891 case ADD: res = p.val + sv;
break;
1892 case SUB: res = p.val - sv;
break;
1893 case OR: res = p.val | sv;
break;
1894 case AND: res = p.val & sv;
break;
1895 case XOR: res = p.val ^ sv;
break;
1896 case AND_NOT: res = p.val & ~sv;
break;
1897 case MOVT: res = (p.val & 0xFFFF) | ((sv & 0xFFFF) << 16);
break;
1898 case SLL: res = p.val << sv;
break;
1899 case SLR: res = p.val >> sv;
break;
1900 case SAR: res =
int64(p.val) >> sv;
break;
1901 default:
return false;
1905 set_multivals(&rvals, insn);
1910inline void reg_value_base_t::perform_binary_op_for_nums(
1911 const reg_value_base_t &r,
1915 if ( is_num() && r.is_num() )
1917 if ( perform_binary_op(r, aop, insn) )
1928inline void reg_value_base_t::add(
1929 const reg_value_base_t &r,
1932 if ( is_spd() && r.is_num()
1933 || is_num() && r.is_spd()
1934 || is_num() && r.is_num() )
1936 if ( perform_binary_op(r, ADD, insn) )
1938 state = is_spd() || r.is_spd() ? SPDINSN : NUMINSN;
1947inline void reg_value_base_t::sub(
1948 const reg_value_base_t &r,
1951 if ( is_spd() && r.is_num()
1952 || is_spd() && r.is_spd()
1953 || is_num() && r.is_num() )
1955 if ( perform_binary_op(r, SUB, insn) )
1957 state = is_spd() && r.is_num() ? SPDINSN : NUMINSN;
1966inline void reg_value_base_t::bor(
1967 const reg_value_base_t &r,
1970 return perform_binary_op_for_nums(r, OR, insn);
1974inline void reg_value_base_t::band(
1975 const reg_value_base_t &r,
1978 if ( (is_spd() && r.is_mask()) || (is_num() && r.is_num()) )
1980 if ( perform_binary_op(r, AND, insn) )
1991inline void reg_value_base_t::bxor(
1992 const reg_value_base_t &r,
1995 return perform_binary_op_for_nums(r, XOR, insn);
1999inline void reg_value_base_t::bandnot(
2000 const reg_value_base_t &r,
2003 if ( (is_spd() && r.is_mask()) || (is_num() && r.is_num()) )
2005 if ( perform_binary_op(r, AND_NOT, insn) )
2007 state = is_spd() ? SPDINSN : NUMINSN;
2016inline void reg_value_base_t::sll(
2017 const reg_value_base_t &r,
2020 return perform_binary_op_for_nums(r, SLL, insn);
2024inline void reg_value_base_t::slr(
2025 const reg_value_base_t &r,
2028 return perform_binary_op_for_nums(r, SLR, insn);
2032inline void reg_value_base_t::sar(
2033 const reg_value_base_t &r,
2036 return perform_binary_op_for_nums(r, SAR, insn);
2040inline void reg_value_base_t::movt(
2041 const reg_value_base_t &r,
2044 return perform_binary_op_for_nums(r, MOVT, insn);
2048inline void reg_value_base_t::neg(
const insn_t &insn)
2052 qvector<uint64> rvals;
2054 for (
auto &p : vals )
2056 set_multivals(&rvals, insn);
2066inline void reg_value_base_t::bnot(
const insn_t &insn)
2070 qvector<uint64> rvals;
2072 for (
auto &p : vals )
2074 set_multivals(&rvals, insn);
2084inline void reg_value_base_t::add_num(
uint64 r,
const insn_t &insn)
2086 if ( !is_known() || r == 0 )
2088 qvector<uint64> rvals;
2090 for (
auto &p : vals )
2092 set_multivals(&rvals, insn);
2093 state = is_spd() ? SPDINSN : NUMINSN;
2097inline void reg_value_base_t::add_num(
uint64 r)
2099 if ( !is_known() || r == 0 )
2101 for (
auto &p : vals )
2107inline void reg_value_base_t::shift_left(
uint64 r)
2109 if ( !is_known() || r == 0 )
2111 for (
auto &p : vals )
2117inline void reg_value_base_t::shift_right(
uint64 r,
int nbytes)
2119 if ( !is_known() || r == 0 )
2121 for (
auto &p : vals )
2138inline void reg_value_base_t::set_multivals(
2143 std::sort(rvals->begin(), rvals->end());
2144 size_t newsz = std::unique(rvals->begin(), rvals->end()) - rvals->begin();
2146 for (
size_t i = 0; i < newsz; ++i )
2147 vals[i] = val_def_t(rvals->at(i), insn);
2151inline void reg_value_base_t::sort_multivals()
2154 std::sort(vals.begin(), vals.end());
2156 size_t new_size = std::unique(vals.begin(), vals.end()) - vals.begin();
2157 vals.resize(new_size);
2161inline bool reg_value_base_t::get_num(
uint64 *uval,
int slotsize)
const
2163 if ( slotsize == 0 || !is_num() || !is_value_unique() )
2165 *uval =
extend_sign(vals.begin()->val, slotsize,
false);
2170inline bool reg_value_base_t::get_addr(
ea_t *addr,
int addrsize)
const
2172 if ( addrsize == 0 || !is_num() || !is_value_unique() )
2174 *addr =
extend_sign(vals.begin()->val, addrsize,
false);
2179inline bool reg_value_base_t::get_spd(
sval_t *sval,
int addrsize)
const
2181 if ( addrsize == 0 || !is_spd() || !is_value_unique() )
2183 *sval =
extend_sign(vals.begin()->val, addrsize,
true);
2188inline void reg_value_base_t::extend(
int width,
bool is_signed)
2192 for (
auto &p : vals )
2198inline void reg_value_base_t::truncate(
2205 bool is_signed = is_spd();
2208 width = is_spd() ? addrsize : slotsize;
2212 for (
auto &p : vals )
2241 bool negative = stkoff < 0;
2244 | (negative ? STKOFF_SIGNBIT : 0)
2245 |
uint32(negative ? -stkoff : stkoff));
2252 if ( packed_width == BADREG )
2257 packed &= ~WIDTH_MASK;
2258 packed |= packed_width;
2273 if ( packed_width == BADREG )
2278 packed &= ~WIDTH_MASK;
2279 packed |= packed_width;
2290 case 1:
return 0 << WIDTH_SHIFT;
break;
2291 case 2:
return 1 << WIDTH_SHIFT;
break;
2292 case 4:
return 2 << WIDTH_SHIFT;
break;
2293 case 8:
return 3 << WIDTH_SHIFT;
break;
2294 default:
return BADREG;
Operand of an instruction.
Definition ua.hpp:170
op_dtype_t dtype
Type of operand value (see Operand value types).
Definition ua.hpp:225
Reimplementation of vector class from STL.
Definition pro.h:2262
void reserve(size_t cnt)
Increase the capacity of the qvector.
Definition pro.h:2605
void swap(qvector< T > &r) noexcept
Replace all attributes of this qvector with that of 'r', and vice versa.
Definition pro.h:2634
void qclear(void)
Destroy all elements but do not free memory.
Definition pro.h:2505
iterator end(void)
Get an iterator that points to the end of the qvector (NOT the last element)
Definition pro.h:2684
iterator begin(void)
Get an iterator that points to the first element in the qvector.
Definition pro.h:2683
void push_back(T &&x)
Append a new element to the end the qvector with a move semantics.
Definition pro.h:2432
size_t size(void) const
Get the number of elements in the qvector.
Definition pro.h:2494
idaman DEPRECATED sval_t ida_export get_spd(func_t *pfn, ea_t ea)
Get difference between the initial and current values of ESP.
THREAD_SAFE constexpr bool idaapi is_unknown(flags64_t F)
Does flag denote unexplored byte?
Definition bytes.hpp:786
bool function_contains(ea_t func_ea, ea_t ea)
Does the function at func_ea contain ea?
Definition funcs.hpp:1121
bool is_same_func(ea_t ea1, ea_t ea2)
Do two addresses belong to the same function?
Definition funcs.hpp:1128
idaman bool ida_export get_fchunk_info(fchunk_info_t *out, ea_t ea)
Get the range of the function chunk (entry or tail) containing 'ea'.
const optype_t o_imm
An immediate Value (constant).
Definition ua.hpp:92
const optype_t o_void
No Operand.
Definition ua.hpp:82
int code
Definition fpro.h:88
const char *hexapi dstr(const tinfo_t *tif)
Print the specified type info.
Definition hexrays.hpp:11173
cref_t
CODE xref types.
Definition xref.hpp:49
dref_t
DATA xref types.
Definition xref.hpp:67
@ fl_U
unknown – for compatibility with old versions.
Definition xref.hpp:50
@ dr_O
Offset The reference uses 'offset' of data rather than its value OR The reference appeared because th...
Definition xref.hpp:70
cexpr_t *hexapi make_num(uint64 n, cfunc_t *func=nullptr, ea_t ea=BADADDR, int opnum=0, type_sign_t sign=no_sign, int size=0)
Create a number expression.
Definition hexrays.hpp:13470
int inf_get_effective_addrsize()
Definition ida.hpp:686
Contains definition of the interface to IDP modules.
int nbytes
Definition kernwin.hpp:3037
void(idaapi *range_marker)(ea_t ea
Pointer to range marker function (for idaviews and hexviews) This pointer is initialized by setup_ran...
unsigned __int64 uint64
Definition llong.hpp:13
__int64 int64
Definition llong.hpp:14
This is the first header included in the IDA project.
unsigned short uint16
unsigned 16 bit value
Definition pro.h:350
unsigned int uint32
unsigned 32 bit value
Definition pro.h:352
qvector< uval_t > uvalvec_t
vector of unsigned values
Definition pro.h:2836
adiff_t sval_t
signed value used by the processor.
Definition pro.h:450
uint64 ea_t
Definition pro.h:425
int int32
signed 32 bit value
Definition pro.h:351
unsigned char uchar
unsigned 8 bit value
Definition pro.h:341
THREAD_SAFE void qswap(T &a, T &b)
Swap 2 objects of the same type using memory copies.
Definition pro.h:1728
qvector< ea_t > eavec_t
vector of addresses
Definition pro.h:2838
idaman uint64 ida_export extend_sign(uint64 v, int nbytes, bool sign_extend)
Sign or zero-extend the value 'v' to occupy 64 bits.
unsigned char uint8
unsigned 8 bit value
Definition pro.h:348
constexpr bool is_pow2(T val)
is power of 2? (or zero)
Definition pro.h:1435
_qstring< char > qstring
regular string
Definition pro.h:3771
int compare(const T &a, const T &b)
Definition pro.h:4607
unsigned int
Definition pronet.h:99
constexpr bool operator<(qpair< F, S > const &a, qpair< F, S > const &b)
Definition qpair.hpp:108
void swap(qpair< F, S > &a, qpair< F, S > &b) noexcept(noexcept(a.swap(b)))
Definition qpair.hpp:78
constexpr bool operator==(qpair< F, S > const &a, qpair< F, S > const &b)
Definition qpair.hpp:98
idaman void ida_export invalidate_regfinder_cache(ea_t to=BADADDR, ea_t from=BADADDR, cref_t cref=fl_U)
The control flow from FROM to TO has removed (CREF==fl_U) or added (CREF!=fl_U).
idaman int ida_export reg_finder94_find_nearest_rvi(reg_value_info_t *rvi, ea_t ea, const int reg[2])
idaman int ida_export find_sp_value(sval_t *sval, ea_t ea, int reg=-1)
Find a value of the SP based register using the register tracker.
DECLARE_REG_VALUE_DEF_HELPERS(idaman) struct reg_value_def_t
the register value and its defining instruction
Definition regfinder.hpp:56
idaman bool ida_export find_regname_value_info(reg_value_info_t *rvi, ea_t ea, const char *regname, int max_depth=0)
Find register value using the register tracker.
idaman bool ida_export reg_finder94_find_reg_value_info(reg_value_info_t *out, ea_t ea, int reg, int max_depth)
DECLARE_TYPE_AS_MOVABLE(reg_value_def_t)
void(* reg_finder_binary_ops_adjust_fun)(reg_value_base_t *v1, reg_value_base_t *v2, const insn_t &insn, void *ud)
Definition regfinder.hpp:903
idaman int ida_export find_reg_value(uint64 *uval, ea_t ea, int reg)
Find register value using the register tracker.
idaman void ida_export invalidate_regfinder_xrefs_cache(ea_t to=BADADDR, dref_t dref=dr_O)
The data reference to TO has added (DREF!=dr_O) or removed (DREF==dr_O).
DECLARE_REG_FINDER_HELPERS(idaman) struct reg_finder_block_t
DECLARE_REG_VALUE_BASE_HELPERS(idaman) struct reg_value_base_t
the value in a register after emulating instructions (base class)
Definition regfinder.hpp:136
bool ida_export find_reg_value_info(reg_value_info_t *rvi, ea_t ea, int reg, int max_depth=0)
Find register value using the register tracker.
Definition regfinder.hpp:1789
int ida_export find_nearest_rvi(reg_value_info_t *rvi, ea_t ea, const int reg[2])
Find the value of any of the two registers using the register tracker.
Definition regfinder.hpp:1833
Base class for an range.
Definition range.hpp:35
Definition regfinder.hpp:818
void set_width_signness(int width, bool is_signed)
Definition regfinder.hpp:2270
rfop_t & operator=(const rfop_t &r)=default
bool empty() const
Definition regfinder.hpp:850
void set_width(int width)
Definition regfinder.hpp:2249
static bool is_valid_reg(int reg)
Definition regfinder.hpp:853
uint16 get_reg() const
Definition regfinder.hpp:878
void set_signness(bool is_signed)
Definition regfinder.hpp:2262
reg_finder_op_t(const rfop_t &r)=default
void clear()
Definition regfinder.hpp:851
reg_finder_op_t()
Definition regfinder.hpp:844
static reg_finder_op_t make_reg(int reg, int width)
Definition regfinder.hpp:2225
static bool is_valid_stkoff(sval_t stkoff)
Definition regfinder.hpp:859
int get_width() const
Definition regfinder.hpp:873
static reg_finder_op_t make_stkoff(sval_t stkoff, int width)
Definition regfinder.hpp:2234
reg_finder_op_t rfop_t
Definition regfinder.hpp:843
static uint32 pack_width(int width)
Definition regfinder.hpp:2286
bool is_reg() const
Definition regfinder.hpp:870
sval_t get_stkoff() const
Definition regfinder.hpp:879
DECLARE_COMPARISONS(reg_finder_op_t)
Definition regfinder.hpp:887
bool is_signed() const
Definition regfinder.hpp:872
static int get_op_width(const op_t &op)
Definition regfinder.hpp:2299
bool is_stkvar() const
Definition regfinder.hpp:871
bool is_reg(int reg) const
Definition regfinder.hpp:885
Definition regfinder.hpp:1005
cond_t(uchar cond=AL, uchar kind=NONE)
Definition regfinder.hpp:1041
uchar get_kind() const
Definition regfinder.hpp:1057
@ JUMPS
Definition regfinder.hpp:1038
@ NONE
Definition regfinder.hpp:1036
@ MODIFIES_CC
Definition regfinder.hpp:1037
bool jumps() const
Definition regfinder.hpp:1062
@ LE
Definition regfinder.hpp:1029
@ VC
Definition regfinder.hpp:1023
@ NV
Definition regfinder.hpp:1031
@ AL
Definition regfinder.hpp:1030
@ CC
Definition regfinder.hpp:1019
@ HI
Definition regfinder.hpp:1024
@ EQ
Definition regfinder.hpp:1016
@ CS
Definition regfinder.hpp:1018
@ LS
Definition regfinder.hpp:1025
@ MI
Definition regfinder.hpp:1020
@ LT
Definition regfinder.hpp:1027
@ PL
Definition regfinder.hpp:1021
@ VS
Definition regfinder.hpp:1022
@ GE
Definition regfinder.hpp:1026
@ NE
Definition regfinder.hpp:1017
@ GT
Definition regfinder.hpp:1028
bool modifies_cond_codes() const
Definition regfinder.hpp:1061
uchar get_cond() const
Definition regfinder.hpp:1044
bool is_included_in(cond_t r) const
Definition regfinder.hpp:1048
Definition regfinder.hpp:1325
void handle_delay_slot()
Definition regfinder.hpp:1332
bool has_delay_slot() const
Definition regfinder.hpp:1328
bool operator<(const flow_t &r) const
Definition regfinder.hpp:1345
ea_t ds
Definition regfinder.hpp:1327
flow_t(ea_t _ea, ea_t _ds=BADADDR)
Definition regfinder.hpp:1334
ea_t ea
Definition regfinder.hpp:1326
bool is_ea_handled() const
Definition regfinder.hpp:1330
ea_t actual_ea() const
Definition regfinder.hpp:1342
Definition regfinder.hpp:1415
bool is_signed
Definition regfinder.hpp:1429
sval_t delta
Definition regfinder.hpp:1435
const op_t * src_op
Definition regfinder.hpp:1426
rfop_t new_rfop
Definition regfinder.hpp:1418
const op_t * dst_op
Definition regfinder.hpp:1424
Definition regfinder.hpp:931
bool does_call_spoil_stkvars() const
Definition regfinder.hpp:960
const procmod_t & pm
Definition regfinder.hpp:932
void calc_op_addr(rvb_t *addr, const op_t &memop, const insn_t &insn, flow_t flow)
Definition regfinder.hpp:1515
virtual cond_t get_cond(ea_t ea) const
Definition regfinder.hpp:1364
rvi_t find_op_addr(const op_t &memop, const insn_t &insn, int max_depth=0)
Definition regfinder.hpp:1278
void emulate_unary_op(rvb_t *value, rvb_t::arith_op_t aop, int reg, const insn_t &insn, flow_t flow)
Definition regfinder.hpp:1547
size_t linear_flow_cnt
Definition regfinder.hpp:985
reg_value_info_t rvi_t
Definition regfinder.hpp:970
virtual bool is_funcwide_reg(ea_t ea, int reg) const
Definition regfinder.hpp:1401
bool update_sizes(int _slotsize=0)
Definition regfinder.hpp:1142
virtual rvb_t handle_well_known_regs(flow_t flow, rfop_t rfop, bool is_func_start) const
Definition regfinder.hpp:1374
friend struct reg_finder_chainvec_t
Definition regfinder.hpp:1068
friend struct reg_finder_block_t
Definition regfinder.hpp:975
friend struct reg_finder_pred_t
Definition regfinder.hpp:976
reg_finder_block_t block_t
Definition regfinder.hpp:973
friend struct reg_finder_xrefs_cache_t
Definition regfinder.hpp:1113
reg_finder_t(const procmod_t &_pm, int _proc_maxop=3, uint32 _flags=RF_DOES_CALL_SPOIL_STKVARS)
Definition regfinder.hpp:1124
size_t bblk_cnt
Definition regfinder.hpp:992
bool may_modify_stkvar(rvb_t *value, rfop_t rfop, const insn_t &insn)
Definition regfinder.hpp:1583
virtual int get_sp_reg(ea_t ea) const
Definition regfinder.hpp:1394
int find_nearest(reg_value_info_t *rvi, ea_t ea, const int reg[2], size_t linear_insns=10)
Definition regfinder.hpp:1204
bool find_const(uint64 *val, ea_t ea, rfop_t rfop, int max_depth=0)
Definition regfinder.hpp:1229
static constexpr uint32 RF_ALLOW_XREFS_CACHE
Definition regfinder.hpp:958
ea_t aborting_ea
Definition regfinder.hpp:991
op_t fake_op1
Definition regfinder.hpp:999
bool can_resolve_mem(ea_t ea) const
Definition regfinder.hpp:1314
int addrsize
Definition regfinder.hpp:936
const int proc_maxop
Definition regfinder.hpp:933
uint32 flags
Definition regfinder.hpp:934
virtual bool is_mem_readonly(ea_t) const
Definition regfinder.hpp:1388
virtual flow_t process_delay_slot(ea_t ea, cref_t) const
Definition regfinder.hpp:1358
bool find_addr(ea_t *addr, ea_t ea, rfop_t rfop, int max_depth=0)
Definition regfinder.hpp:1236
void invalidate_cache()
Definition regfinder.hpp:1162
virtual bool emulate_insn(rvb_t *value, const rfop_t &rfop, const insn_t &insn, flow_t flow)
Definition regfinder.hpp:1467
bool only_linear_flow() const
Definition regfinder.hpp:987
size_t initial_block_idx
Definition regfinder.hpp:980
static constexpr size_t NO_CHAIN
Definition regfinder.hpp:996
friend struct reg_finder_rfop_chains_t
Definition regfinder.hpp:1104
reg_finder_op_t rfop_t
Definition regfinder.hpp:972
void invalidate_xrefs_cache(ea_t ea, dref_t dref)
Definition regfinder.hpp:1169
void emulate_mem_read(rvb_t *value, const rvb_t &addr, int width, bool is_signed, const insn_t &insn)
Definition regfinder.hpp:1301
virtual ~reg_finder_t()
Definition regfinder.hpp:1138
rfop_t make_rfop(const op_t &_op, const insn_t &insn, ea_t func_ea)
Definition regfinder.hpp:1257
bool fixed_max_depth
Definition regfinder.hpp:981
int slotsize
Definition regfinder.hpp:937
ea_t cur_func_ea
Definition regfinder.hpp:979
void emulate_binary_op_shifted(rvb_t *value, rvb_t::arith_op_t aop, const op_t &op1, const op_t &op2, int width, bool is_signed, rvb_t::arith_op_t shift, uint8 shift_count, const insn_t &insn, flow_t flow)
Definition regfinder.hpp:1560
rvb_t find(flow_t flow, int reg)
Definition regfinder.hpp:1505
static constexpr uint32 RF_DOES_CALL_SPOIL_STKVARS
Definition regfinder.hpp:953
virtual bool can_track_op(op_t *op, const insn_t &insn, ea_t func_ea) const
Definition regfinder.hpp:1482
bool allow_xrefs_cache() const
Definition regfinder.hpp:964
bool find_spd(sval_t *spval, ea_t ea, int reg=-1, int max_depth=-1)
Definition regfinder.hpp:1243
int cur_call_depth
Definition regfinder.hpp:984
void invalidate_cache(ea_t to, ea_t from, cref_t cref)
Definition regfinder.hpp:1157
int cur_max_depth
Definition regfinder.hpp:983
rvb_t standalone_value
Definition regfinder.hpp:993
rvi_t find(ea_t ea, rfop_t rfop, int max_depth=0, size_t linear_insns=0)
Definition regfinder.hpp:1189
friend struct reg_finder_debug_t
Definition regfinder.hpp:1319
virtual bool is_move_insn(move_desc_t *move_desc, const rfop_t &rfop, const insn_t &insn)
Definition regfinder.hpp:1442
rvb_t find(flow_t flow, rfop_t rfop)
Definition regfinder.hpp:1495
void emulate_binary_op(rvb_t *value, rvb_t::arith_op_t aop, const op_t &op1, const op_t &op2, const insn_t &insn, flow_t flow, reg_finder_binary_ops_adjust_fun adjust=nullptr, void *ud=nullptr)
Definition regfinder.hpp:1530
virtual bool can_track_op93(op_t *op, const insn_t &insn, range_t *pfn) const
Definition regfinder.hpp:1408
reg_value_base_t rvb_t
Definition regfinder.hpp:971
op_t fake_op2
Definition regfinder.hpp:1000
static int get_effective_addrsize()
Definition regfinder.hpp:946
reg_finder_pred_t pred_t
Definition regfinder.hpp:974
Definition regfinder.hpp:733
bool get_addr(ea_t *addr) const
Return the address if the value is a constant (truncated to ADDRSIZE).
Definition regfinder.hpp:774
reg_value_info_t(reg_value_base_t &&base, int _slotsize, int _addrsize)
Definition regfinder.hpp:747
void trunc_uval(const procmod_t &pm)
Definition regfinder.hpp:800
void set_context(int _slotsize, int _addrsize)
Set the context.
Definition regfinder.hpp:758
bool get_num(uint64 *uval) const
Return the number if the value is a constant (truncated to SLOTSIZE).
Definition regfinder.hpp:767
void truncate(int width=0)
Truncate the value to WIDTH (in bytes).
Definition regfinder.hpp:794
bool get_spd(sval_t *sval) const
Return the SP delta if the value depends on the stack pointer (sign-extended to ADDRSIZE).
Definition regfinder.hpp:784
int addrsize
Definition regfinder.hpp:736
reg_value_info_t()
Definition regfinder.hpp:739
reg_value_info_t(const reg_value_base_t &base, int _slotsize, int _addrsize)
Definition regfinder.hpp:740
int slotsize
Definition regfinder.hpp:735
Functions that deal with the disassembling of program instructions.
idaman size_t ida_export get_dtype_size(op_dtype_t dtype)
Get size of opt_::dtype field.