220#pragma warning(disable:4062)
221#pragma warning(disable:4265)
258typedef std::set<voff_t> voff_set_t;
272typedef std::set<ea_t> easet_t;
273typedef std::set<minsn_t *> minsn_ptr_set_t;
274typedef std::set<qstring> strings_t;
275typedef qvector<minsn_t*> minsnptrs_t;
276typedef qvector<mop_t*> mopptrs_t;
277typedef qvector<mop_t> mopvec_t;
278typedef qvector<uint64> uint64vec_t;
279typedef qvector<mreg_t> mregvec_t;
280typedef qrefcnt_t<cfunc_t> cfuncptr_t;
284#define MAX_SUPPORTED_STACK_SIZE 0x100000
289#define HEXRAYS_PLACEMENT_DELETE void operator delete(void *, void *) {}
290#define HEXRAYS_MEMORY_ALLOCATION_FUNCS() \
291 void *operator new (size_t _s) { return hexrays_alloc(_s); } \
292 void *operator new[](size_t _s) { return hexrays_alloc(_s); } \
293 void *operator new(size_t , void *_v) { return _v; } \
294 void operator delete (void *_blk) { hexrays_free(_blk); } \
295 void operator delete[](void *_blk) { hexrays_free(_blk); } \
296 HEXRAYS_PLACEMENT_DELETE
298void *
hexapi hexrays_alloc(
size_t size);
299void hexapi hexrays_free(
void *ptr);
301typedef uint64 uvlr_t;
303enum { MAX_VLR_SIZE =
sizeof(uvlr_t) };
304const uvlr_t MAX_VALUE = uvlr_t(-1);
305const svlr_t MAX_SVALUE = svlr_t(uvlr_t(-1) >> 1);
306const svlr_t MIN_SVALUE = ~MAX_SVALUE;
332#define VLR_RANGE 0x03
333#define VLR_SRANGE 0x04
337#define VLR_UNION 0x07
358 char reserved[
sizeof(qvector<int>)];
366 explicit valrng_t(
int size_ = MAX_VLR_SIZE)
367 : flags(VLR_NONE), size(size_), value(0), limit(0), stride(0) {}
371 void swap(
valrng_t &r) { qswap(*
this, r); }
373 DEFINE_MEMORY_ALLOCATION_FUNCS()
375 void set_none(
void) { clear(); }
376 void set_all(
void) { clear(); flags = VLR_ALL; }
377 void set_unk(
void) { clear(); flags = VLR_UNK; }
378 void hexapi set_eq(uvlr_t v);
379 void hexapi set_cmp(cmpop_t cmp, uvlr_t _value);
388 bool hexapi reduce_size(
int new_size);
396 bool empty(
void)
const {
return flags == VLR_NONE; }
397 bool all_values(
void)
const {
return flags == VLR_ALL; }
398 bool is_unknown(
void)
const {
return flags == VLR_UNK; }
399 bool hexapi has(uvlr_t v)
const;
401 void hexapi print(qstring *vout)
const;
402 const char *
hexapi dstr(
void)
const;
404 bool hexapi cvt_to_single_value(uvlr_t *v)
const;
405 bool hexapi cvt_to_cmp(cmpop_t *cmp, uvlr_t *val,
bool strict)
const;
407 int get_size()
const {
return size; }
408 static uvlr_t max_value(
int size_)
410 return size_ == MAX_VLR_SIZE
412 : (uvlr_t(1) << (size_ * 8)) - 1;
414 static uvlr_t min_svalue(
int size_)
416 return size_ == MAX_VLR_SIZE
418 : (uvlr_t(1) << (size_ * 8 - 1));
420 static uvlr_t max_svalue(
int size_)
422 return size_ == MAX_VLR_SIZE
424 : (uvlr_t(1) << (size_ * 8 - 1)) - 1;
426 uvlr_t max_value()
const {
return max_value(size); }
427 uvlr_t min_svalue()
const {
return min_svalue(size); }
428 uvlr_t max_svalue()
const {
return max_svalue(size); }
440typedef int maymust_t;
446 MAYMUST_ACCESS_MASK = 0x01,
448 ONE_ACCESS_TYPE = 0x20,
451 INCLUDE_SPOILED_REGS = 0x40,
453 EXCLUDE_PASS_REGS = 0x80,
458 WITH_ASSERTS = 0x200,
460 EXCLUDE_VOLATILE = 0x400,
462 INCLUDE_UNUSED_SRC = 0x800,
464 INCLUDE_DEAD_RETREGS = 0x1000,
466 INCLUDE_RESTRICTED = 0x2000,
467 CALL_SPOILS_ONLY_ARGS = 0x4000;
471inline THREAD_SAFE
bool is_may_access(maymust_t maymust)
473 return (maymust & MAYMUST_ACCESS_MASK) != MUST_ACCESS;
637inline THREAD_SAFE
bool is_mcode_addsub(mcode_t mcode) {
return mcode == m_add || mcode == m_sub; }
639inline THREAD_SAFE
bool is_mcode_xdsu(mcode_t mcode) {
return mcode == m_xds || mcode == m_xdu; }
641inline THREAD_SAFE
bool is_mcode_set(mcode_t mcode) {
return mcode >= m_sets && mcode <= m_setle; }
643inline THREAD_SAFE
bool is_mcode_set1(mcode_t mcode) {
return mcode == m_sets; }
645inline THREAD_SAFE
bool is_mcode_j1(mcode_t mcode) {
return mcode == m_jcnd; }
647inline THREAD_SAFE
bool is_mcode_jcond(mcode_t mcode) {
return mcode >= m_jcnd && mcode <= m_jle; }
649inline THREAD_SAFE
bool is_mcode_convertible_to_jmp(mcode_t mcode) {
return mcode >= m_setnz && mcode <= m_setle; }
651inline THREAD_SAFE
bool is_mcode_convertible_to_set(mcode_t mcode) {
return mcode >= m_jnz && mcode <= m_jle; }
653inline THREAD_SAFE
bool is_mcode_call(mcode_t mcode) {
return mcode == m_call || mcode == m_icall; }
655inline THREAD_SAFE
bool is_mcode_fpu(mcode_t mcode) {
return mcode >= m_f2i; }
657inline THREAD_SAFE
bool is_mcode_commutative(mcode_t mcode)
659 return mcode == m_add
670inline THREAD_SAFE
bool is_mcode_shift(mcode_t mcode)
672 return mcode == m_shl
677inline THREAD_SAFE
bool is_mcode_divmod(mcode_t op)
679 return op == m_udiv || op == m_sdiv || op == m_umod || op == m_smod;
682inline THREAD_SAFE
bool has_mcode_seloff(mcode_t op)
684 return op == m_ldx || op == m_stx || op == m_icall || op == m_ijmp;
689inline THREAD_SAFE mcode_t set2jcnd(mcode_t code)
691 return mcode_t(code - m_setnz + m_jnz);
696inline THREAD_SAFE mcode_t jcnd2set(mcode_t code)
698 return mcode_t(code + m_setnz - m_jnz);
705THREAD_SAFE mcode_t
hexapi negate_mcode_relation(mcode_t code);
714THREAD_SAFE mcode_t
hexapi swap_mcode_relation(mcode_t code);
720THREAD_SAFE mcode_t
hexapi get_signed_mcode(mcode_t code);
727THREAD_SAFE mcode_t
hexapi get_unsigned_mcode(mcode_t code);
730inline THREAD_SAFE
bool is_signed_mcode(mcode_t code) {
return get_unsigned_mcode(code) != code; }
732inline THREAD_SAFE
bool is_unsigned_mcode(mcode_t code) {
return get_signed_mcode(code) != code; }
741THREAD_SAFE
bool hexapi mcode_modifies_d(mcode_t mcode);
752const int cc_count = mr_pf - mr_cf + 1;
771 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
786#define NF_NEGDONE 0x02
787#define NF_BINVDONE 0x04
788#define NF_NEGATE 0x08
789#define NF_BITNOT 0x10
833 bool has_unmutable_type()
const
837 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
858 AS_PRINTF(3, 4) virtual
int hexapi print(
int indent, const
char *format,...);
859 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
871 virtual bool idaapi
oneliner(
void)
const newapi {
return false; }
885 AS_PRINTF(3, 4) int
hexapi print(
int indent, const
char *format, ...) override;
905 AS_PRINTF(3, 4) int
hexapi print(
int indent, const
char *format, ...) override;
947 return is_type_ptr(t) || is_type_array(t);
959 return type.is_decl_complex() && !type.is_typeref();
1031 tif.create_typedef(
nullptr, n);
1042 TS_NOELL = 0x8000000,
1043 TS_SHRINK = 0x4000000,
1044 TS_DONTREF = 0x2000000,
1045 TS_MASK = 0xE000000,
1087 int reg1(
void)
const {
return atype() == ALOC_REG2 ? argloc_t::reg1() : get_reginfo(); }
1092 void _set_reg1(
int r1) { argloc_t::_set_reg1(r1, r1>>16); }
1095 void set_reg1(
int r1) { cleanup_argloc(
this); _set_reg1(r1); }
1104 bool hexapi is_aliasable(
const mba_t *mb,
int size)
const;
1134 return location.is_stkoff() ? location.stkoff() : -1;
1137 bool is_reg1(
void)
const {
return location.is_reg1(); }
1139 bool is_reg2(
void)
const {
return location.is_reg2(); }
1151 const scattered_aloc_t &
get_scattered(
void)
const {
return location.scattered(); }
1152 scattered_aloc_t &get_scattered(
void) {
return location.scattered(); }
1154 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
1167#define CVAR_USED 0x00000001
1168#define CVAR_TYPE 0x00000002
1169#define CVAR_NAME 0x00000004
1170#define CVAR_MREG 0x00000008
1171#define CVAR_NOWD 0x00000010
1172#define CVAR_UNAME 0x00000020
1173#define CVAR_UTYPE 0x00000040
1174#define CVAR_RESULT 0x00000080
1175#define CVAR_ARG 0x00000100
1176#define CVAR_FAKE 0x00000200
1177#define CVAR_OVER 0x00000400
1178#define CVAR_FLOAT 0x00000800
1179#define CVAR_SPOILED 0x00001000
1180#define CVAR_MAPDST 0x00002000
1181#define CVAR_PARTIAL 0x00004000
1182#define CVAR_THISARG 0x00008000
1183#define CVAR_FORCED 0x00010000
1185#define CVAR_REGNAME 0x00020000
1187#define CVAR_NOPTR 0x00040000
1188#define CVAR_DUMMY 0x00080000
1190#define CVAR_NOTARG 0x00100000
1191#define CVAR_AUTOMAP 0x00200000
1192#define CVAR_BYREF 0x00400000
1193#define CVAR_INASM 0x00800000
1195#define CVAR_UNUSED 0x01000000
1211 lvar_t(
const qstring &n,
const vdloc_t &l, ea_t e,
const tinfo_t &t,
int w,
int db)
1243 bool hexapi is_promoted_arg(
void)
const;
1276 void set_used(
void) { flags |=
CVAR_USED; }
1277 void clear_used(
void) { flags &= ~CVAR_USED; }
1278 void set_typed(
void) { flags |=
CVAR_TYPE; clr_noptr_var(); }
1279 void set_non_typed(
void) { flags &= ~CVAR_TYPE; }
1283 void clr_user_type(
void) { flags &= ~CVAR_UTYPE; }
1284 void clr_user_name(
void) { flags &= ~CVAR_UNAME; }
1285 void set_mreg_done(
void) { flags |=
CVAR_MREG; }
1286 void clr_mreg_done(
void) { flags &= ~CVAR_MREG; }
1287 void set_unknown_width(
void) { flags |=
CVAR_NOWD; }
1288 void clr_unknown_width(
void) { flags &= ~CVAR_NOWD; }
1289 void set_arg_var(
void) { flags |=
CVAR_ARG; }
1291 void set_fake_var(
void) { flags |=
CVAR_FAKE; }
1292 void clr_fake_var(
void) { flags &= ~CVAR_FAKE; }
1293 void set_overlapped_var(
void) { flags |=
CVAR_OVER; }
1294 void clr_overlapped_var(
void) { flags &= ~CVAR_OVER; }
1295 void set_floating_var(
void) { flags |=
CVAR_FLOAT; }
1296 void clr_floating_var(
void) { flags &= ~CVAR_FLOAT; }
1298 void clr_spoiled_var(
void) { flags &= ~CVAR_SPOILED; }
1299 void set_mapdst_var(
void) { flags |=
CVAR_MAPDST; }
1300 void clr_mapdst_var(
void) { flags &= ~CVAR_MAPDST; }
1301 void set_partialy_typed(
void) { flags |=
CVAR_PARTIAL; }
1302 void clr_partialy_typed(
void) { flags &= ~CVAR_PARTIAL; }
1303 void set_noptr_var(
void) { flags |=
CVAR_NOPTR; }
1304 void clr_noptr_var(
void) { flags &= ~CVAR_NOPTR; }
1306 void clr_thisarg(
void) { flags &= ~CVAR_THISARG; }
1307 void set_forced_var(
void) { flags |=
CVAR_FORCED; }
1308 void clr_forced_var(
void) { flags &= ~CVAR_FORCED; }
1309 void set_dummy_arg(
void) { flags |=
CVAR_DUMMY; }
1310 void clr_dummy_arg(
void) { flags &= ~CVAR_DUMMY; }
1311 void set_notarg(
void) { clr_arg_var(); flags |=
CVAR_NOTARG; }
1312 void clr_notarg(
void) { flags &= ~CVAR_NOTARG; }
1314 void clr_automapped(
void) { flags &= ~CVAR_AUTOMAP; }
1315 void set_used_byref(
void) { flags |=
CVAR_BYREF; }
1316 void clr_used_byref(
void) { flags &= ~CVAR_BYREF; }
1317 void set_decl_unused(
void) { flags |=
CVAR_UNUSED; }
1318 void clr_decl_unused(
void) { flags &= ~CVAR_UNUSED; }
1331 const tinfo_t &
type(
void)
const {
return tif; }
1332 tinfo_t &type(
void) {
return tif; }
1336 bool hexapi accepts_type(
const tinfo_t &t,
bool may_change_thisarg=
false);
1347 bool hexapi set_lvar_type(
const tinfo_t &t,
bool may_fail=
false);
1362 bool hexapi set_width(
int w,
int svw_flags=0);
1364#define SVW_FLOAT 0x01
1365#define SVW_SOFT 0x02
1372 void hexapi append_list(
const mba_t *mba,
mlist_t *lst,
bool pad_if_scattered=
false)
const;
1379 return location.is_aliasable(mba, width);
1383DECLARE_TYPE_AS_MOVABLE(
lvar_t);
1399 int hexapi find_stkvar(sval_t spoff,
int width);
1413 int hexapi find_lvar(
const vdloc_t &location,
int width,
int defblk=-1)
const;
1428#define LVINF_KEEP 0x0001
1434#define LVINF_FORCE 0x0002
1437#define LVINF_NOPTR 0x0004
1438#define LVINF_NOMAP 0x0008
1439#define LVINF_UNUSED 0x0010
1441 lvar_saved_info_t(void) : size(BADSIZE), flags(0) {}
1442 bool has_info(
void)
const
1444 return !name.empty()
1453 return name == r.
name
1459 bool is_kept(
void)
const {
return (flags &
LVINF_KEEP) != 0; }
1460 void clear_keep(
void) { flags &= ~LVINF_KEEP; }
1462 bool is_forced_lvar(
void)
const {
return (flags &
LVINF_FORCE) != 0; }
1463 void set_forced_lvar(
void) { flags |=
LVINF_FORCE; }
1464 void clr_forced_lvar(
void) { flags &= ~LVINF_FORCE; }
1465 bool is_noptr_lvar(
void)
const {
return (flags &
LVINF_NOPTR) != 0; }
1466 void set_noptr_lvar(
void) { flags |=
LVINF_NOPTR; }
1467 void clr_noptr_lvar(
void) { flags &= ~LVINF_NOPTR; }
1468 bool is_nomap_lvar(
void)
const {
return (flags &
LVINF_NOMAP) != 0; }
1469 void set_nomap_lvar(
void) { flags |=
LVINF_NOMAP; }
1470 void clr_nomap_lvar(
void) { flags &= ~LVINF_NOMAP; }
1471 bool is_unused_lvar(
void)
const {
return (flags &
LVINF_UNUSED) != 0; }
1473 void clr_unused_lvar(
void) { flags &= ~LVINF_UNUSED; }
1476typedef qvector<lvar_saved_info_t> lvar_saved_infos_t;
1500#define ULV_PRECISE_DEFEA 0x0001
1506 lvvec.swap(r.
lvvec);
1507 lmaps.swap(r.
lmaps);
1520 return lvvec.empty()
1522 && stkoff_delta == 0
1529 for ( lvar_saved_infos_t::iterator p=lvvec.begin(); p != lvvec.end(); ++p )
1531 if ( p->ll == vloc )
1590#define MLI_NAME 0x01
1591#define MLI_TYPE 0x02
1593#define MLI_SET_FLAGS 0x08
1594#define MLI_CLR_FLAGS 0x10
1609 const char *varname);
1622 const char *oldname,
1623 const char *newname)
1628 info.
name = newname;
1640 int code = ::compare(name, r.name);
1642 code = ::compare(tif, r.tif);
1646 bool empty()
const {
return name.empty() && tif.empty(); }
1650typedef std::map<ea_t, udcall_t> udcall_map_t;
1725 void hexapi cleanup(
void);
1730 bool hexapi init(
const char *decl);
1733 bool empty(
void)
const {
return udc.empty(); }
1737typedef size_t mbitmap_t;
1738const size_t bitset_width =
sizeof(mbitmap_t) * CHAR_BIT;
1739const size_t bitset_align = bitset_width - 1;
1740const size_t bitset_shift = 6;
1749 bitset_t(
void) : bitmap(
nullptr), high(0) {}
1758 std::swap(bitmap, r.bitmap);
1759 std::swap(high, r.high);
1763 bool hexapi add(
int bit);
1764 bool hexapi add(
int bit,
int width);
1766 bool hexapi sub(
int bit);
1767 bool hexapi sub(
int bit,
int width);
1769 bool hexapi cut_at(
int maxbit);
1770 void hexapi shift_down(
int shift);
1771 bool hexapi has(
int bit)
const;
1772 bool hexapi has_all(
int bit,
int width)
const;
1773 bool hexapi has_any(
int bit,
int width)
const;
1776 int (*get_bit_name)(qstring *out,
int bit,
int width,
void *ud)=
nullptr,
1777 void *ud=
nullptr)
const;
1779 bool hexapi empty(
void)
const;
1780 int hexapi count(
void)
const;
1781 int hexapi count(
int bit)
const;
1782 int hexapi last(
void)
const;
1783 void clear(
void) { high = 0; }
1784 void hexapi fill_with_ones(
int maxbit);
1785 bool hexapi fill_gaps(
int total_nbits);
1789 bool includes(
const bitset_t &ml)
const {
return ml.is_subset_of(*
this); }
1790 void extract(intvec_t &out)
const;
1792 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
1799 bool operator==(
const iterator &n)
const {
return i == n.i; }
1800 bool operator!=(
const iterator &n)
const {
return i != n.i; }
1801 int operator*(
void)
const {
return i; }
1805 iterator begin(
void)
const {
return itat(0); }
1806 iterator end(
void)
const {
return iterator(high); }
1807 int front(
void)
const {
return *begin(); }
1808 int back(
void)
const {
return *end(); }
1809 void inc(iterator &p,
int n=1)
const { p.i = goup(p.i+n); }
1811 int hexapi goup(
int reg)
const;
1814typedef qvector<bitset_t> array_of_bitsets;
1826 ivl_tpl(T _off, T _size) : off(_off), size(_size) {}
1827 bool valid()
const {
return last() >= off; }
1828 T end()
const {
return off + size; }
1829 T last()
const {
return off + size - 1; }
1831 DEFINE_MEMORY_ALLOCATION_FUNCS()
1843 friend class qvector<
ivl_t>;
1847 bool empty(
void)
const {
return size == 0; }
1848 void clear(
void) { size = 0; }
1849 void print(qstring *vout)
const;
1852 bool extend_to_cover(
const ivl_t &r)
1854 uval_t new_end = end();
1855 bool changed =
false;
1861 if ( new_end < r.end() )
1867 size = new_end - off;
1870 void intersect(
const ivl_t &r)
1872 uval_t new_off = qmax(off, r.off);
1873 uval_t new_end = end();
1874 if ( new_end > r.end() )
1876 if ( new_off < new_end )
1879 size = new_end - off;
1888 bool overlap(
const ivl_t &ivl)
const
1890 return interval::overlap(off, size, ivl.off, ivl.size);
1893 bool includes(
const ivl_t &ivl)
const
1895 return interval::includes(off, size, ivl.off, ivl.size);
1898 bool contains(uval_t off2)
const
1900 return interval::contains(off, size, off2);
1903 DECLARE_COMPARISONS(
ivl_t);
1904 static const ivl_t allmem;
1905#define ALLMEM ivl_t::allmem
1907DECLARE_TYPE_AS_MOVABLE(
ivl_t);
1915 ivl_with_name_t(): ivl(0, BADADDR), whole(
"<unnamed inteval>"), part(
nullptr) {}
1916 DEFINE_MEMORY_ALLOCATION_FUNCS()
1920template <
class Ivl,
class T>
1924 typedef qvector<Ivl> bag_t;
1928 bool verify(
void)
const;
1931 static bool ivl_all_values(
const Ivl &ivl) {
return ivl.off == 0 && ivl.size == 0; }
1935 ivlset_tpl(
const Ivl &ivl) {
if ( ivl.valid() ) bag.push_back(ivl); }
1936 DEFINE_MEMORY_ALLOCATION_FUNCS()
1938 void swap(
ivlset_tpl &r) { bag.swap(r.bag); }
1939 const Ivl &getivl(
int idx)
const {
return bag[idx]; }
1940 const Ivl &lastivl(
void)
const {
return bag.back(); }
1941 size_t nivls(
void)
const {
return bag.size(); }
1942 bool empty(
void)
const {
return bag.empty(); }
1943 void clear(
void) { bag.clear(); }
1944 void qclear(
void) { bag.qclear(); }
1945 bool all_values()
const {
return nivls() == 1 && ivl_all_values(bag[0]); }
1946 void set_all_values() { clear(); bag.push_back(Ivl(0, 0)); }
1947 bool single_value()
const {
return nivls() == 1 && bag[0].size == 1; }
1948 bool single_value(T v)
const {
return single_value() && bag[0].off == v; }
1950 bool operator==(
const Ivl &v)
const {
return nivls() == 1 && bag[0] == v; }
1951 bool operator!=(
const Ivl &v)
const {
return !(*
this == v); }
1953 typedef typename bag_t::iterator iterator;
1954 typedef typename bag_t::const_iterator const_iterator;
1955 const_iterator begin(
void)
const {
return bag.begin(); }
1956 const_iterator end(
void)
const {
return bag.end(); }
1957 iterator begin(
void) {
return bag.begin(); }
1958 iterator end(
void) {
return bag.end(); }
1973 bool add(ea_t ea, asize_t size) {
return add(
ivl_t(ea, size)); }
1977 bool sub(ea_t ea, asize_t size) {
return sub(
ivl_t(ea, size)); }
1979 bool hexapi has_common(
const ivl_t &ivl,
bool strict=
false)
const;
1980 void hexapi print(qstring *vout)
const;
1982 asize_t
hexapi count(
void)
const;
1984 bool hexapi contains(uval_t off)
const;
1992typedef qvector<ivlset_t> array_of_ivlsets;
2005 void hexapi print(qstring *vout)
const;
2008DECLARE_TYPE_AS_MOVABLE(
rlist_t);
2021 void swap(
mlist_t &r) { reg.swap(r.reg); mem.swap(r.mem); }
2022 bool hexapi addmem(ea_t ea, asize_t size);
2023 bool add(
mreg_t r,
int size) {
return add(
mlist_t(r, size)); }
2024 bool add(
const rlist_t &r) {
return reg.add(r); }
2025 bool add(
const ivl_t &ivl) {
return add(
mlist_t(ivl)); }
2026 bool add(
const mlist_t &lst) {
return reg.add(lst.reg) | mem.add(lst.mem); }
2027 bool sub(
mreg_t r,
int size) {
return sub(
mlist_t(r, size)); }
2028 bool sub(
const ivl_t &ivl) {
return sub(
mlist_t(ivl)); }
2029 bool sub(
const mlist_t &lst) {
return reg.sub(lst.reg) | mem.sub(lst.mem); }
2030 asize_t count(
void)
const {
return reg.count() + mem.count(); }
2031 void hexapi print(qstring *vout)
const;
2033 bool empty(
void)
const {
return reg.empty() && mem.empty(); }
2034 void clear(
void) { reg.clear(); mem.clear(); }
2035 bool has(
mreg_t r)
const {
return reg.has(r); }
2036 bool has_all(
mreg_t r,
int size)
const {
return reg.has_all(r, size); }
2037 bool has_any(
mreg_t r,
int size)
const {
return reg.has_any(r, size); }
2038 bool has_memory(
void)
const {
return !mem.empty(); }
2039 bool has_allmem(
void)
const {
return mem == ALLMEM; }
2040 bool has_common(
const mlist_t &lst)
const {
return reg.has_common(lst.reg) || mem.has_common(lst.mem); }
2041 bool includes(
const mlist_t &lst)
const {
return reg.includes(lst.reg) && mem.includes(lst.mem); }
2042 bool intersect(
const mlist_t &lst) {
return reg.intersect(lst.reg) | mem.intersect(lst.mem); }
2043 bool is_subset_of(
const mlist_t &lst)
const {
return lst.includes(*
this); }
2046 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2048DECLARE_TYPE_AS_MOVABLE(
mlist_t);
2049typedef qvector<mlist_t> mlistvec_t;
2050DECLARE_TYPE_AS_MOVABLE(mlistvec_t);
2155 bool colored_gdl_edges;
2157 friend class iterator;
2158 virtual int goup(
int node)
const newapi;
2179 mba_t *_mba=
nullptr,
2182 : mba(_mba), blk(_blk), topins(_topins), curins(
nullptr) {}
2183 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2184 bool really_alloc(
void)
const;
2193 mba_t *_mba=
nullptr,
2197 virtual int idaapi visit_minsn(
void) = 0;
2206 mba_t *_mba=
nullptr,
2213 virtual int idaapi visit_mop(
mop_t *op,
const tinfo_t *type,
bool is_target) = 0;
2220 virtual int idaapi visit_scif_mop(
const mop_t &r,
int off) = 0;
2231 mlist_mop_visitor_t(
void): topins(
nullptr), curins(
nullptr), changed(
false), list(
nullptr) {}
2232 virtual int idaapi visit_mop(
mop_t *op) = 0;
2282 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2285 std::swap(off, r.off);
2286 std::swap(idx, r.idx);
2307 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2310 std::swap(off, r.off);
2315 member_t *
hexapi get_stkvar(uval_t *p_off=
nullptr)
const;
2338 scif_t(
mba_t *_mba, tinfo_t *tif, qstring *n=
nullptr) : mba(_mba)
2358 mnumber_t(uint64 v, ea_t _ea=BADADDR,
int n=0)
2360 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2363 if ( value < r.value )
2365 if ( value > r.value )
2370 void update_value(uint64 val64)
2384 operator uint16 *(void) {
return fnum.w; }
2385 operator const uint16 *(void)
const {
return fnum.w; }
2386 void hexapi print(qstring *vout)
const;
2388 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2391 return ecmp(fnum, r.fnum);
2398#define SHINS_NUMADDR 0x01
2399#define SHINS_VALNUM 0x02
2400#define SHINS_SHORT 0x04
2401#define SHINS_LDXEA 0x08
2434#define OPROP_IMPDONE 0x01
2435#define OPROP_UDT 0x02
2436#define OPROP_FLOAT 0x04
2437#define OPROP_CCFLAGS 0x08
2439#define OPROP_UDEFVAL 0x10
2440#define OPROP_LOWADDR 0x20
2476 void set_udt(
void) { oprops |=
OPROP_UDT; }
2479 bool is_impptr_done(
void)
const {
return (oprops &
OPROP_IMPDONE) != 0; }
2480 bool is_udt(
void)
const {
return (oprops &
OPROP_UDT) != 0; }
2481 bool probably_floating(
void)
const {
return (oprops &
OPROP_FLOAT) != 0; }
2482 bool is_undef_val(
void)
const {
return (oprops &
OPROP_UDEFVAL) != 0; }
2483 bool is_lowaddr(
void)
const {
return (oprops &
OPROP_LOWADDR) != 0; }
2484 bool is_ccflags(
void)
const
2489 bool is_pcval(
void)
const
2494 mop_t(
void) { zero(); }
2496 mop_t(
mreg_t _r,
int _s) : t(
mop_r), oprops(0), valnum(0), size(_s), r(_r) {}
2497 mop_t &operator=(
const mop_t &rop) {
return assign(rop); }
2503 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2504 void zero(
void) { t =
mop_z; oprops = 0; valnum = 0; size =
NOSIZE; nnn =
nullptr; }
2507 void erase_but_keep_size(
void) {
int s2 = size; erase(); size = s2; }
2552 void hexapi create_from_scattered_vdloc(
2570 void hexapi make_number(uint64 _value,
int _size, ea_t _ea=BADADDR,
int opnum=0);
2577 bool hexapi make_fpnum(
const void *bytes,
size_t _size);
2588 void _make_reg(
mreg_t reg,
int _size)
2596 void make_reg(
mreg_t reg,
int _size) { erase(); _make_reg(reg, _size); }
2632 void make_stkvar(
mba_t *mba, sval_t off) { erase(); _make_stkvar(mba, off); }
2638 void hexapi make_reg_pair(
int loreg,
int hireg,
int halfsize);
2645 void _make_insn(
minsn_t *ins);
2664 void hexapi make_helper(
const char *name);
2670 cstr = ::qstrdup(str);
2672 void _make_strlit(qstring *str)
2675 cstr = str->extract();
2709 bool empty(
void)
const {
return t ==
mop_z; }
2720 bool is_cc(
void)
const {
return is_reg() && r >= mr_cf && r < mr_first; }
2724 bool is_bit_reg(
void)
const {
return is_reg() && is_bit_reg(r); }
2732 bool is_glbaddr()
const;
2734 bool is_glbaddr(ea_t ea)
const;
2736 bool is_stkaddr()
const;
2740 bool is_insn(mcode_t code)
const;
2743 bool has_side_effects(
bool include_ldx_and_divs=
false)
const;
2745 bool hexapi may_use_aliased_memory(
void)
const;
2750 bool hexapi is01(
void)
const;
2757 bool hexapi is_sign_extended_from(
int nbytes)
const;
2764 bool hexapi is_zero_extended_from(
int nbytes)
const;
2770 return is_sign_extended_from(nbytes);
2772 return is_zero_extended_from(nbytes);
2782 bool hexapi equal_mops(
const mop_t &rop,
int eqflags)
const;
2783 bool operator==(
const mop_t &rop)
const {
return equal_mops(rop, 0); }
2784 bool operator!=(
const mop_t &rop)
const {
return !equal_mops(rop, 0); }
2788 bool operator <(
const mop_t &rop)
const {
return lexcompare(rop) < 0; }
2789 friend int lexcompare(
const mop_t &a,
const mop_t &b) {
return a.lexcompare(b); }
2802 const tinfo_t *type=
nullptr,
2803 bool is_target=
false);
2818 uint64
value(
bool is_signed)
const {
return extend_sign(nnn->value, size, is_signed); }
2819 int64 signed_value(
void)
const {
return value(
true); }
2820 uint64 unsigned_value(
void)
const {
return value(
false); }
2821 void update_numop_value(uint64 val)
2823 nnn->update_value(extend_sign(val, size,
false));
2830 bool hexapi is_constant(uint64 *out=
nullptr,
bool is_signed=
true)
const;
2832 bool is_equal_to(uint64 n,
bool is_signed=
true)
const
2835 return is_constant(&v, is_signed) && v == n;
2837 bool is_zero(
void)
const {
return is_equal_to(0,
false); }
2838 bool is_one(
void)
const {
return is_equal_to(1,
false); }
2839 bool is_positive_constant(
void)
const
2842 return is_constant(&v,
true) && int64(v) > 0;
2844 bool is_negative_constant(
void)
const
2847 return is_constant(&v,
true) && int64(v) < 0;
2856 member_t *
get_stkvar(uval_t *p_off)
const {
return s->get_stkvar(p_off); }
2863 bool hexapi get_stkoff(sval_t *p_off)
const;
2872 const minsn_t *get_insn(mcode_t code)
const;
2873 minsn_t *get_insn(mcode_t code);
2882 bool hexapi make_low_half(
int width);
2888 bool hexapi make_high_half(
int width);
2894 bool hexapi make_first_half(
int width);
2900 bool hexapi make_second_half(
int width);
2911 bool hexapi shift_mop(
int offset);
2937 bool hexapi preserve_side_effects(
2940 bool *moved_calls=
nullptr);
2948 void hexapi apply_ld_mcode(mcode_t mcode, ea_t ea,
int newsize);
2949 void apply_xdu(ea_t ea,
int newsize) { apply_ld_mcode(m_xdu, ea, newsize); }
2950 void apply_xds(ea_t ea,
int newsize) { apply_ld_mcode(m_xds, ea, newsize); }
2952DECLARE_TYPE_AS_MOVABLE(
mop_t);
2960 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2972 :
mop_t(ra), insize(ra.insize), outsize(ra.outsize) {}
2974 :
mop_t(ra), insize(isz), outsize(osz) {}
2979 insize = rop.insize;
2980 outsize = rop.outsize;
2985 int code = mop_t::lexcompare(ra);
2986 return code != 0 ? code
2987 : insize != ra.insize ? (insize-ra.insize)
2988 : outsize != ra.outsize ? (outsize-ra.outsize)
3006 void copy_mop(
const mop_t &op) { *(
mop_t *)
this = op; }
3009 void hexapi set_regarg(
mreg_t mr,
int sz,
const tinfo_t &tif);
3010 void set_regarg(
mreg_t mr,
const tinfo_t &tif)
3012 set_regarg(mr, tif.get_size(), tif);
3014 void set_regarg(
mreg_t mr,
char dt, type_sign_t sign = type_unsigned)
3016 int sz = get_dtype_size(dt);
3019 void make_int(
int val, ea_t val_ea,
int opno = 0)
3021 type = tinfo_t(BTF_INT);
3022 make_number(val, inf_get_cc_size_i(), val_ea, opno);
3024 void make_uint(
int val, ea_t val_ea,
int opno = 0)
3026 type = tinfo_t(BTF_UINT);
3027 make_number(val, inf_get_cc_size_i(), val_ea, opno);
3031typedef qvector<mcallarg_t> mcallargs_t;
3083#define FUNC_NAME_MEMCPY "memcpy"
3084#define FUNC_NAME_WMEMCPY "wmemcpy"
3085#define FUNC_NAME_MEMSET "memset"
3086#define FUNC_NAME_WMEMSET "wmemset"
3087#define FUNC_NAME_MEMSET32 "memset32"
3088#define FUNC_NAME_MEMSET64 "memset64"
3089#define FUNC_NAME_STRCPY "strcpy"
3090#define FUNC_NAME_WCSCPY "wcscpy"
3091#define FUNC_NAME_STRLEN "strlen"
3092#define FUNC_NAME_WCSLEN "wcslen"
3093#define FUNC_NAME_STRCAT "strcat"
3094#define FUNC_NAME_WCSCAT "wcscat"
3095#define FUNC_NAME_TAIL "tail"
3096#define FUNC_NAME_VA_ARG "va_arg"
3097#define FUNC_NAME_EMPTY "$empty"
3098#define FUNC_NAME_PRESENT "$present"
3099#define FUNC_NAME_CONTAINING_RECORD "CONTAINING_RECORD"
3105#define MAX_FUNC_ARGS 64
3135#define FCI_PROP 0x001
3136#define FCI_DEAD 0x002
3137#define FCI_FINAL 0x004
3138#define FCI_NORET 0x008
3139#define FCI_PURE 0x010
3140#define FCI_NOSIDE 0x020
3141#define FCI_SPLOK 0x040
3146#define FCI_HASCALL 0x080
3149#define FCI_HASFMT 0x100
3151#define FCI_EXPLOCS 0x400
3157 : callee(_callee), solid_args(_sargs), call_spd(0), stkargs_top(0),
3158 cc(CM_CC_INVALID), flags(0), role(
ROLE_UNK) {}
3159 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
3163 bool is_vararg(
void)
const {
return is_vararg_cc(cc); }
3177 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
3178 bool empty(
void)
const {
return targets.empty(); }
3179 size_t size(
void)
const {
return targets.size(); }
3180 void resize(
int s) { values.resize(s); targets.resize(s); }
3181 void hexapi print(qstring *vout)
const;
3193 voff_t(
mopt_t _type, sval_t _off) : off(_off), type(_type) {}
3200 void set(
mopt_t _type, sval_t _off) { type = _type; off = _off; }
3201 void set_stkoff(sval_t stkoff) { set(
mop_S, stkoff); }
3203 void undef() { set(
mop_z, -1); }
3205 bool defined()
const {
return type !=
mop_z; }
3206 bool is_reg()
const {
return type ==
mop_r; }
3207 bool is_stkoff()
const {
return type ==
mop_S; }
3208 mreg_t get_reg()
const { QASSERT(51892, is_reg());
return off; }
3209 sval_t get_stkoff()
const { QASSERT(51893, is_stkoff());
return off; }
3211 void inc(sval_t delta) { off += delta; }
3212 voff_t add(
int width)
const {
return voff_t(type, off+width); }
3213 sval_t diff(
const voff_t &r)
const { QASSERT(51894, type == r.
type);
return off - r.
off; }
3215 DECLARE_COMPARISONS(
voff_t)
3217 int code = ::compare(type, r.type);
3218 return code != 0 ? code : ::compare(off, r.off);
3229 :
voff_t(_type, _off), size(_size) {}
3234 void set(
mopt_t _type, sval_t _off,
int _size = 0)
3235 { voff_t::set(_type, _off); size = _size; }
3236 void set(
const voff_t &voff,
int _size)
3237 { set(voff.
type, voff.
off, _size); }
3238 void set_stkoff(sval_t stkoff,
int sz = 0) { set(
mop_S, stkoff, sz); }
3239 void set_reg (
mreg_t mreg,
int sz = 0) { set(
mop_r, mreg, sz); }
3252 return type == r.
type
3253 && interval::overlap(off, size, r.
off, r.
size);
3258 return type == r.
type
3259 && interval::includes(off, size, r.
off, r.
size);
3265 return type == voff2.
type
3266 && interval::contains(off, size, voff2.
off);
3270 DECLARE_COMPARISONS(
vivl_t)
3272 int code = voff_t::compare(r);
3275 bool operator==(
const mop_t &mop)
const
3277 return type == mop.
t && off == (mop.
is_reg() ? mop.r : mop.s->
off);
3279 void hexapi print(qstring *vout)
const;
3298#define CHF_INITED 0x01
3299#define CHF_REPLACED 0x02
3300#define CHF_OVER 0x04
3301#define CHF_FAKE 0x08
3302#define CHF_PASSTHRU 0x10
3303#define CHF_TERM 0x20
3305 chain_t() : width(0), varnum(-1), flags(CHF_INITED) {}
3307 : k(t, off), width(w), varnum(v), flags(
CHF_INITED) {}
3309 : k(_k), width(w), varnum(-1), flags(
CHF_INITED) {}
3310 void set_value(
const chain_t &r)
3311 { width = r.
width; varnum = r.
varnum; flags = r.
flags; *(intvec_t *)
this = (intvec_t &)r; }
3312 const voff_t &key()
const {
return k; }
3313 bool is_inited(
void)
const {
return (flags &
CHF_INITED) != 0; }
3314 bool is_reg(
void)
const {
return k.is_reg(); }
3315 bool is_stkoff(
void)
const {
return k.is_stkoff(); }
3316 bool is_replaced(
void)
const {
return (flags &
CHF_REPLACED) != 0; }
3317 bool is_overlapped(
void)
const {
return (flags &
CHF_OVER) != 0; }
3318 bool is_fake(
void)
const {
return (flags &
CHF_FAKE) != 0; }
3319 bool is_passreg(
void)
const {
return (flags &
CHF_PASSTHRU) != 0; }
3320 bool is_term(
void)
const {
return (flags &
CHF_TERM) != 0; }
3321 void set_inited(
bool b) { setflag(flags,
CHF_INITED, b); }
3322 void set_replaced(
bool b) { setflag(flags,
CHF_REPLACED, b); }
3323 void set_overlapped(
bool b) { setflag(flags,
CHF_OVER, b); }
3324 void set_term(
bool b) { setflag(flags,
CHF_TERM, b); }
3325 mreg_t get_reg()
const {
return k.get_reg(); }
3326 sval_t get_stkoff()
const {
return k.get_stkoff(); }
3327 bool overlap(
const chain_t &r)
const
3329 bool includes(
const chain_t &r)
const
3331 const voff_t endoff()
const {
return k.add(width); }
3333 bool operator<(
const chain_t &r)
const {
return key() < r.key(); }
3335 void hexapi print(qstring *vout)
const;
3339 void clear_varnum(
void) { varnum = -1; set_replaced(
false); }
3344#define SIZEOF_BLOCK_CHAINS 24
3345#elif defined(__MAC__)
3346#define SIZEOF_BLOCK_CHAINS 32
3348#define SIZEOF_BLOCK_CHAINS 56
3358 size_t body[SIZEOF_BLOCK_CHAINS/
sizeof(size_t)];
3374 chain_t *get_stk_chain(sval_t off,
int width=1)
3381 {
return get_chain(
chain_t(k, width)); }
3391 void hexapi print(qstring *vout)
const;
3393 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
3401 virtual int idaapi visit_chain(
int nblock,
chain_t &ch) = 0;
3420#define GCA_EMPTY 0x01
3421#define GCA_SPEC 0x02
3422#define GCA_ALLOC 0x04
3423#define GCA_NALLOC 0x08
3424#define GCA_OFIRST 0x10
3425#define GCA_OLAST 0x20
3435 void hexapi release(
void);
3438 qvector<block_chains_t>::swap(r);
3439 std::swap(lock, r.lock);
3446 void hexapi init(ea_t _ea);
3461#define IPROP_OPTIONAL 0x0001
3462#define IPROP_PERSIST 0x0002
3463#define IPROP_WILDMATCH 0x0004
3466#define IPROP_CLNPOP 0x0008
3468#define IPROP_FPINSN 0x0010
3469#define IPROP_FARCALL 0x0020
3470#define IPROP_TAILCALL 0x0040
3471#define IPROP_ASSERT 0x0080
3476#define IPROP_SPLIT 0x0700
3477#define IPROP_SPLIT1 0x0100
3478#define IPROP_SPLIT2 0x0200
3479#define IPROP_SPLIT4 0x0300
3480#define IPROP_SPLIT8 0x0400
3481#define IPROP_COMBINED 0x0800
3482#define IPROP_EXTSTX 0x1000
3483#define IPROP_IGNLOWSRC 0x2000
3486#define IPROP_INV_JX 0x4000
3487#define IPROP_WAS_NORET 0x8000
3488#define IPROP_MULTI_MOV 0x10000
3492#define IPROP_DONT_PROP 0x20000
3493#define IPROP_DONT_COMB 0x40000
3494#define IPROP_MBARRIER 0x80000
3498 bool is_optional(
void)
const {
return (iprops &
IPROP_OPTIONAL) != 0; }
3499 bool is_combined(
void)
const {
return (iprops &
IPROP_COMBINED) != 0; }
3500 bool is_farcall(
void)
const {
return (iprops &
IPROP_FARCALL) != 0; }
3501 bool is_cleaning_pop(
void)
const {
return (iprops &
IPROP_CLNPOP) != 0; }
3502 bool is_extstx(
void)
const {
return (iprops &
IPROP_EXTSTX) != 0; }
3503 bool is_tailcall(
void)
const {
return (iprops &
IPROP_TAILCALL) != 0; }
3504 bool is_fpinsn(
void)
const {
return (iprops &
IPROP_FPINSN) != 0; }
3505 bool is_assert(
void)
const {
return (iprops &
IPROP_ASSERT) != 0; }
3506 bool is_persistent(
void)
const {
return (iprops &
IPROP_PERSIST) != 0; }
3507 bool is_wild_match(
void)
const {
return (iprops &
IPROP_WILDMATCH) != 0; }
3508 bool is_propagatable(
void)
const {
return (iprops &
IPROP_DONT_PROP) == 0; }
3509 bool is_ignlowsrc(
void)
const {
return (iprops &
IPROP_IGNLOWSRC) != 0; }
3510 bool is_inverted_jx(
void)
const {
return (iprops &
IPROP_INV_JX) != 0; }
3511 bool was_noret_icall(
void)
const {
return (iprops &
IPROP_WAS_NORET) != 0; }
3512 bool is_multimov(
void)
const {
return (iprops &
IPROP_MULTI_MOV) != 0; }
3513 bool is_combinable(
void)
const {
return (iprops &
IPROP_DONT_COMB) == 0; }
3514 bool was_split(
void)
const {
return (iprops &
IPROP_SPLIT) != 0; }
3515 bool is_mbarrier(
void)
const {
return (iprops &
IPROP_MBARRIER) != 0; }
3518 void hexapi set_combined(
void);
3519 void clr_combined(
void) { iprops &= ~IPROP_COMBINED; }
3521 void set_cleaning_pop(
void) { iprops |=
IPROP_CLNPOP; }
3524 void clr_tailcall(
void) { iprops &= ~IPROP_TAILCALL; }
3526 void clr_fpinsn(
void) { iprops &= ~IPROP_FPINSN; }
3528 void clr_assert(
void) { iprops &= ~IPROP_ASSERT; }
3533 void clr_ignlowsrc(
void) { iprops &= ~IPROP_IGNLOWSRC; }
3536 void clr_noret_icall(
void) { iprops &= ~IPROP_WAS_NORET; }
3538 void clr_multimov(
void) { iprops &= ~IPROP_MULTI_MOV; }
3539 void set_combinable(
void) { iprops &= ~IPROP_DONT_COMB; }
3542 void set_split_size(
int s)
3544 iprops &= ~IPROP_SPLIT;
3550 int get_split_size(
void)
const
3553 return cnt == 0 ? 0 : 1 << (cnt-1);
3559 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
3577 void hexapi setaddr(ea_t new_ea);
3586 int optimize_solo(
int optflags=0) {
return optimize_subtree(
nullptr,
nullptr,
nullptr,
nullptr, optflags); }
3589#define OPTI_ADDREXPRS 0x0001
3590#define OPTI_MINSTKREF 0x0002
3591#define OPTI_COMBINSNS 0x0004
3592#define OPTI_NO_LDXOPT 0x0008
3599 int hexapi optimize_subtree(
3603 ea_t *converted_call,
3622 void hexapi _make_nop(
void);
3628 bool hexapi equal_insns(
const minsn_t &m,
int eqflags)
const;
3631#define EQ_IGNSIZE 0x0001
3632#define EQ_IGNCODE 0x0002
3633#define EQ_CMPDEST 0x0004
3634#define EQ_OPTINSN 0x0008
3639 bool operator <(
const minsn_t &ri)
const {
return lexcompare(ri) < 0; }
3648 bool hexapi is_noret_call(
int flags=0);
3649#define NORET_IGNORE_WAS_NORET_ICALL 0x01
3650#define NORET_FORBID_ANALYSIS 0x02
3663 bool hexapi is_helper(
const char *name)
const;
3671 bool contains_call(
bool with_helpers=
false)
const {
return find_call(with_helpers) !=
nullptr; }
3677 bool hexapi has_side_effects(
bool include_ldx_and_divs=
false)
const;
3681 bool is_memcpy(
void)
const {
return get_role() ==
ROLE_MEMCPY; }
3682 bool is_memset(
void)
const {
return get_role() ==
ROLE_MEMSET; }
3683 bool is_alloca(
void)
const {
return get_role() ==
ROLE_ALLOCA; }
3684 bool is_bswap (
void)
const {
return get_role() ==
ROLE_BSWAP; }
3685 bool is_readflags (
void)
const {
return get_role() ==
ROLE_READFLAGS; }
3707 minsn_t *find_ins_op(
mop_t **other, mcode_t op=m_nop) {
return CONST_CAST(
minsn_t*)((CONST_CAST(
const minsn_t*)(
this))->find_ins_op((
const mop_t**)other, op)); }
3715 mop_t *find_num_op(
mop_t **other) {
return CONST_CAST(
mop_t*)((CONST_CAST(
const minsn_t*)(
this))->find_num_op((
const mop_t**)other)); }
3717 bool is_mov(
void)
const {
return opcode == m_mov || (opcode == m_f2f && l.
size == d.
size); }
3718 bool is_like_move(
void)
const {
return is_mov() || is_mcode_xdsu(opcode) || opcode == m_low; }
3722 bool hexapi modifes_d(
void)
const;
3723 bool modifies_pair_mop(
void)
const {
return d.
t ==
mop_p && modifes_d(); }
3737 bool hexapi may_use_aliased_memory(
void)
const;
3761#define MAXRANGE bitrange_t(0, USHRT_MAX)
3780#define MBL_PRIV 0x0001
3782#define MBL_NONFAKE 0x0000
3783#define MBL_FAKE 0x0002
3784#define MBL_GOTO 0x0004
3785#define MBL_TCAL 0x0008
3786#define MBL_PUSH 0x0010
3787#define MBL_DMT64 0x0020
3788#define MBL_COMB 0x0040
3789#define MBL_PROP 0x0080
3790#define MBL_DEAD 0x0100
3791#define MBL_LIST 0x0200
3792#define MBL_INCONST 0x0400
3793#define MBL_CALL 0x0800
3794#define MBL_BACKPROP 0x1000
3795#define MBL_NORET 0x2000
3796#define MBL_DSLOT 0x4000
3797#define MBL_VALRANGES 0x8000
3798#define MBL_KEEP 0x10000
3832 void mark_lists_dirty(
void) { flags &= ~MBL_LIST; request_propagation(); }
3833 void request_propagation(
void) { flags |=
MBL_PROP; }
3834 bool needs_propagation(
void)
const {
return (flags &
MBL_PROP) != 0; }
3835 void request_demote64(
void) { flags |=
MBL_DMT64; }
3836 bool lists_dirty(
void)
const {
return (flags &
MBL_LIST) == 0; }
3838 int make_lists_ready(
void)
3840 if ( lists_ready() )
3842 return build_lists(
false);
3846 int npred(
void)
const {
return predset.size(); }
3848 int nsucc(
void)
const {
return succset.size(); }
3850 int pred(
int n)
const {
return predset[n]; }
3852 int succ(
int n)
const {
return succset[n]; }
3856 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
3857 bool empty(
void)
const {
return head ==
nullptr; }
3866 void hexapi dump(
void)
const;
3867 AS_PRINTF(2, 0) void
hexapi vdump_block(const
char *title, va_list va) const;
3868 AS_PRINTF(2, 3)
void dump_block(const
char *title, ...)
const
3871 va_start(va, title);
3872 vdump_block(title, va);
3944 int hexapi optimize_block(
void);
3950 int hexapi build_lists(
bool kill_deads);
3958 int hexapi optimize_useless_jump(
void);
3975 void hexapi append_use_list(
3979 bitrange_t mask=MAXRANGE)
const;
3988 void hexapi append_def_list(
3991 maymust_t maymust)
const;
4033 {
return find_first_use(list, i1, i2, maymust) !=
nullptr; }
4049 return CONST_CAST(
minsn_t*)(find_first_use(list,
4050 CONST_CAST(
const minsn_t*)(i1),
4066 maymust_t maymust=MAY_ACCESS)
const
4068 return find_redefinition(list, i1, i2, maymust) !=
nullptr;
4083 maymust_t maymust=MAY_ACCESS)
const;
4088 maymust_t maymust=MAY_ACCESS)
const
4090 return CONST_CAST(
minsn_t*)(find_redefinition(list,
4091 CONST_CAST(
const minsn_t*)(i1),
4125#define FD_BACKWARD 0x0000
4126#define FD_FORWARD 0x0001
4127#define FD_USE 0x0000
4128#define FD_DEF 0x0002
4129#define FD_DIRTY 0x0004
4140 return find_access(op, p_i1, i2, fdflags|
FD_DEF);
4148 return find_access(op, p_i1, i2, fdflags|
FD_USE);
4155 bool hexapi get_valranges(
4165 bool hexapi get_valranges(
4173#define VR_AT_START 0x0000
4175#define VR_AT_END 0x0001
4178#define VR_EXACT 0x0002
4190 size_t hexapi get_reginsn_qty(
void)
const;
4192 bool is_call_block(
void)
const {
return tail !=
nullptr && is_mcode_call(tail->
opcode); }
4193 bool is_unknown_call(
void)
const {
return tail !=
nullptr && tail->
is_unknown_call(); }
4194 bool is_nway(
void)
const {
return type ==
BLT_NWAY; }
4195 bool is_branch(
void)
const {
return type ==
BLT_2WAY && tail->
d.
t ==
mop_b; }
4196 bool is_simple_goto_block(
void)
const
4198 return get_reginsn_qty() == 1
4199 && tail->
opcode == m_goto
4202 bool is_simple_jcnd_block()
const
4206 && get_reginsn_qty() == 1
4207 && is_mcode_convertible_to_set(tail->
opcode);
4291 return strcmp(text.c_str(), r.text.c_str());
4295typedef qvector<hexwarn_t> hexwarns_t;
4328 func_t *pfn =
nullptr;
4332 ea_t start(
void)
const {
return (ranges.empty() ? *pfn : ranges[0]).start_ea; }
4333 bool empty(
void)
const {
return pfn ==
nullptr && ranges.empty(); }
4334 void clear(
void) { pfn =
nullptr; ranges.clear(); }
4335 bool is_snippet(
void)
const {
return !ranges.empty(); }
4336 bool hexapi range_contains(ea_t ea)
const;
4337 bool is_fragmented(
void)
const {
return ranges.empty() ? pfn->tailqty > 0 : ranges.size() > 1; }
4343 const rangevec_t *ranges =
nullptr;
4344 const range_t *rptr =
nullptr;
4346 bool set(
const rangevec_t &r);
4347 bool next_code(
void);
4348 ea_t current(
void)
const {
return cur; }
4355 func_item_iterator_t fii;
4356 bool is_snippet(
void)
const {
return rii.ranges !=
nullptr; }
4359 if ( mbr.is_snippet() )
4360 return rii.set(mbr.
ranges);
4362 return fii.set(mbr.
pfn);
4364 bool next_code(
void)
4367 return rii.next_code();
4369 return fii.next_code();
4371 ea_t current(
void)
const
4373 return is_snippet() ? rii.current() : fii.current();
4380 const range_t *rptr =
nullptr;
4381 const range_t *rend =
nullptr;
4382 bool set(
const rangevec_t &r) { rptr = r.begin(); rend = r.end();
return rptr != rend; }
4383 bool next(
void) {
return ++rptr != rend; }
4384 const range_t &chunk(
void)
const {
return *rptr; }
4391 func_tail_iterator_t fii;
4392 bool is_snippet(
void)
const {
return rii.rptr !=
nullptr; }
4395 if ( mbr.is_snippet() )
4396 return rii.set(mbr.
ranges);
4398 return fii.set(mbr.
pfn);
4407 const range_t &chunk(
void)
const
4409 return is_snippet() ? rii.chunk() : fii.chunk();
4420 DECLARE_UNCOPYABLE(
mba_t)
4426#define MBA_PRCDEFS 0x00000001
4427#define MBA_NOFUNC 0x00000002
4428#define MBA_PATTERN 0x00000004
4429#define MBA_LOADED 0x00000008
4430#define MBA_RETFP 0x00000010
4431#define MBA_SPLINFO 0x00000020
4432#define MBA_PASSREGS 0x00000040
4433#define MBA_THUNK 0x00000080
4434#define MBA_CMNSTK 0x00000100
4437#define MBA_PREOPT 0x00000200
4438#define MBA_CMBBLK 0x00000400
4439#define MBA_ASRTOK 0x00000800
4440#define MBA_CALLS 0x00001000
4441#define MBA_ASRPROP 0x00002000
4442#define MBA_SAVRST 0x00004000
4443#define MBA_RETREF 0x00008000
4444#define MBA_GLBOPT 0x00010000
4445#define MBA_LVARS0 0x00040000
4446#define MBA_LVARS1 0x00080000
4447#define MBA_DELPAIRS 0x00100000
4448#define MBA_CHVARS 0x00200000
4451#define MBA_SHORT 0x00400000
4452#define MBA_COLGDL 0x00800000
4453#define MBA_INSGDL 0x01000000
4454#define MBA_NICE 0x02000000
4455#define MBA_REFINE 0x04000000
4456#define MBA_WINGR32 0x10000000
4457#define MBA_NUMADDR 0x20000000
4458#define MBA_VALNUM 0x40000000
4460#define MBA_INITIAL_FLAGS (MBA_INSGDL|MBA_NICE|MBA_CMBBLK|MBA_REFINE\
4461 |MBA_PRCDEFS|MBA_WINGR32|MBA_VALNUM)
4463#define MBA2_LVARNAMES_OK 0x00000001
4464#define MBA2_LVARS_RENAMED 0x00000002
4465#define MBA2_OVER_CHAINS 0x00000004
4466#define MBA2_VALRNG_DONE 0x00000008
4467#define MBA2_IS_CTR 0x00000010
4468#define MBA2_IS_DTR 0x00000020
4469#define MBA2_ARGIDX_OK 0x00000040
4470#define MBA2_NO_DUP_CALLS 0x00000080
4471#define MBA2_NO_DUP_LVARS 0x00000100
4472#define MBA2_UNDEF_RETVAR 0x00000200
4473#define MBA2_ARGIDX_SORTED 0x00000400
4475#define MBA2_CODE16_BIT 0x00000800
4476#define MBA2_STACK_RETVAL 0x00001000
4478#define MBA2_DONT_VERIFY 0x80000000
4482#define MBA2_INITIAL_FLAGS (MBA2_LVARNAMES_OK|MBA2_LVARS_RENAMED)
4484#define MBA2_ALL_FLAGS 0x00001FFF
4486 bool precise_defeas(
void)
const {
return (flags &
MBA_PRCDEFS) != 0; }
4487 bool optimized(
void)
const {
return (flags &
MBA_GLBOPT) != 0; }
4488 bool short_display(
void)
const {
return (flags &
MBA_SHORT ) != 0; }
4489 bool show_reduction(
void)
const {
return (flags &
MBA_COLGDL) != 0; }
4490 bool graph_insns(
void)
const {
return (flags &
MBA_INSGDL) != 0; }
4491 bool loaded_gdl(
void)
const {
return (flags &
MBA_LOADED) != 0; }
4492 bool should_beautify(
void)
const {
return (flags &
MBA_NICE ) != 0; }
4493 bool rtype_refined(
void)
const {
return (flags &
MBA_RETREF) != 0; }
4494 bool may_refine_rettype(
void)
const {
return (flags &
MBA_REFINE) != 0; }
4495 bool use_wingraph32(
void)
const {
return (flags &
MBA_WINGR32) != 0; }
4496 bool display_numaddrs(
void)
const {
return (flags &
MBA_NUMADDR) != 0; }
4497 bool display_valnums(
void)
const {
return (flags &
MBA_VALNUM) != 0; }
4498 bool is_pattern(
void)
const {
return (flags &
MBA_PATTERN) != 0; }
4499 bool is_thunk(
void)
const {
return (flags &
MBA_THUNK) != 0; }
4500 bool saverest_done(
void)
const {
return (flags &
MBA_SAVRST) != 0; }
4501 bool callinfo_built(
void)
const {
return (flags &
MBA_CALLS) != 0; }
4502 bool really_alloc(
void)
const {
return (flags &
MBA_LVARS0) != 0; }
4503 bool lvars_allocated(
void)
const {
return (flags &
MBA_LVARS1) != 0; }
4504 bool chain_varnums_ok(
void)
const {
return (flags &
MBA_CHVARS) != 0; }
4505 bool returns_fpval(
void)
const {
return (flags &
MBA_RETFP) != 0; }
4506 bool has_passregs(
void)
const {
return (flags &
MBA_PASSREGS) != 0; }
4507 bool generated_asserts(
void)
const {
return (flags &
MBA_ASRTOK) != 0; }
4508 bool propagated_asserts(
void)
const {
return (flags &
MBA_ASRPROP) != 0; }
4509 bool deleted_pairs(
void)
const {
return (flags &
MBA_DELPAIRS) != 0; }
4510 bool common_stkvars_stkargs(
void)
const {
return (flags &
MBA_CMNSTK) != 0; }
4513 bool has_over_chains(
void)
const {
return (flags2 &
MBA2_OVER_CHAINS) != 0; }
4514 bool valranges_done(
void)
const {
return (flags2 &
MBA2_VALRNG_DONE) != 0; }
4515 bool argidx_ok(
void)
const {
return (flags2 &
MBA2_ARGIDX_OK) != 0; }
4517 bool code16_bit_removed(
void)
const {
return (flags2 &
MBA2_CODE16_BIT) != 0; }
4519 bool is_ctr(
void)
const {
return (flags2 &
MBA2_IS_CTR) != 0; }
4520 bool is_dtr(
void)
const {
return (flags2 &
MBA2_IS_DTR) != 0; }
4522 int get_mba_flags(
void)
const {
return flags; }
4523 int get_mba_flags2(
void)
const {
return flags2; }
4524 void set_mba_flags(
int f) { flags |= f; }
4525 void clr_mba_flags(
int f) { flags &= ~f; }
4526 void set_mba_flags2(
int f) { flags2 |= f; }
4527 void clr_mba_flags2(
int f) { flags2 &= ~f; }
4529 int calc_shins_flags(
void)
const
4531 int shins_flags = 0;
4532 if ( short_display() )
4534 if ( display_valnums() )
4536 if ( display_numaddrs() )
4583 sval_t stkoff_vd2ida(sval_t off)
const
4585 return off - tmpstk_size;
4588 sval_t stkoff_ida2vd(sval_t off)
const
4590 return off + tmpstk_size;
4592 sval_t argbase()
const
4594 return retsize + stacksize;
4596 static vdloc_t hexapi idaloc2vd(
const argloc_t &loc,
int width, sval_t spd);
4597 vdloc_t hexapi idaloc2vd(
const argloc_t &loc,
int width)
const;
4599 static argloc_t
hexapi vd2idaloc(
const vdloc_t &loc,
int width, sval_t spd);
4600 argloc_t
hexapi vd2idaloc(
const vdloc_t &loc,
int width)
const;
4602 bool is_stkarg(
const lvar_t &v)
const
4606 member_t *get_stkvar(sval_t vd_stkoff, uval_t *poff)
const;
4608 argloc_t get_ida_argloc(
const lvar_t &v)
const
4614 ea_t last_prolog_ea;
4615 ea_t first_epilog_ea;