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_info_t;
132#define DECLARE_REG_VALUE_INFO_HELPERS(decl)\
133decl int ida_export reg_value_info_vals_union(reg_value_info_t *_this, const reg_value_info_t *r);\
134decl void ida_export reg_value_info_dstr(const reg_value_info_t *_this, qstring *vout, const procmod_t *pm);
140struct reg_value_info_t
143 using val_def_t = reg_value_def_t;
144 friend struct reg_finder_block_t;
189 state_t state = UNDEF;
191 explicit reg_value_info_t(
198 vals.
push_back(val_def_t(_val, def_ea, val_flags));
200 explicit reg_value_info_t(
207 vals.
push_back(val_def_t(_val, insn, val_flags));
211 reg_value_info_t() {}
219 bool empty()
const {
return state == UNDEF; }
221 void swap(reg_value_info_t &r)
noexcept
223 std::swap(state, r.state);
229 static reg_value_info_t make_dead_end(
ea_t dead_end_ea)
231 return reg_value_info_t(DEADEND, dead_end_ea);
236 static reg_value_info_t make_aborted(
238 int aborting_depth = -1)
240 return reg_value_info_t(ABORTED, bblk_ea,
uint32(aborting_depth));
245 static reg_value_info_t make_badinsn(
ea_t insn_ea)
247 return reg_value_info_t(BADINSN, insn_ea);
252 static reg_value_info_t make_unkinsn(
const insn_t &insn)
254 return reg_value_info_t(UNKINSN, insn);
259 static reg_value_info_t make_unkfunc(
ea_t func_ea)
261 return reg_value_info_t(UNKFUNC, func_ea);
266 static reg_value_info_t make_unkloop(
ea_t bblk_ea)
268 return reg_value_info_t(UNKLOOP, bblk_ea);
273 static reg_value_info_t make_unkmult(
ea_t bblk_ea)
275 return reg_value_info_t(UNKMULT, bblk_ea);
280 static reg_value_info_t make_unkxref(
ea_t bblk_ea)
282 return reg_value_info_t(UNKXREF, bblk_ea);
287 static reg_value_info_t make_unkvals(
ea_t bblk_ea)
289 return reg_value_info_t(UNKVALS, bblk_ea);
299 return reg_value_info_t(NUMINSN, insn, rval, val_flags);
308 return reg_value_info_t(NUMADDR, val_ea, rval, val_flags);
313 static reg_value_info_t make_initial_sp(
ea_t func_ea)
315 return reg_value_info_t(SPDADDR, func_ea, 0);
322 bool is_dead_end()
const {
return state == DEADEND; }
324 bool aborted()
const {
return state == ABORTED; }
326 bool is_special()
const {
return is_dead_end() || aborted(); }
329 bool is_badinsn()
const {
return state == BADINSN; }
331 bool is_unkinsn()
const {
return state == UNKINSN; }
333 bool is_unkfunc()
const {
return state == UNKFUNC; }
335 bool is_unkloop()
const {
return state == UNKLOOP; }
338 bool is_unkmult()
const {
return state == UNKMULT; }
340 bool is_unkxref()
const {
return state == UNKXREF; }
343 bool is_unkvals()
const {
return state == UNKVALS; }
347 return state == BADINSN
357 bool is_num()
const {
return state == NUMINSN || state == NUMADDR; }
359 bool is_spd()
const {
return state == SPDINSN || state == SPDADDR; }
361 bool is_known()
const {
return is_num() || is_spd(); }
365 bool get_num(
uval_t *uval)
const
367 if ( !is_num() || !is_value_unique() )
369 *uval = vals.
begin()->val;
378 if ( !is_spd() || !is_value_unique() )
384 ea_t get_def_ea()
const
386 return !is_value_unique() ? BADADDR : vals.
begin()->def_ea;
389 uint16 get_def_itype()
const
391 return !is_value_unique() ? 0 : vals.
begin()->def_itype;
394 int get_aborting_depth()
const
396 if ( !aborted() || !is_value_unique() )
402 const reg_value_def_t *vals_begin()
const {
return vals.
begin(); }
404 const reg_value_def_t *vals_end()
const {
return vals.
end(); }
406 size_t vals_size()
const {
return vals.
size(); }
409 bool is_value_unique()
const
413 if ( vals.
size() == 1 )
415 auto p = vals.
begin();
417 for ( ++p; p != vals.
end(); ++p )
424 bool have_all_vals_flag(
uint16 val_flags)
const
426 for (
auto p : vals )
427 if ( (p.flags & val_flags) == 0 )
431 bool has_any_vals_flag(
uint16 val_flags)
const
433 for (
auto p : vals )
434 if ( (p.flags & val_flags) != 0 )
438 bool is_all_vals_pc_based()
const
440 return have_all_vals_flag(val_def_t::PC_BASED);
442 bool is_any_vals_pc_based()
const
444 return has_any_vals_flag(val_def_t::PC_BASED);
446 bool is_all_vals_like_got()
const
448 return have_all_vals_flag(val_def_t::LIKE_GOT);
450 bool is_any_vals_like_got()
const
452 return has_any_vals_flag(val_def_t::LIKE_GOT);
456 void set_all_vals_flag(
uint16 val_flags)
458 for (
auto &p : vals )
459 p.flags |= val_flags;
461 void set_all_vals_pc_based()
463 return set_all_vals_flag(val_def_t::PC_BASED);
465 void set_all_vals_got_based()
467 return set_all_vals_flag(val_def_t::LIKE_GOT);
475 void set_dead_end(
ea_t dead_end_ea)
479 vals.
push_back(val_def_t(BADADDR, dead_end_ea));
484 void set_badinsn(
ea_t insn_ea)
488 vals.
push_back(val_def_t(BADADDR, insn_ea));
493 void set_unkinsn(
const insn_t &insn)
497 vals.
push_back(val_def_t(BADADDR, insn));
502 void set_unkfunc(
ea_t func_ea)
506 vals.
push_back(val_def_t(BADADDR, func_ea));
511 void set_unkloop(
ea_t bblk_ea)
515 vals.
push_back(val_def_t(BADADDR, bblk_ea));
520 void set_unkmult(
ea_t bblk_ea)
524 vals.
push_back(val_def_t(BADADDR, bblk_ea));
529 void set_unkxref(
ea_t bblk_ea)
533 vals.
push_back(val_def_t(BADADDR, bblk_ea));
538 void set_unkvals(
ea_t bblk_ea)
542 vals.
push_back(val_def_t(BADADDR, bblk_ea));
547 void set_aborted(
ea_t bblk_ea,
int aborting_depth = -1)
556 void set_num(
uval_t rval,
const insn_t &insn,
uint16 val_flags = 0)
560 vals.
push_back(val_def_t(rval, insn, val_flags));
565 void set_num(
uvalvec_t *rvals,
const insn_t &insn)
568 set_multivals(rvals, insn);
576 vals.
push_back(val_def_t(rval, val_ea, val_flags));
580 enum set_compare_res_t
593 set_compare_res_t vals_union(
const reg_value_info_t &r)
595 return set_compare_res_t(reg_value_info_vals_union(
this, &r));
601 inline void extend(
const procmod_t &pm,
int width,
bool is_signed);
605 inline void trunc_uval(
const procmod_t &pm);
611 OR, AND, XOR, AND_NOT,
618 inline void add(
const reg_value_info_t &r,
const insn_t &insn);
621 inline void sub(
const reg_value_info_t &r,
const insn_t &insn);
625 inline void bor(
const reg_value_info_t &r,
const insn_t &insn);
629 inline void band(
const reg_value_info_t &r,
const insn_t &insn);
633 inline void bxor(
const reg_value_info_t &r,
const insn_t &insn);
637 inline void bandnot(
const reg_value_info_t &r,
const insn_t &insn);
640 inline void sll(
const reg_value_info_t &r,
const insn_t &insn);
644 inline void slr(
const reg_value_info_t &r,
const insn_t &insn);
648 inline void sar(
const reg_value_info_t &r,
const insn_t &insn);
652 inline void movt(
const reg_value_info_t &r,
const insn_t &insn);
654 inline void neg(
const insn_t &insn);
657 inline void bnot(
const insn_t &insn);
660 inline void add_num(
uval_t r,
const insn_t &insn);
664 inline void add_num(
uval_t r);
667 inline void shift_left(
uval_t r);
670 inline void shift_right(
uval_t r);
676 reg_value_info_dstr(
this, &out, pm);
684 set_compare_res_t vals_union_impl(
const reg_value_info_t &r);
689 inline bool perform_binary_op(
690 const reg_value_info_t &r,
695 inline void set_multivals(V *rvals,
const insn_t &insn);
697 inline void sort_multivals();
702struct reg_finder_op_t
713 static constexpr uint32 REG = 0;
714 static constexpr uint32 STKVAR = 1 << 31;
715 static constexpr int WIDTH_SHIFT = 29;
716 static constexpr uint32 WIDTH_MASK = 0x3 << WIDTH_SHIFT;
717 static constexpr uint32 SIGNED = 1 << 28;
718 static constexpr int STKOFF_SIGNBIT = 1 << 27;
719 static constexpr uint32 STKOFF_MASK = STKOFF_SIGNBIT - 1;
721 static constexpr uint32 BADREG = 0x10000;
735 bool empty()
const {
return packed == BADREG; }
740 return reg >= 0 && reg < BADREG;
745 return make_reg(reg, pm.eah().ea_size);
750 return stkoff >= -
sval_t(STKOFF_MASK) && stkoff <=
sval_t(STKOFF_MASK);
759 bool is_reg()
const {
return (packed & STKVAR) == 0; }
760 bool is_stkvar()
const {
return (packed & STKVAR) != 0; }
761 bool is_signed()
const {
return (packed & SIGNED) != 0; }
764 return 1 << ((packed & WIDTH_MASK) >> WIDTH_SHIFT);
770 sval_t stkoff = packed & STKOFF_MASK;
771 return (packed & STKOFF_SIGNBIT) == 0 ? stkoff : -stkoff;
780 return r.empty() ? 0 : -1;
783 return ::compare(packed, r.packed);
793struct reg_value_ud_chain_t;
795 reg_value_info_t *v1,
796 reg_value_info_t *v2,
800#define DECLARE_REG_FINDER_HELPERS(decl)\
801decl void ida_export reg_finder_invalidate_cache(reg_finder_t *_this, ea_t to, ea_t from, cref_t cref);\
802decl void ida_export reg_finder_invalidate_xrefs_cache(reg_finder_t *_this, ea_t ea, dref_t dref);\
803decl void ida_export reg_finder_find(reg_finder_t *_this, reg_value_info_t *out, ea_t ea, ea_t ds, reg_finder_op_t op, int max_depth, size_t linear_insns);\
804decl void ida_export reg_finder_make_rfop(reg_finder_t *_this, reg_finder_op_t *rfop, const op_t *op, const insn_t *insn, func_t *pfn);\
805decl bool ida_export reg_finder_calc_op_addr(reg_finder_t *_this, reg_value_info_t *addr, const op_t *memop, const insn_t *insn, ea_t ea, ea_t ds, int max_depth);\
806decl bool ida_export reg_finder_emulate_mem_read(reg_finder_t *_this, reg_value_info_t *value, const reg_value_info_t *addr, int width, bool is_signed, const insn_t *insn);\
807decl void ida_export reg_finder_emulate_binary_op(reg_finder_t *_this, reg_value_info_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);\
808decl void ida_export reg_finder_emulate_unary_op(reg_finder_t *_this, reg_value_info_t *value, int aop, int reg, const insn_t *insn, ea_t ea, ea_t ds);\
809decl bool ida_export reg_finder_may_modify_stkvar(reg_finder_t *_this, reg_value_info_t *value, reg_finder_op_t op, const insn_t *insn);\
810decl bool ida_export reg_finder_can_resolve_mem(const reg_finder_t *_this, ea_t ea);\
811decl void ida_export reg_finder_ctr(reg_finder_t *_this);\
812decl void ida_export reg_finder_dtr(reg_finder_t *_this);
818struct reg_finder_block_t;
819struct reg_finder_pred_t;
880 static constexpr uint32 COND_MASK = 0x0F;
881 static constexpr int KIND_SHIFT = 4;
882 static constexpr uint32 KIND_MASK = 0xF;
914 : packed((cond & COND_MASK) | ((kind & KIND_MASK) << KIND_SHIFT)) {}
926 return cnd == rcnd || rcnd ==
AL;
931 return uchar((packed >> KIND_SHIFT) & KIND_MASK);
938 using udc_t = reg_value_ud_chain_t;
948 DECLARE_COMPARISONS(addr_t)
952 code = rfop.compare(r.rfop);
964 : chain_num(_chain_num), delta(_delta) {}
967 bool operator==(
const vref_t &r)
969 return chain_num == r.chain_num && delta == r.delta;
988 bool in_invalidate =
false;
989 bool debug_on =
true;
1000 reg_finder_ctr(
this);
1009 reg_finder_invalidate_cache(
this, to, from, cref);
1014 reg_finder_invalidate_cache(
this, BADADDR, BADADDR,
fl_U);
1021 reg_finder_invalidate_xrefs_cache(
this, ea, dref);
1043 size_t linear_insns = 0)
1047 reg_finder_find(
this, &ret,
1048 flow.
ea, flow.
ds, rfop,
1049 max_depth, linear_insns);
1055 reg_value_info_t *rvi,
1058 size_t linear_insns = 10)
1060 if ( reg[0] == reg[1] )
1063 if ( rvi->is_known() )
1066 if ( rvi->is_known() )
1069 if ( rvi->is_known() )
1072 if ( rvi->is_known() )
1080 return find(ea, rfop, max_depth).get_num(val);
1104 reg_finder_make_rfop(
this, &res, &op, &insn, pfn);
1126 reg_finder_calc_op_addr(
this, &ret,
1128 &insn, flow.
ea, flow.
ds, max_depth);
1149 reg_finder_emulate_mem_read(
this, value, &addr,
1157 return reg_finder_can_resolve_mem(
this, ea);
1218 bool is_func_start)
const
1222 qnotused(is_func_start);
1290 qnotused(move_desc);
1318 value->set_unkinsn(insn);
1330 reg_finder_find(
this, &ret, flow.
ea, flow.
ds, rfop, 0, 0);
1341 reg_finder_find(
this, &ret, flow.
ea, flow.
ds, rfop, 0, 0);
1353 reg_finder_calc_op_addr(
this, addr,
1355 &insn, flow.
ea, flow.
ds, 0);
1360 rvi_t::arith_op_t aop,
1368 reg_finder_emulate_binary_op(
this, value,
1370 &insn, flow.
ea, flow.
ds,
1375 rvi_t::arith_op_t aop,
1380 reg_finder_emulate_unary_op(
this, value,
1382 &insn, flow.
ea, flow.
ds);
1391 return reg_finder_may_modify_stkvar(
this, value, rfop, &insn);
1396 rvi_t find_chain(
const flow_t flow,
const rfop_t rfop);
1397 void create_initial_block(
const flow_t flow,
const rfop_t rfop);
1399 bool create_new_block(vref_t *res_vref,
const pred_t &pred);
1400 bool handle_block_pred(
size_t chain_num, vref_t pred_vref);
1401 vref_t finalize_block();
1404 bool collect_predecessors(
qvector<flow_t> *pred_addrs, flow_t flow)
const;
1405 bool analyze_linear_flow(
1408 ea_t initial_ea)
const;
1409 bool merge_loop_blocks(
const block_t *loop_block,
sval_t delta);
1410 bool decode_and_emulate_insn(
1421 rvi_t make_aborted();
1422 bool set_aborted_or_unkinsn(
rvi_t *value,
const insn_t &insn);
1425 enum handle_move_res_t
1440 handle_move_res_t handle_move(
1443 const insn_t &insn);
1448 enum overlap_res_t { SAME, OVERLAPS, DIFFERENT };
1449 overlap_res_t does_rfop_overlap_with_op(
1452 const insn_t &insn);
1456 bool calc_stkvar_off(
1463 reg_value_ud_chain_t &get_chain(
size_t chain_num);
1464 const reg_value_ud_chain_t &get_chain(
size_t chain_num)
const;
1465 void erase_block(
size_t chain_num);
1468 size_t from_chain_num,
1469 size_t to_chain_num,
1471 void adjust_deltas(
const qvector<addr_t> &addrs,
sval_t delta);
1472 void trim_cache(
ea_t ea,
int max_cache_size);
1474 bool is_rfop_changed(
1479 DECLARE_REG_FINDER_HELPERS(
friend)
1483 void invalidate_xrefs_cache_impl(
ea_t ea,
dref_t dref);
1487 rvi_t find_impl(
flow_t flow,
int reg,
int max_depth = 0)
1491 rfop_t make_rfop_impl(
const op_t &op,
const insn_t &insn, func_t *pfn);
1492 bool calc_op_addr_impl(
1498 bool emulate_mem_read_impl(
1503 const insn_t &insn);
1504 void emulate_binary_op_impl(
1506 rvi_t::arith_op_t aop,
1512 void *ud =
nullptr);
1513 void emulate_unary_op_impl(
1515 rvi_t::arith_op_t aop,
1519 bool may_modify_stkvar_impl(
1522 const insn_t &insn);
1523 bool can_resolve_mem_impl(
ea_t ea)
const;
1579 reg_value_info_t *rvi,
1594 reg_value_info_t *rvi,
1605 ea_t from = BADADDR,
1619inline void reg_value_info_t::extend(
1626 for (
auto &p : vals )
1630 p.val = pm.trunc_uval(p.val);
1632 p.val = pm.ea2sval(p.val);
1638inline void reg_value_info_t::trunc_uval(
const procmod_t &pm)
1642 for (
auto &p : vals )
1643 p.val = pm.trunc_uval(p.val);
1648inline bool reg_value_info_t::perform_binary_op(
1649 const reg_value_info_t &r,
1653 const reg_value_info_t *mv;
1655 if ( r.is_value_unique() )
1658 sv = r.vals.begin()->val;
1660 else if ( is_value_unique() )
1663 sv = vals.begin()->val;
1670 rvals.
reserve(mv->vals.size());
1671 for (
const auto &p : mv->vals )
1676 case ADD: res = p.val + sv;
break;
1677 case SUB: res = p.val - sv;
break;
1678 case OR: res = p.val | sv;
break;
1679 case AND: res = p.val & sv;
break;
1680 case XOR: res = p.val ^ sv;
break;
1681 case AND_NOT: res = p.val & ~sv;
break;
1682 case SLL: res = p.val << sv;
break;
1683 case SLR: res = p.val >> sv;
break;
1684 case SAR: res =
int64(p.val) >> sv;
break;
1685 case MOVT: res = (p.val & 0xFFFF) | ((sv & 0xFFFF) << 16);
break;
1686 default:
return false;
1690 set_multivals(&rvals, insn);
1695inline void reg_value_info_t::add(
1696 const reg_value_info_t &r,
1699 if ( is_spd() && r.is_num()
1700 || is_num() && r.is_spd()
1701 || is_num() && r.is_num() )
1703 if ( perform_binary_op(r, ADD, insn) )
1705 if ( is_spd() || r.is_spd() )
1715inline void reg_value_info_t::sub(
1716 const reg_value_info_t &r,
1719 if ( is_spd() && r.is_num()
1720 || is_spd() && r.is_spd()
1721 || is_num() && r.is_num() )
1723 if ( perform_binary_op(r, SUB, insn) )
1726 state = r.is_spd() ? NUMINSN : SPDINSN;
1735inline void reg_value_info_t::bor(
1736 const reg_value_info_t &r,
1739 if ( is_num() && r.is_num() )
1740 if ( perform_binary_op(r, OR, insn) )
1747inline void reg_value_info_t::band(
1748 const reg_value_info_t &r,
1752 if ( is_spd() && r.get_num(&mask) &&
is_pow2(mask + 1) && mask <= 31 )
1754 if ( perform_binary_op(r, AND, insn) )
1760 if ( is_num() && r.is_num() )
1762 if ( perform_binary_op(r, AND, insn) )
1770inline void reg_value_info_t::bxor(
1771 const reg_value_info_t &r,
1774 if ( is_num() && r.is_num() )
1775 if ( perform_binary_op(r, XOR, insn) )
1782inline void reg_value_info_t::bandnot(
1783 const reg_value_info_t &r,
1787 if ( is_spd() && r.get_num(&mask) &&
is_pow2(mask + 1) && mask <= 31 )
1788 if ( perform_binary_op(r, AND_NOT, insn) )
1790 if ( is_num() && r.is_num() )
1791 if ( perform_binary_op(r, AND_NOT, insn) )
1798inline void reg_value_info_t::sll(
1799 const reg_value_info_t &r,
1802 if ( is_num() && r.is_num() && perform_binary_op(r, SLL, insn) )
1809inline void reg_value_info_t::slr(
1810 const reg_value_info_t &r,
1813 if ( is_num() && r.is_num() && perform_binary_op(r, SLR, insn) )
1820inline void reg_value_info_t::sar(
1821 const reg_value_info_t &r,
1824 if ( is_num() && r.is_num() && perform_binary_op(r, SAR, insn) )
1831inline void reg_value_info_t::movt(
1832 const reg_value_info_t &r,
1835 if ( is_num() && r.is_num() && perform_binary_op(r, MOVT, insn) )
1842inline void reg_value_info_t::neg(
const insn_t &insn)
1848 for (
auto &p : vals )
1850 set_multivals(&rvals, insn);
1859inline void reg_value_info_t::bnot(
const insn_t &insn)
1865 for (
auto &p : vals )
1867 set_multivals(&rvals, insn);
1876inline void reg_value_info_t::add_num(
uval_t r,
const insn_t &insn)
1878 if ( !is_known() || r == 0 )
1882 for (
auto &p : vals )
1884 set_multivals(&rvals, insn);
1888inline void reg_value_info_t::add_num(
uval_t r)
1890 if ( !is_known() || r == 0 )
1892 for (
auto &p : vals )
1898inline void reg_value_info_t::shift_left(
uval_t r)
1900 if ( !is_known() || r == 0 )
1902 for (
auto &p : vals )
1908inline void reg_value_info_t::shift_right(
uval_t r)
1910 if ( !is_known() || r == 0 )
1912 for (
auto &p : vals )
1919inline void reg_value_info_t::set_multivals(
1924 std::sort(rvals->begin(), rvals->end());
1925 size_t newsz = std::unique(rvals->begin(), rvals->end()) - rvals->begin();
1927 for (
size_t i = 0; i < newsz; ++i )
1928 vals[i] = val_def_t(rvals->at(i), insn);
1932inline void reg_value_info_t::sort_multivals()
1935 std::sort(vals.begin(), vals.end());
1937 size_t new_size = std::unique(vals.begin(), vals.end()) - vals.begin();
1938 vals.resize(new_size);
1958 bool negative = stkoff < 0;
1961 | (negative ? STKOFF_SIGNBIT : 0)
1962 |
uint32(negative ? -stkoff : stkoff));
1969 if ( packed_width == BADREG )
1974 packed &= ~WIDTH_MASK;
1975 packed |= packed_width;
1990 if ( packed_width == BADREG )
1995 packed &= ~WIDTH_MASK;
1996 packed |= packed_width;
2007 case 1:
return 0 << WIDTH_SHIFT;
break;
2008 case 2:
return 1 << WIDTH_SHIFT;
break;
2009 case 4:
return 2 << WIDTH_SHIFT;
break;
2010 case 8:
return 3 << WIDTH_SHIFT;
break;
2011 default:
return BADREG;
A function is a set of continuous ranges of addresses with characteristics.
Definition funcs.hpp:85
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:2250
void reserve(size_t cnt)
Increase the capacity of the qvector.
Definition pro.h:2528
void swap(qvector< T > &r) noexcept
Replace all attributes of this qvector with that of 'r', and vice versa.
Definition pro.h:2560
void qclear(void)
Destroy all elements but do not free memory.
Definition pro.h:2434
iterator end(void)
Get an iterator that points to the end of the qvector (NOT the last element)
Definition pro.h:2610
iterator begin(void)
Get an iterator that points to the first element in the qvector.
Definition pro.h:2609
void push_back(T &&x)
Append a new element to the end the qvector with a move semantics.
Definition pro.h:2361
size_t size(void) const
Get the number of elements in the qvector.
Definition pro.h:2423
idaman sval_t ida_export get_spd(func_t *pfn, ea_t ea)
Get difference between the initial and current values of ESP.
bool func_contains(func_t *pfn, ea_t ea)
Does the given function contain the given address?
Definition funcs.hpp:305
idaman func_t *ida_export get_fchunk(ea_t ea)
Get pointer to function chunk structure by address.
bool is_same_func(ea_t ea1, ea_t ea2)
Do two addresses belong to the same function?
Definition funcs.hpp:311
THREAD_SAFE constexpr bool idaapi is_unknown(flags64_t F)
Does flag denote unexplored byte?
Definition bytes.hpp:805
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:10432
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:12657
Contains definition of the interface to IDP modules.
uval_t uval_t
Definition kernwin.hpp:1878
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:346
unsigned int uint32
unsigned 32 bit value
Definition pro.h:348
qvector< uval_t > uvalvec_t
vector of unsigned values
Definition pro.h:2762
adiff_t sval_t
signed value used by the processor.
Definition pro.h:446
uint64 ea_t
Definition pro.h:421
int int32
signed 32 bit value
Definition pro.h:347
unsigned char uchar
unsigned 8 bit value
Definition pro.h:337
THREAD_SAFE void qswap(T &a, T &b)
Swap 2 objects of the same type using memory copies.
Definition pro.h:1715
qvector< ea_t > eavec_t
vector of addresses
Definition pro.h:2764
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:344
constexpr bool is_pow2(T val)
is power of 2? (or zero)
Definition pro.h:1432
_qstring< char > qstring
regular string
Definition pro.h:3694
int compare(const T &a, const T &b)
Definition pro.h:4514
idaman 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.
idaman int ida_export find_reg_value(uval_t *uval, ea_t ea, int reg)
Find register value using the register tracker.
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).
void(* reg_finder_binary_ops_adjust_fun)(reg_value_info_t *v1, reg_value_info_t *v2, const insn_t &insn, void *ud)
Definition regfinder.hpp:794
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_INFO_HELPERS(idaman) struct reg_value_info_t
the value in a register after emulating instructions
Definition regfinder.hpp:136
DECLARE_REG_VALUE_DEF_HELPERS(idaman) struct reg_value_def_t
the register value and its defining instruction
Definition regfinder.hpp:56
DECLARE_TYPE_AS_MOVABLE(reg_value_def_t)
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
idaman 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:703
void set_width_signness(int width, bool is_signed)
Definition regfinder.hpp:1987
rfop_t & operator=(const rfop_t &r)=default
bool empty() const
Definition regfinder.hpp:735
void set_width(int width)
Definition regfinder.hpp:1966
static bool is_valid_reg(int reg)
Definition regfinder.hpp:738
uint16 get_reg() const
Definition regfinder.hpp:767
void set_signness(bool is_signed)
Definition regfinder.hpp:1979
reg_finder_op_t(const rfop_t &r)=default
void clear()
Definition regfinder.hpp:736
reg_finder_op_t()
Definition regfinder.hpp:729
static reg_finder_op_t make_reg(int reg, int width)
Definition regfinder.hpp:1942
static bool is_valid_stkoff(sval_t stkoff)
Definition regfinder.hpp:748
int get_width() const
Definition regfinder.hpp:762
static reg_finder_op_t make_reg(const procmod_t &pm, int reg)
Definition regfinder.hpp:743
static reg_finder_op_t make_stkoff(sval_t stkoff, int width)
Definition regfinder.hpp:1951
reg_finder_op_t rfop_t
Definition regfinder.hpp:728
static uint32 pack_width(int width)
Definition regfinder.hpp:2003
bool is_reg() const
Definition regfinder.hpp:759
sval_t get_stkoff() const
Definition regfinder.hpp:768
DECLARE_COMPARISONS(reg_finder_op_t)
Definition regfinder.hpp:776
bool is_signed() const
Definition regfinder.hpp:761
static int get_op_width(const op_t &op)
Definition regfinder.hpp:2016
bool is_stkvar() const
Definition regfinder.hpp:760
bool is_reg(int reg) const
Definition regfinder.hpp:774
Definition regfinder.hpp:877
cond_t(uchar cond=AL, uchar kind=NONE)
Definition regfinder.hpp:913
uchar get_kind() const
Definition regfinder.hpp:929
@ JUMPS
Definition regfinder.hpp:910
@ NONE
Definition regfinder.hpp:908
@ MODIFIES_CC
Definition regfinder.hpp:909
bool jumps() const
Definition regfinder.hpp:934
@ LE
Definition regfinder.hpp:901
@ VC
Definition regfinder.hpp:895
@ NV
Definition regfinder.hpp:903
@ AL
Definition regfinder.hpp:902
@ CC
Definition regfinder.hpp:891
@ HI
Definition regfinder.hpp:896
@ EQ
Definition regfinder.hpp:888
@ CS
Definition regfinder.hpp:890
@ LS
Definition regfinder.hpp:897
@ MI
Definition regfinder.hpp:892
@ LT
Definition regfinder.hpp:899
@ PL
Definition regfinder.hpp:893
@ VS
Definition regfinder.hpp:894
@ GE
Definition regfinder.hpp:898
@ NE
Definition regfinder.hpp:889
@ GT
Definition regfinder.hpp:900
bool modifies_cond_codes() const
Definition regfinder.hpp:933
uchar get_cond() const
Definition regfinder.hpp:916
bool is_included_in(cond_t r) const
Definition regfinder.hpp:920
Definition regfinder.hpp:1165
void handle_delay_slot()
Definition regfinder.hpp:1172
bool has_delay_slot() const
Definition regfinder.hpp:1168
bool operator<(const flow_t &r) const
Definition regfinder.hpp:1185
ea_t ds
Definition regfinder.hpp:1167
flow_t(ea_t _ea, ea_t _ds=BADADDR)
Definition regfinder.hpp:1174
ea_t ea
Definition regfinder.hpp:1166
bool is_ea_handled() const
Definition regfinder.hpp:1170
ea_t actual_ea() const
Definition regfinder.hpp:1182
Definition regfinder.hpp:1258
bool is_signed
Definition regfinder.hpp:1272
sval_t delta
Definition regfinder.hpp:1278
const op_t * src_op
Definition regfinder.hpp:1269
rfop_t new_rfop
Definition regfinder.hpp:1261
const op_t * dst_op
Definition regfinder.hpp:1267
Definition regfinder.hpp:821
bool does_call_spoil_stkvars() const
Definition regfinder.hpp:836
rvi_t find(flow_t flow, rfop_t rfop)
Definition regfinder.hpp:1327
const procmod_t & pm
Definition regfinder.hpp:822
virtual cond_t get_cond(ea_t ea) const
Definition regfinder.hpp:1205
rvi_t find_op_addr(const op_t &memop, const insn_t &insn, int max_depth=0)
Definition regfinder.hpp:1119
size_t linear_flow_cnt
Definition regfinder.hpp:860
reg_value_info_t rvi_t
Definition regfinder.hpp:846
virtual bool is_funcwide_reg(ea_t ea, int reg) const
Definition regfinder.hpp:1242
friend struct reg_finder_chainvec_t
Definition regfinder.hpp:940
friend struct reg_finder_block_t
Definition regfinder.hpp:850
friend struct reg_finder_pred_t
Definition regfinder.hpp:851
reg_finder_block_t block_t
Definition regfinder.hpp:848
friend struct reg_finder_xrefs_cache_t
Definition regfinder.hpp:985
reg_finder_t(const procmod_t &_pm, int _proc_maxop=3, uint32 _flags=RF_DOES_CALL_SPOIL_STKVARS)
Definition regfinder.hpp:992
size_t bblk_cnt
Definition regfinder.hpp:863
virtual int get_sp_reg(ea_t ea) const
Definition regfinder.hpp:1235
void emulate_binary_op(rvi_t *value, rvi_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:1358
virtual bool can_track_op(op_t *op, const insn_t &insn, func_t *pfn) const
Definition regfinder.hpp:1248
int find_nearest(reg_value_info_t *rvi, ea_t ea, const int reg[2], size_t linear_insns=10)
Definition regfinder.hpp:1054
static constexpr uint32 RF_ALLOW_XREFS_CACHE
Definition regfinder.hpp:834
ea_t aborting_ea
Definition regfinder.hpp:864
op_t fake_op1
Definition regfinder.hpp:871
bool can_resolve_mem(ea_t ea) const
Definition regfinder.hpp:1155
const int proc_maxop
Definition regfinder.hpp:823
bool may_modify_stkvar(rvi_t *value, rfop_t rfop, const insn_t &insn)
Definition regfinder.hpp:1389
rvi_t standalone_value
Definition regfinder.hpp:865
virtual bool emulate_insn(rvi_t *value, const rfop_t &rfop, const insn_t &insn, flow_t flow)
Definition regfinder.hpp:1310
uint32 flags
Definition regfinder.hpp:825
void calc_op_addr(rvi_t *addr, const op_t &memop, const insn_t &insn, flow_t flow)
Definition regfinder.hpp:1347
virtual bool is_mem_readonly(ea_t) const
Definition regfinder.hpp:1229
virtual flow_t process_delay_slot(ea_t ea, cref_t) const
Definition regfinder.hpp:1199
void invalidate_cache()
Definition regfinder.hpp:1012
virtual rvi_t handle_well_known_regs(flow_t flow, rfop_t rfop, bool is_func_start) const
Definition regfinder.hpp:1215
bool only_linear_flow() const
Definition regfinder.hpp:862
size_t initial_block_idx
Definition regfinder.hpp:855
static constexpr size_t NO_CHAIN
Definition regfinder.hpp:868
friend struct reg_finder_rfop_chains_t
Definition regfinder.hpp:976
reg_finder_op_t rfop_t
Definition regfinder.hpp:847
rvi_t find(flow_t flow, int reg)
Definition regfinder.hpp:1337
void invalidate_xrefs_cache(ea_t ea, dref_t dref)
Definition regfinder.hpp:1019
virtual ~reg_finder_t()
Definition regfinder.hpp:1002
bool fixed_max_depth
Definition regfinder.hpp:856
func_t * cur_func
Definition regfinder.hpp:854
void emulate_mem_read(rvi_t *value, const rvi_t &addr, int width, bool is_signed, const insn_t &insn)
Definition regfinder.hpp:1142
static constexpr uint32 RF_DOES_CALL_SPOIL_STKVARS
Definition regfinder.hpp:829
rfop_t make_rfop(const op_t &_op, const insn_t &insn, func_t *pfn)
Definition regfinder.hpp:1098
void emulate_unary_op(rvi_t *value, rvi_t::arith_op_t aop, int reg, const insn_t &insn, flow_t flow)
Definition regfinder.hpp:1373
bool allow_xrefs_cache() const
Definition regfinder.hpp:840
bool find_spd(sval_t *spval, ea_t ea, int reg=-1, int max_depth=-1)
Definition regfinder.hpp:1085
int cur_call_depth
Definition regfinder.hpp:859
void invalidate_cache(ea_t to, ea_t from, cref_t cref)
Definition regfinder.hpp:1007
int cur_max_depth
Definition regfinder.hpp:858
rvi_t find(ea_t ea, rfop_t rfop, int max_depth=0, size_t linear_insns=0)
Definition regfinder.hpp:1039
bool find_const(uval_t *val, ea_t ea, rfop_t rfop, int max_depth=0)
Definition regfinder.hpp:1078
virtual bool is_move_insn(move_desc_t *move_desc, const rfop_t &rfop, const insn_t &insn)
Definition regfinder.hpp:1285
op_t fake_op2
Definition regfinder.hpp:872
reg_finder_pred_t pred_t
Definition regfinder.hpp:849
THREAD_SAFE bool operator<(const bytevec_t &v1, const bytevec_t &v2)
Compare two bytevecs with '<'.
Definition typeinf.hpp:631
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.