231#pragma warning(disable:4062)
232#pragma warning(disable:4265)
269typedef std::set<voff_t> voff_set_t;
283typedef std::set<ea_t> easet_t;
284typedef std::set<minsn_t *> minsn_ptr_set_t;
285typedef std::set<qstring> strings_t;
286typedef qvector<minsn_t*> minsnptrs_t;
287typedef qvector<mop_t*> mopptrs_t;
288typedef qvector<mop_t> mopvec_t;
289typedef qvector<uint64> uint64vec_t;
290typedef qvector<mreg_t> mregvec_t;
291typedef qrefcnt_t<cfunc_t> cfuncptr_t;
295#define MAX_SUPPORTED_STACK_SIZE 0x100000
300#define HEXRAYS_PLACEMENT_DELETE void operator delete(void *, void *) {}
301#define HEXRAYS_MEMORY_ALLOCATION_FUNCS() \
302 void *operator new (size_t _s) { return hexrays_alloc(_s); } \
303 void *operator new[](size_t _s) { return hexrays_alloc(_s); } \
304 void *operator new(size_t , void *_v) { return _v; } \
305 void operator delete (void *_blk) { hexrays_free(_blk); } \
306 void operator delete[](void *_blk) { hexrays_free(_blk); } \
307 HEXRAYS_PLACEMENT_DELETE
309void *
hexapi hexrays_alloc(
size_t size);
310void hexapi hexrays_free(
void *ptr);
312typedef uint64 uvlr_t;
314enum { MAX_VLR_SIZE =
sizeof(uvlr_t) };
315const uvlr_t MAX_VALUE = uvlr_t(-1);
316const svlr_t MAX_SVALUE = svlr_t(uvlr_t(-1) >> 1);
317const svlr_t MIN_SVALUE = ~MAX_SVALUE;
343#define VLR_RANGE 0x03
344#define VLR_SRANGE 0x04
348#define VLR_UNION 0x07
369 char reserved[
sizeof(qvector<int>)];
377 explicit valrng_t(
int size_ = MAX_VLR_SIZE)
378 : flags(VLR_NONE), size(size_), value(0), limit(0), stride(0) {}
382 void swap(
valrng_t &r) { qswap(*
this, r); }
384 DEFINE_MEMORY_ALLOCATION_FUNCS()
386 void set_none(
void) { clear(); }
387 void set_all(
void) { clear(); flags = VLR_ALL; }
388 void set_unk(
void) { clear(); flags = VLR_UNK; }
389 void hexapi set_eq(uvlr_t v);
390 void hexapi set_cmp(cmpop_t cmp, uvlr_t _value);
399 bool hexapi reduce_size(
int new_size);
407 bool empty(
void)
const {
return flags == VLR_NONE; }
408 bool all_values(
void)
const {
return flags == VLR_ALL; }
409 bool is_unknown(
void)
const {
return flags == VLR_UNK; }
410 bool hexapi has(uvlr_t v)
const;
412 void hexapi print(qstring *vout)
const;
413 const char *
hexapi dstr(
void)
const;
415 bool hexapi cvt_to_single_value(uvlr_t *v)
const;
416 bool hexapi cvt_to_cmp(cmpop_t *cmp, uvlr_t *val,
bool strict)
const;
418 int get_size()
const {
return size; }
419 static uvlr_t max_value(
int size_)
421 return size_ == MAX_VLR_SIZE
423 : (uvlr_t(1) << (size_ * 8)) - 1;
425 static uvlr_t min_svalue(
int size_)
427 return size_ == MAX_VLR_SIZE
429 : (uvlr_t(1) << (size_ * 8 - 1));
431 static uvlr_t max_svalue(
int size_)
433 return size_ == MAX_VLR_SIZE
435 : (uvlr_t(1) << (size_ * 8 - 1)) - 1;
437 uvlr_t max_value()
const {
return max_value(size); }
438 uvlr_t min_svalue()
const {
return min_svalue(size); }
439 uvlr_t max_svalue()
const {
return max_svalue(size); }
451typedef int maymust_t;
457 MAYMUST_ACCESS_MASK = 0x01,
459 ONE_ACCESS_TYPE = 0x20,
462 INCLUDE_SPOILED_REGS = 0x40,
464 EXCLUDE_PASS_REGS = 0x80,
469 WITH_ASSERTS = 0x200,
471 EXCLUDE_VOLATILE = 0x400,
473 INCLUDE_UNUSED_SRC = 0x800,
475 INCLUDE_DEAD_RETREGS = 0x1000,
477 INCLUDE_RESTRICTED = 0x2000,
478 CALL_SPOILS_ONLY_ARGS = 0x4000;
482inline THREAD_SAFE
bool is_may_access(maymust_t maymust)
484 return (maymust & MAYMUST_ACCESS_MASK) != MUST_ACCESS;
648inline THREAD_SAFE
bool is_mcode_addsub(mcode_t mcode) {
return mcode == m_add || mcode == m_sub; }
650inline THREAD_SAFE
bool is_mcode_xdsu(mcode_t mcode) {
return mcode == m_xds || mcode == m_xdu; }
652inline THREAD_SAFE
bool is_mcode_set(mcode_t mcode) {
return mcode >= m_sets && mcode <= m_setle; }
654inline THREAD_SAFE
bool is_mcode_set1(mcode_t mcode) {
return mcode == m_sets; }
656inline THREAD_SAFE
bool is_mcode_j1(mcode_t mcode) {
return mcode == m_jcnd; }
658inline THREAD_SAFE
bool is_mcode_jcond(mcode_t mcode) {
return mcode >= m_jcnd && mcode <= m_jle; }
660inline THREAD_SAFE
bool is_mcode_convertible_to_jmp(mcode_t mcode) {
return mcode >= m_setnz && mcode <= m_setle; }
662inline THREAD_SAFE
bool is_mcode_convertible_to_set(mcode_t mcode) {
return mcode >= m_jnz && mcode <= m_jle; }
664inline THREAD_SAFE
bool is_mcode_call(mcode_t mcode) {
return mcode == m_call || mcode == m_icall; }
666inline THREAD_SAFE
bool is_mcode_fpu(mcode_t mcode) {
return mcode >= m_f2i; }
668inline THREAD_SAFE
bool is_mcode_commutative(mcode_t mcode)
670 return mcode == m_add
681inline THREAD_SAFE
bool is_mcode_shift(mcode_t mcode)
683 return mcode == m_shl
688inline THREAD_SAFE
bool is_mcode_divmod(mcode_t op)
690 return op == m_udiv || op == m_sdiv || op == m_umod || op == m_smod;
693inline THREAD_SAFE
bool has_mcode_seloff(mcode_t op)
695 return op == m_ldx || op == m_stx || op == m_icall || op == m_ijmp;
700inline THREAD_SAFE mcode_t set2jcnd(mcode_t code)
702 return mcode_t(code - m_setnz + m_jnz);
707inline THREAD_SAFE mcode_t jcnd2set(mcode_t code)
709 return mcode_t(code + m_setnz - m_jnz);
716THREAD_SAFE mcode_t
hexapi negate_mcode_relation(mcode_t code);
725THREAD_SAFE mcode_t
hexapi swap_mcode_relation(mcode_t code);
731THREAD_SAFE mcode_t
hexapi get_signed_mcode(mcode_t code);
738THREAD_SAFE mcode_t
hexapi get_unsigned_mcode(mcode_t code);
741inline THREAD_SAFE
bool is_signed_mcode(mcode_t code) {
return get_unsigned_mcode(code) != code; }
743inline THREAD_SAFE
bool is_unsigned_mcode(mcode_t code) {
return get_signed_mcode(code) != code; }
752THREAD_SAFE
bool hexapi mcode_modifies_d(mcode_t mcode);
763const int cc_count = mr_pf - mr_cf + 1;
782 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
797#define NF_NEGDONE 0x02
798#define NF_BINVDONE 0x04
799#define NF_NEGATE 0x08
800#define NF_BITNOT 0x10
844 bool has_unmutable_type()
const
848 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
869 AS_PRINTF(3, 4) virtual
int hexapi print(
int indent, const
char *format, ...);
870 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
882 virtual bool idaapi
oneliner(
void)
const newapi {
return false; }
896 AS_PRINTF(3, 4) int
hexapi print(
int indent, const
char *format, ...) override;
916 AS_PRINTF(3, 4) int
hexapi print(
int indent, const
char *format, ...) override;
958 return is_type_ptr(t) || is_type_array(t);
970 return type.is_decl_complex() && !type.is_typeref();
1042 tif.create_typedef(
nullptr, n);
1053 TS_NOELL = 0x8000000,
1054 TS_SHRINK = 0x4000000,
1055 TS_DONTREF = 0x2000000,
1056 TS_MASK = 0xE000000,
1098 int reg1(
void)
const {
return atype() == ALOC_REG2 ? argloc_t::reg1() : get_reginfo(); }
1103 void _set_reg1(
int r1) { argloc_t::_set_reg1(r1, r1>>16); }
1106 void set_reg1(
int r1) { cleanup_argloc(
this); _set_reg1(r1); }
1115 bool hexapi is_aliasable(
const mba_t *mb,
int size)
const;
1145 return location.is_stkoff() ? location.stkoff() : -1;
1148 bool is_reg1(
void)
const {
return location.is_reg1(); }
1150 bool is_reg2(
void)
const {
return location.is_reg2(); }
1162 const scattered_aloc_t &
get_scattered(
void)
const {
return location.scattered(); }
1163 scattered_aloc_t &get_scattered(
void) {
return location.scattered(); }
1165 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
1178#define CVAR_USED 0x00000001
1179#define CVAR_TYPE 0x00000002
1180#define CVAR_NAME 0x00000004
1181#define CVAR_MREG 0x00000008
1182#define CVAR_NOWD 0x00000010
1183#define CVAR_UNAME 0x00000020
1184#define CVAR_UTYPE 0x00000040
1185#define CVAR_RESULT 0x00000080
1186#define CVAR_ARG 0x00000100
1187#define CVAR_FAKE 0x00000200
1188#define CVAR_OVER 0x00000400
1189#define CVAR_FLOAT 0x00000800
1190#define CVAR_SPOILED 0x00001000
1191#define CVAR_MAPDST 0x00002000
1192#define CVAR_PARTIAL 0x00004000
1193#define CVAR_THISARG 0x00008000
1194#define CVAR_FORCED 0x00010000
1196#define CVAR_REGNAME 0x00020000
1198#define CVAR_NOPTR 0x00040000
1199#define CVAR_DUMMY 0x00080000
1201#define CVAR_NOTARG 0x00100000
1202#define CVAR_AUTOMAP 0x00200000
1203#define CVAR_BYREF 0x00400000
1204#define CVAR_INASM 0x00800000
1206#define CVAR_UNUSED 0x01000000
1208#define CVAR_SHARED 0x02000000
1223 lvar_t(
const qstring &n,
const vdloc_t &l, ea_t e,
const tinfo_t &t,
int w,
int db)
1255 bool hexapi is_promoted_arg(
void)
const;
1290 void set_used(
void) { flags |=
CVAR_USED; }
1291 void clear_used(
void) { flags &= ~CVAR_USED; }
1292 void set_typed(
void) { flags |=
CVAR_TYPE; clr_noptr_var(); }
1293 void set_non_typed(
void) { flags &= ~CVAR_TYPE; }
1297 void clr_user_type(
void) { flags &= ~CVAR_UTYPE; }
1298 void clr_user_name(
void) { flags &= ~CVAR_UNAME; }
1299 void set_mreg_done(
void) { flags |=
CVAR_MREG; }
1300 void clr_mreg_done(
void) { flags &= ~CVAR_MREG; }
1301 void set_unknown_width(
void) { flags |=
CVAR_NOWD; }
1302 void clr_unknown_width(
void) { flags &= ~CVAR_NOWD; }
1303 void set_arg_var(
void) { flags |=
CVAR_ARG; }
1305 void set_fake_var(
void) { flags |=
CVAR_FAKE; }
1306 void clr_fake_var(
void) { flags &= ~CVAR_FAKE; }
1307 void set_overlapped_var(
void) { flags |=
CVAR_OVER; }
1308 void clr_overlapped_var(
void) { flags &= ~CVAR_OVER; }
1309 void set_floating_var(
void) { flags |=
CVAR_FLOAT; }
1310 void clr_floating_var(
void) { flags &= ~CVAR_FLOAT; }
1312 void clr_spoiled_var(
void) { flags &= ~CVAR_SPOILED; }
1313 void set_mapdst_var(
void) { flags |=
CVAR_MAPDST; }
1314 void clr_mapdst_var(
void) { flags &= ~CVAR_MAPDST; }
1315 void set_partialy_typed(
void) { flags |=
CVAR_PARTIAL; }
1316 void clr_partialy_typed(
void) { flags &= ~CVAR_PARTIAL; }
1317 void set_noptr_var(
void) { flags |=
CVAR_NOPTR; }
1318 void clr_noptr_var(
void) { flags &= ~CVAR_NOPTR; }
1320 void clr_thisarg(
void) { flags &= ~CVAR_THISARG; }
1321 void set_forced_var(
void) { flags |=
CVAR_FORCED; }
1322 void clr_forced_var(
void) { flags &= ~CVAR_FORCED; }
1323 void set_dummy_arg(
void) { flags |=
CVAR_DUMMY; }
1324 void clr_dummy_arg(
void) { flags &= ~CVAR_DUMMY; }
1325 void set_notarg(
void) { clr_arg_var(); flags |=
CVAR_NOTARG; }
1326 void clr_notarg(
void) { flags &= ~CVAR_NOTARG; }
1328 void clr_automapped(
void) { flags &= ~CVAR_AUTOMAP; }
1329 void set_used_byref(
void) { flags |=
CVAR_BYREF; }
1330 void clr_used_byref(
void) { flags &= ~CVAR_BYREF; }
1331 void set_decl_unused(
void) { flags |=
CVAR_UNUSED; }
1332 void clr_decl_unused(
void) { flags &= ~CVAR_UNUSED; }
1334 void clr_shared(
void) { flags &= ~CVAR_SHARED; }
1347 const tinfo_t &
type(
void)
const {
return tif; }
1348 tinfo_t &type(
void) {
return tif; }
1352 bool hexapi accepts_type(
const tinfo_t &t,
bool may_change_thisarg=
false);
1363 bool hexapi set_lvar_type(
const tinfo_t &t,
bool may_fail=
false);
1378 bool hexapi set_width(
int w,
int svw_flags=0);
1380#define SVW_FLOAT 0x01
1381#define SVW_SOFT 0x02
1388 void hexapi append_list(
const mba_t *mba,
mlist_t *lst,
bool pad_if_scattered=
false)
const;
1395 return location.is_aliasable(mba, width);
1399DECLARE_TYPE_AS_MOVABLE(
lvar_t);
1415 int hexapi find_stkvar(sval_t spoff,
int width);
1429 int hexapi find_lvar(
const vdloc_t &location,
int width,
int defblk=-1)
const;
1444#define LVINF_KEEP 0x0001
1450#define LVINF_FORCE 0x0002
1453#define LVINF_NOPTR 0x0004
1454#define LVINF_NOMAP 0x0008
1455#define LVINF_UNUSED 0x0010
1457 lvar_saved_info_t(void) : size(BADSIZE), flags(0) {}
1458 bool has_info(
void)
const
1460 return !name.empty()
1469 return name == r.
name
1475 bool is_kept(
void)
const {
return (flags &
LVINF_KEEP) != 0; }
1476 void clear_keep(
void) { flags &= ~LVINF_KEEP; }
1478 bool is_forced_lvar(
void)
const {
return (flags &
LVINF_FORCE) != 0; }
1479 void set_forced_lvar(
void) { flags |=
LVINF_FORCE; }
1480 void clr_forced_lvar(
void) { flags &= ~LVINF_FORCE; }
1481 bool is_noptr_lvar(
void)
const {
return (flags &
LVINF_NOPTR) != 0; }
1482 void set_noptr_lvar(
void) { flags |=
LVINF_NOPTR; }
1483 void clr_noptr_lvar(
void) { flags &= ~LVINF_NOPTR; }
1484 bool is_nomap_lvar(
void)
const {
return (flags &
LVINF_NOMAP) != 0; }
1485 void set_nomap_lvar(
void) { flags |=
LVINF_NOMAP; }
1486 void clr_nomap_lvar(
void) { flags &= ~LVINF_NOMAP; }
1487 bool is_unused_lvar(
void)
const {
return (flags &
LVINF_UNUSED) != 0; }
1489 void clr_unused_lvar(
void) { flags &= ~LVINF_UNUSED; }
1492typedef qvector<lvar_saved_info_t> lvar_saved_infos_t;
1516#define ULV_PRECISE_DEFEA 0x0001
1522 lvvec.swap(r.
lvvec);
1523 lmaps.swap(r.
lmaps);
1536 return lvvec.empty()
1538 && stkoff_delta == 0
1545 for ( lvar_saved_infos_t::iterator p=lvvec.begin(); p != lvvec.end(); ++p )
1547 if ( p->ll == vloc )
1606#define MLI_NAME 0x01
1607#define MLI_TYPE 0x02
1609#define MLI_SET_FLAGS 0x08
1610#define MLI_CLR_FLAGS 0x10
1625 const char *varname);
1638 const char *oldname,
1639 const char *newname)
1644 info.
name = newname;
1656 int code = ::compare(name, r.name);
1658 code = ::compare(tif, r.tif);
1662 bool empty()
const {
return name.empty() && tif.empty(); }
1666typedef std::map<ea_t, udcall_t> udcall_map_t;
1741 void hexapi cleanup(
void);
1746 bool hexapi init(
const char *decl);
1749 bool empty(
void)
const {
return udc.empty(); }
1753typedef size_t mbitmap_t;
1754const size_t bitset_width =
sizeof(mbitmap_t) * CHAR_BIT;
1755const size_t bitset_align = bitset_width - 1;
1756const size_t bitset_shift = 6;
1765 bitset_t(
void) : bitmap(
nullptr), high(0) {}
1774 std::swap(bitmap, r.bitmap);
1775 std::swap(high, r.high);
1779 bool hexapi add(
int bit);
1780 bool hexapi add(
int bit,
int width);
1782 bool hexapi sub(
int bit);
1783 bool hexapi sub(
int bit,
int width);
1785 bool hexapi cut_at(
int maxbit);
1786 void hexapi shift_down(
int shift);
1787 bool hexapi has(
int bit)
const;
1788 bool hexapi has_all(
int bit,
int width)
const;
1789 bool hexapi has_any(
int bit,
int width)
const;
1792 int (*get_bit_name)(qstring *out,
int bit,
int width,
void *ud)=
nullptr,
1793 void *ud=
nullptr)
const;
1795 bool hexapi empty(
void)
const;
1796 int hexapi count(
void)
const;
1797 int hexapi count(
int bit)
const;
1798 int hexapi last(
void)
const;
1799 void clear(
void) { high = 0; }
1800 void hexapi fill_with_ones(
int maxbit);
1801 bool hexapi fill_gaps(
int total_nbits);
1805 bool includes(
const bitset_t &ml)
const {
return ml.is_subset_of(*
this); }
1806 void extract(intvec_t &out)
const;
1808 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
1815 bool operator==(
const iterator &n)
const {
return i == n.i; }
1816 bool operator!=(
const iterator &n)
const {
return i != n.i; }
1817 int operator*(
void)
const {
return i; }
1821 iterator begin(
void)
const {
return itat(0); }
1822 iterator end(
void)
const {
return iterator(high); }
1823 int front(
void)
const {
return *begin(); }
1824 int back(
void)
const {
return *end(); }
1825 void inc(iterator &p,
int n=1)
const { p.i = goup(p.i+n); }
1827 int hexapi goup(
int reg)
const;
1830typedef qvector<bitset_t> array_of_bitsets;
1840 ivl_tpl(T _off, T _size) : off(_off), size(_size) {}
1841 bool valid()
const {
return last() >= off; }
1842 T end()
const {
return off + size; }
1843 T last()
const {
return off + size - 1; }
1845 DEFINE_MEMORY_ALLOCATION_FUNCS()
1857 bool empty(
void)
const {
return size == 0; }
1858 void clear(
void) { size = 0; }
1859 void print(qstring *vout)
const;
1862 bool extend_to_cover(
const ivl_t &r)
1864 uval_t new_end = end();
1865 bool changed =
false;
1871 if ( new_end < r.end() )
1877 size = new_end - off;
1880 void intersect(
const ivl_t &r)
1882 uval_t new_off = qmax(off, r.off);
1883 uval_t new_end = end();
1884 if ( new_end > r.end() )
1886 if ( new_off < new_end )
1889 size = new_end - off;
1898 bool overlap(
const ivl_t &ivl)
const
1900 return interval::overlap(off, size, ivl.off, ivl.size);
1903 bool includes(
const ivl_t &ivl)
const
1905 return interval::includes(off, size, ivl.off, ivl.size);
1908 bool contains(uval_t off2)
const
1910 return interval::contains(off, size, off2);
1913 DECLARE_COMPARISONS(
ivl_t);
1914 static const ivl_t allmem;
1915#define ALLMEM ivl_t::allmem
1917DECLARE_TYPE_AS_MOVABLE(
ivl_t);
1925 ivl_with_name_t(): ivl(0, BADADDR), whole(
"<unnamed inteval>"), part(
nullptr) {}
1926 DEFINE_MEMORY_ALLOCATION_FUNCS()
1930template <
class Ivl,
class T>
1934 typedef qvector<Ivl> bag_t;
1938 bool verify(
void)
const;
1941 static bool ivl_all_values(
const Ivl &ivl) {
return ivl.off == 0 && ivl.size == 0; }
1945 ivlset_tpl(
const Ivl &ivl) {
if ( ivl.valid() ) bag.push_back(ivl); }
1946 DEFINE_MEMORY_ALLOCATION_FUNCS()
1948 void swap(
ivlset_tpl &r) { bag.swap(r.bag); }
1949 const Ivl &getivl(
int idx)
const {
return bag[idx]; }
1950 const Ivl &lastivl(
void)
const {
return bag.back(); }
1951 size_t nivls(
void)
const {
return bag.size(); }
1952 bool empty(
void)
const {
return bag.empty(); }
1953 void clear(
void) { bag.clear(); }
1954 void qclear(
void) { bag.qclear(); }
1955 bool all_values()
const {
return nivls() == 1 && ivl_all_values(bag[0]); }
1956 void set_all_values() { clear(); bag.push_back(Ivl(0, 0)); }
1957 bool single_value()
const {
return nivls() == 1 && bag[0].size == 1; }
1958 bool single_value(T v)
const {
return single_value() && bag[0].off == v; }
1960 bool operator==(
const Ivl &v)
const {
return nivls() == 1 && bag[0] == v; }
1961 bool operator!=(
const Ivl &v)
const {
return !(*
this == v); }
1963 typedef typename bag_t::iterator iterator;
1964 typedef typename bag_t::const_iterator const_iterator;
1965 const_iterator begin(
void)
const {
return bag.begin(); }
1966 const_iterator end(
void)
const {
return bag.end(); }
1967 iterator begin(
void) {
return bag.begin(); }
1968 iterator end(
void) {
return bag.end(); }
1983 bool add(ea_t ea, asize_t size) {
return add(
ivl_t(ea, size)); }
1987 bool sub(ea_t ea, asize_t size) {
return sub(
ivl_t(ea, size)); }
1989 bool hexapi has_common(
const ivl_t &ivl,
bool strict=
false)
const;
1990 void hexapi print(qstring *vout)
const;
1992 asize_t
hexapi count(
void)
const;
1994 bool hexapi contains(uval_t off)
const;
2002typedef qvector<ivlset_t> array_of_ivlsets;
2016 void hexapi print(qstring *vout)
const;
2019DECLARE_TYPE_AS_MOVABLE(
rlist_t);
2032 void swap(
mlist_t &r) { reg.swap(r.reg); mem.swap(r.mem); }
2033 bool hexapi addmem(ea_t ea, asize_t size);
2034 bool add(
mreg_t r,
int size) {
return add(
mlist_t(r, size)); }
2035 bool add(
const rlist_t &r) {
return reg.add(r); }
2036 bool add(
const ivl_t &ivl) {
return add(
mlist_t(ivl)); }
2037 bool add(
const mlist_t &lst) {
return reg.add(lst.reg) | mem.add(lst.mem); }
2038 bool sub(
mreg_t r,
int size) {
return sub(
mlist_t(r, size)); }
2039 bool sub(
const ivl_t &ivl) {
return sub(
mlist_t(ivl)); }
2040 bool sub(
const mlist_t &lst) {
return reg.sub(lst.reg) | mem.sub(lst.mem); }
2041 asize_t count(
void)
const {
return reg.count() + mem.count(); }
2042 void hexapi print(qstring *vout)
const;
2044 bool empty(
void)
const {
return reg.empty() && mem.empty(); }
2045 void clear(
void) { reg.clear(); mem.clear(); }
2046 bool has(
mreg_t r)
const {
return reg.has(r); }
2047 bool has_all(
mreg_t r,
int size)
const {
return reg.has_all(r, size); }
2048 bool has_any(
mreg_t r,
int size)
const {
return reg.has_any(r, size); }
2049 bool has_memory(
void)
const {
return !mem.empty(); }
2050 bool has_allmem(
void)
const {
return mem == ALLMEM; }
2051 bool has_common(
const mlist_t &lst)
const {
return reg.has_common(lst.reg) || mem.has_common(lst.mem); }
2052 bool includes(
const mlist_t &lst)
const {
return reg.includes(lst.reg) && mem.includes(lst.mem); }
2053 bool intersect(
const mlist_t &lst) {
return reg.intersect(lst.reg) | mem.intersect(lst.mem); }
2054 bool is_subset_of(
const mlist_t &lst)
const {
return lst.includes(*
this); }
2057 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2059DECLARE_TYPE_AS_MOVABLE(
mlist_t);
2060typedef qvector<mlist_t> mlistvec_t;
2061DECLARE_TYPE_AS_MOVABLE(mlistvec_t);
2166 bool colored_gdl_edges;
2168 friend class iterator;
2169 virtual int goup(
int node)
const newapi;
2190 mba_t *_mba=
nullptr,
2193 : mba(_mba), blk(_blk), topins(_topins), curins(
nullptr) {}
2194 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2195 bool really_alloc(
void)
const;
2204 mba_t *_mba=
nullptr,
2208 virtual int idaapi visit_minsn(
void) = 0;
2217 mba_t *_mba=
nullptr,
2224 virtual int idaapi visit_mop(
mop_t *op,
const tinfo_t *type,
bool is_target) = 0;
2231 virtual int idaapi visit_scif_mop(
const mop_t &r,
int off) = 0;
2242 mlist_mop_visitor_t(
void): topins(
nullptr), curins(
nullptr), changed(
false), list(
nullptr) {}
2243 virtual int idaapi visit_mop(
mop_t *op) = 0;
2293 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2296 std::swap(off, r.off);
2297 std::swap(idx, r.idx);
2318 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2321 std::swap(off, r.off);
2326 member_t *
hexapi get_stkvar(uval_t *p_off=
nullptr)
const;
2349 scif_t(
mba_t *_mba, tinfo_t *tif, qstring *n=
nullptr) : mba(_mba)
2369 mnumber_t(uint64 v, ea_t _ea=BADADDR,
int n=0)
2371 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2374 if ( value < r.value )
2376 if ( value > r.value )
2381 void update_value(uint64 val64)
2395 operator uint16 *(void) {
return fnum.w; }
2396 operator const uint16 *(void)
const {
return fnum.w; }
2397 void hexapi print(qstring *vout)
const;
2399 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2402 return ecmp(fnum, r.fnum);
2409#define SHINS_NUMADDR 0x01
2410#define SHINS_VALNUM 0x02
2411#define SHINS_SHORT 0x04
2412#define SHINS_LDXEA 0x08
2445#define OPROP_IMPDONE 0x01
2446#define OPROP_UDT 0x02
2447#define OPROP_FLOAT 0x04
2448#define OPROP_CCFLAGS 0x08
2451#define OPROP_UDEFVAL 0x10
2452#define OPROP_LOWADDR 0x20
2488 void set_udt(
void) { oprops |=
OPROP_UDT; }
2491 bool is_impptr_done(
void)
const {
return (oprops &
OPROP_IMPDONE) != 0; }
2492 bool is_udt(
void)
const {
return (oprops &
OPROP_UDT) != 0; }
2493 bool probably_floating(
void)
const {
return (oprops &
OPROP_FLOAT) != 0; }
2494 bool is_undef_val(
void)
const {
return (oprops &
OPROP_UDEFVAL) != 0; }
2495 bool is_lowaddr(
void)
const {
return (oprops &
OPROP_LOWADDR) != 0; }
2496 bool is_ccflags(
void)
const
2501 bool is_pcval(
void)
const
2505 bool is_glbaddr_from_fixup()
const
2510 mop_t(
void) { zero(); }
2512 mop_t(
mreg_t _r,
int _s) : t(
mop_r), oprops(0), valnum(0), size(_s), r(_r) {}
2513 mop_t &operator=(
const mop_t &rop) {
return assign(rop); }
2519 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2520 void zero() { t =
mop_z; oprops = 0; valnum = 0; size =
NOSIZE; nnn =
nullptr; }
2523 void erase_but_keep_size(
void) {
int s2 = size; erase(); size = s2; }
2568 void hexapi create_from_scattered_vdloc(
2586 void hexapi make_number(uint64 _value,
int _size, ea_t _ea=BADADDR,
int opnum=0);
2593 bool hexapi make_fpnum(
const void *bytes,
size_t _size);
2604 void _make_reg(
mreg_t reg,
int _size)
2612 void make_reg(
mreg_t reg,
int _size) { erase(); _make_reg(reg, _size); }
2630 void hexapi _make_gvar(ea_t ea);
2632 void hexapi make_gvar(ea_t ea);
2644 void make_stkvar(
mba_t *mba, sval_t off) { erase(); _make_stkvar(mba, off); }
2650 void hexapi make_reg_pair(
int loreg,
int hireg,
int halfsize);
2657 void _make_insn(
minsn_t *ins);
2676 void hexapi make_helper(
const char *name);
2682 cstr = ::qstrdup(str);
2684 void _make_strlit(qstring *str)
2687 cstr = str->extract();
2721 bool empty(
void)
const {
return t ==
mop_z; }
2732 bool is_cc(
void)
const {
return is_reg() && r >= mr_cf && r < mr_first; }
2736 bool is_bit_reg(
void)
const {
return is_reg() && is_bit_reg(r); }
2744 bool is_glbaddr()
const;
2746 bool is_glbaddr(ea_t ea)
const;
2748 bool is_stkaddr()
const;
2752 bool is_insn(mcode_t code)
const;
2755 bool has_side_effects(
bool include_ldx_and_divs=
false)
const;
2757 bool hexapi may_use_aliased_memory(
void)
const;
2762 bool hexapi is01(
void)
const;
2769 bool hexapi is_sign_extended_from(
int nbytes)
const;
2776 bool hexapi is_zero_extended_from(
int nbytes)
const;
2782 return is_sign_extended_from(nbytes);
2784 return is_zero_extended_from(nbytes);
2794 bool hexapi equal_mops(
const mop_t &rop,
int eqflags)
const;
2795 bool operator==(
const mop_t &rop)
const {
return equal_mops(rop, 0); }
2796 bool operator!=(
const mop_t &rop)
const {
return !equal_mops(rop, 0); }
2800 bool operator <(
const mop_t &rop)
const {
return lexcompare(rop) < 0; }
2801 friend int lexcompare(
const mop_t &a,
const mop_t &b) {
return a.lexcompare(b); }
2814 const tinfo_t *type=
nullptr,
2815 bool is_target=
false);
2830 uint64
value(
bool is_signed)
const {
return extend_sign(nnn->value, size, is_signed); }
2831 int64 signed_value(
void)
const {
return value(
true); }
2832 uint64 unsigned_value(
void)
const {
return value(
false); }
2833 void update_numop_value(uint64 val)
2835 nnn->update_value(extend_sign(val, size,
false));
2842 bool hexapi is_constant(uint64 *out=
nullptr,
bool is_signed=
true)
const;
2844 bool is_equal_to(uint64 n,
bool is_signed=
true)
const
2847 return is_constant(&v, is_signed) && v == n;
2849 bool is_zero(
void)
const {
return is_equal_to(0,
false); }
2850 bool is_one(
void)
const {
return is_equal_to(1,
false); }
2851 bool is_positive_constant(
void)
const
2854 return is_constant(&v,
true) && int64(v) > 0;
2856 bool is_negative_constant(
void)
const
2859 return is_constant(&v,
true) && int64(v) < 0;
2868 member_t *
get_stkvar(uval_t *p_off)
const {
return s->get_stkvar(p_off); }
2875 bool hexapi get_stkoff(sval_t *p_off)
const;
2884 const minsn_t *get_insn(mcode_t code)
const;
2885 minsn_t *get_insn(mcode_t code);
2894 bool hexapi make_low_half(
int width);
2900 bool hexapi make_high_half(
int width);
2906 bool hexapi make_first_half(
int width);
2912 bool hexapi make_second_half(
int width);
2923 bool hexapi shift_mop(
int offset);
2949 bool hexapi preserve_side_effects(
2952 bool *moved_calls=
nullptr);
2960 void hexapi apply_ld_mcode(mcode_t mcode, ea_t ea,
int newsize);
2961 void apply_xdu(ea_t ea,
int newsize) { apply_ld_mcode(m_xdu, ea, newsize); }
2962 void apply_xds(ea_t ea,
int newsize) { apply_ld_mcode(m_xds, ea, newsize); }
2964DECLARE_TYPE_AS_MOVABLE(
mop_t);
2972 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2984 :
mop_t(ra), insize(ra.insize), outsize(ra.outsize) {}
2986 :
mop_t(ra), insize(isz), outsize(osz) {}
2991 insize = rop.insize;
2992 outsize = rop.outsize;
2997 int code = mop_t::lexcompare(ra);
2998 return code != 0 ? code
2999 : insize != ra.insize ? (insize-ra.insize)
3000 : outsize != ra.outsize ? (outsize-ra.outsize)
3018 void copy_mop(
const mop_t &op) { *(
mop_t *)
this = op; }
3021 void hexapi set_regarg(
mreg_t mr,
int sz,
const tinfo_t &tif);
3022 void set_regarg(
mreg_t mr,
const tinfo_t &tif)
3024 set_regarg(mr, tif.get_size(), tif);
3026 void set_regarg(
mreg_t mr,
char dt, type_sign_t sign = type_unsigned)
3028 int sz = get_dtype_size(dt);
3031 void make_int(
int val, ea_t val_ea,
int opno = 0)
3033 type = tinfo_t(BTF_INT);
3034 make_number(val, inf_get_cc_size_i(), val_ea, opno);
3036 void make_uint(
int val, ea_t val_ea,
int opno = 0)
3038 type = tinfo_t(BTF_UINT);
3039 make_number(val, inf_get_cc_size_i(), val_ea, opno);
3043typedef qvector<mcallarg_t> mcallargs_t;
3095#define FUNC_NAME_MEMCPY "memcpy"
3096#define FUNC_NAME_WMEMCPY "wmemcpy"
3097#define FUNC_NAME_MEMSET "memset"
3098#define FUNC_NAME_WMEMSET "wmemset"
3099#define FUNC_NAME_MEMSET32 "memset32"
3100#define FUNC_NAME_MEMSET64 "memset64"
3101#define FUNC_NAME_STRCPY "strcpy"
3102#define FUNC_NAME_WCSCPY "wcscpy"
3103#define FUNC_NAME_STRLEN "strlen"
3104#define FUNC_NAME_WCSLEN "wcslen"
3105#define FUNC_NAME_STRCAT "strcat"
3106#define FUNC_NAME_WCSCAT "wcscat"
3107#define FUNC_NAME_TAIL "tail"
3108#define FUNC_NAME_VA_ARG "va_arg"
3109#define FUNC_NAME_EMPTY "$empty"
3110#define FUNC_NAME_PRESENT "$present"
3111#define FUNC_NAME_CONTAINING_RECORD "CONTAINING_RECORD"
3117#define MAX_FUNC_ARGS 64
3147#define FCI_PROP 0x001
3148#define FCI_DEAD 0x002
3149#define FCI_FINAL 0x004
3150#define FCI_NORET 0x008
3151#define FCI_PURE 0x010
3152#define FCI_NOSIDE 0x020
3153#define FCI_SPLOK 0x040
3158#define FCI_HASCALL 0x080
3161#define FCI_HASFMT 0x100
3163#define FCI_EXPLOCS 0x400
3169 : callee(_callee), solid_args(_sargs), call_spd(0), stkargs_top(0),
3170 cc(CM_CC_INVALID), flags(0), role(
ROLE_UNK) {}
3171 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
3175 bool is_vararg(
void)
const {
return is_vararg_cc(cc); }
3189 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
3190 bool empty(
void)
const {
return targets.empty(); }
3191 size_t size(
void)
const {
return targets.size(); }
3192 void resize(
int s) { values.resize(s); targets.resize(s); }
3193 void hexapi print(qstring *vout)
const;
3205 voff_t(
mopt_t _type, sval_t _off) : off(_off), type(_type) {}
3212 void set(
mopt_t _type, sval_t _off) { type = _type; off = _off; }
3213 void set_stkoff(sval_t stkoff) { set(
mop_S, stkoff); }
3215 void undef() { set(
mop_z, -1); }
3217 bool defined()
const {
return type !=
mop_z; }
3218 bool is_reg()
const {
return type ==
mop_r; }
3219 bool is_stkoff()
const {
return type ==
mop_S; }
3220 mreg_t get_reg()
const { QASSERT(51892, is_reg());
return off; }
3221 sval_t get_stkoff()
const { QASSERT(51893, is_stkoff());
return off; }
3223 void inc(sval_t delta) { off += delta; }
3224 voff_t add(
int width)
const {
return voff_t(type, off+width); }
3225 sval_t diff(
const voff_t &r)
const { QASSERT(51894, type == r.
type);
return off - r.
off; }
3227 DECLARE_COMPARISONS(
voff_t)
3229 int code = ::compare(type, r.type);
3230 return code != 0 ? code : ::compare(off, r.off);
3241 :
voff_t(_type, _off), size(_size) {}
3246 void set(
mopt_t _type, sval_t _off,
int _size = 0)
3247 { voff_t::set(_type, _off); size = _size; }
3248 void set(
const voff_t &voff,
int _size)
3249 { set(voff.
type, voff.
off, _size); }
3250 void set_stkoff(sval_t stkoff,
int sz = 0) { set(
mop_S, stkoff, sz); }
3251 void set_reg (
mreg_t mreg,
int sz = 0) { set(
mop_r, mreg, sz); }
3264 return type == r.
type
3265 && interval::overlap(off, size, r.
off, r.
size);
3270 return type == r.
type
3271 && interval::includes(off, size, r.
off, r.
size);
3277 return type == voff2.
type
3278 && interval::contains(off, size, voff2.
off);
3282 DECLARE_COMPARISONS(
vivl_t)
3284 int code = voff_t::compare(r);
3287 bool operator==(
const mop_t &mop)
const
3289 return type == mop.
t && off == (mop.
is_reg() ? mop.r : mop.s->
off);
3291 void hexapi print(qstring *vout)
const;
3310#define CHF_INITED 0x01
3311#define CHF_REPLACED 0x02
3312#define CHF_OVER 0x04
3313#define CHF_FAKE 0x08
3314#define CHF_PASSTHRU 0x10
3315#define CHF_TERM 0x20
3317 chain_t() : width(0), varnum(-1), flags(CHF_INITED) {}
3319 : k(t, off), width(w), varnum(v), flags(
CHF_INITED) {}
3321 : k(_k), width(w), varnum(-1), flags(
CHF_INITED) {}
3322 void set_value(
const chain_t &r)
3323 { width = r.
width; varnum = r.
varnum; flags = r.
flags; *(intvec_t *)
this = (intvec_t &)r; }
3324 const voff_t &key()
const {
return k; }
3325 bool is_inited(
void)
const {
return (flags &
CHF_INITED) != 0; }
3326 bool is_reg(
void)
const {
return k.is_reg(); }
3327 bool is_stkoff(
void)
const {
return k.is_stkoff(); }
3328 bool is_replaced(
void)
const {
return (flags &
CHF_REPLACED) != 0; }
3329 bool is_overlapped(
void)
const {
return (flags &
CHF_OVER) != 0; }
3330 bool is_fake(
void)
const {
return (flags &
CHF_FAKE) != 0; }
3331 bool is_passreg(
void)
const {
return (flags &
CHF_PASSTHRU) != 0; }
3332 bool is_term(
void)
const {
return (flags &
CHF_TERM) != 0; }
3333 void set_inited(
bool b) { setflag(flags,
CHF_INITED, b); }
3334 void set_replaced(
bool b) { setflag(flags,
CHF_REPLACED, b); }
3335 void set_overlapped(
bool b) { setflag(flags,
CHF_OVER, b); }
3336 void set_term(
bool b) { setflag(flags,
CHF_TERM, b); }
3337 mreg_t get_reg()
const {
return k.get_reg(); }
3338 sval_t get_stkoff()
const {
return k.get_stkoff(); }
3339 bool overlap(
const chain_t &r)
const
3341 bool includes(
const chain_t &r)
const
3343 const voff_t endoff()
const {
return k.add(width); }
3345 bool operator<(
const chain_t &r)
const {
return key() < r.key(); }
3347 void hexapi print(qstring *vout)
const;
3351 void clear_varnum(
void) { varnum = -1; set_replaced(
false); }
3357# define SIZEOF_BLOCK_CHAINS 32
3359# define SIZEOF_BLOCK_CHAINS 24
3361#elif defined(__MAC__)
3362# define SIZEOF_BLOCK_CHAINS 32
3364# define SIZEOF_BLOCK_CHAINS 56
3375 size_t body[SIZEOF_BLOCK_CHAINS/
sizeof(size_t)];
3390 chain_t *get_stk_chain(sval_t off,
int width=1)
3397 {
return get_chain(
chain_t(k, width)); }
3407 void hexapi print(qstring *vout)
const;
3409 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
3417 virtual int idaapi visit_chain(
int nblock,
chain_t &ch) = 0;
3436#define GCA_EMPTY 0x01
3437#define GCA_SPEC 0x02
3438#define GCA_ALLOC 0x04
3439#define GCA_NALLOC 0x08
3440#define GCA_OFIRST 0x10
3441#define GCA_OLAST 0x20
3451 void hexapi release(
void);
3454 qvector<block_chains_t>::swap(r);
3455 std::swap(lock, r.lock);
3462 void hexapi init(ea_t _ea);
3477#define IPROP_OPTIONAL 0x0001
3478#define IPROP_PERSIST 0x0002
3479#define IPROP_WILDMATCH 0x0004
3482#define IPROP_CLNPOP 0x0008
3484#define IPROP_FPINSN 0x0010
3485#define IPROP_FARCALL 0x0020
3486#define IPROP_TAILCALL 0x0040
3487#define IPROP_ASSERT 0x0080
3492#define IPROP_SPLIT 0x0700
3493#define IPROP_SPLIT1 0x0100
3494#define IPROP_SPLIT2 0x0200
3495#define IPROP_SPLIT4 0x0300
3496#define IPROP_SPLIT8 0x0400
3497#define IPROP_COMBINED 0x0800
3498#define IPROP_EXTSTX 0x1000
3499#define IPROP_IGNLOWSRC 0x2000
3502#define IPROP_INV_JX 0x4000
3503#define IPROP_WAS_NORET 0x8000
3504#define IPROP_MULTI_MOV 0x10000
3508#define IPROP_DONT_PROP 0x20000
3509#define IPROP_DONT_COMB 0x40000
3510#define IPROP_MBARRIER 0x80000
3512#define IPROP_UNMERGED 0x100000
3515 bool is_optional(
void)
const {
return (iprops &
IPROP_OPTIONAL) != 0; }
3516 bool is_combined(
void)
const {
return (iprops &
IPROP_COMBINED) != 0; }
3517 bool is_farcall(
void)
const {
return (iprops &
IPROP_FARCALL) != 0; }
3518 bool is_cleaning_pop(
void)
const {
return (iprops &
IPROP_CLNPOP) != 0; }
3519 bool is_extstx(
void)
const {
return (iprops &
IPROP_EXTSTX) != 0; }
3520 bool is_tailcall(
void)
const {
return (iprops &
IPROP_TAILCALL) != 0; }
3521 bool is_fpinsn(
void)
const {
return (iprops &
IPROP_FPINSN) != 0; }
3522 bool is_assert(
void)
const {
return (iprops &
IPROP_ASSERT) != 0; }
3523 bool is_persistent(
void)
const {
return (iprops &
IPROP_PERSIST) != 0; }
3524 bool is_wild_match(
void)
const {
return (iprops &
IPROP_WILDMATCH) != 0; }
3525 bool is_propagatable(
void)
const {
return (iprops &
IPROP_DONT_PROP) == 0; }
3526 bool is_ignlowsrc(
void)
const {
return (iprops &
IPROP_IGNLOWSRC) != 0; }
3527 bool is_inverted_jx(
void)
const {
return (iprops &
IPROP_INV_JX) != 0; }
3528 bool was_noret_icall(
void)
const {
return (iprops &
IPROP_WAS_NORET) != 0; }
3529 bool is_multimov(
void)
const {
return (iprops &
IPROP_MULTI_MOV) != 0; }
3530 bool is_combinable(
void)
const {
return (iprops &
IPROP_DONT_COMB) == 0; }
3531 bool was_split(
void)
const {
return (iprops &
IPROP_SPLIT) != 0; }
3532 bool is_mbarrier(
void)
const {
return (iprops &
IPROP_MBARRIER) != 0; }
3533 bool was_unmerged(
void)
const {
return (iprops &
IPROP_UNMERGED) != 0; }
3536 void hexapi set_combined(
void);
3537 void clr_combined(
void) { iprops &= ~IPROP_COMBINED; }
3539 void set_cleaning_pop(
void) { iprops |=
IPROP_CLNPOP; }
3542 void clr_tailcall(
void) { iprops &= ~IPROP_TAILCALL; }
3544 void clr_fpinsn(
void) { iprops &= ~IPROP_FPINSN; }
3546 void clr_assert(
void) { iprops &= ~IPROP_ASSERT; }
3551 void clr_ignlowsrc(
void) { iprops &= ~IPROP_IGNLOWSRC; }
3554 void clr_noret_icall(
void) { iprops &= ~IPROP_WAS_NORET; }
3556 void clr_multimov(
void) { iprops &= ~IPROP_MULTI_MOV; }
3557 void set_combinable(
void) { iprops &= ~IPROP_DONT_COMB; }
3561 void set_split_size(
int s)
3563 iprops &= ~IPROP_SPLIT;
3569 int get_split_size(
void)
const
3572 return cnt == 0 ? 0 : 1 << (cnt-1);
3578 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
3596 void hexapi setaddr(ea_t new_ea);
3605 int optimize_solo(
int optflags=0) {
return optimize_subtree(
nullptr,
nullptr,
nullptr,
nullptr, optflags); }
3608#define OPTI_ADDREXPRS 0x0001
3609#define OPTI_MINSTKREF 0x0002
3610#define OPTI_COMBINSNS 0x0004
3611#define OPTI_NO_LDXOPT 0x0008
3618 int hexapi optimize_subtree(
3622 ea_t *converted_call,
3641 void hexapi _make_nop(
void);
3647 bool hexapi equal_insns(
const minsn_t &m,
int eqflags)
const;
3650#define EQ_IGNSIZE 0x0001
3651#define EQ_IGNCODE 0x0002
3652#define EQ_CMPDEST 0x0004
3653#define EQ_OPTINSN 0x0008
3658 bool operator <(
const minsn_t &ri)
const {
return lexcompare(ri) < 0; }
3666 bool hexapi is_noret_call(
int flags=0);
3667#define NORET_IGNORE_WAS_NORET_ICALL 0x01
3668#define NORET_FORBID_ANALYSIS 0x02
3681 bool hexapi is_helper(
const char *name)
const;
3689 bool contains_call(
bool with_helpers=
false)
const {
return find_call(with_helpers) !=
nullptr; }
3695 bool hexapi has_side_effects(
bool include_ldx_and_divs=
false)
const;
3699 bool is_memcpy(
void)
const {
return get_role() ==
ROLE_MEMCPY; }
3700 bool is_memset(
void)
const {
return get_role() ==
ROLE_MEMSET; }
3701 bool is_alloca(
void)
const {
return get_role() ==
ROLE_ALLOCA; }
3702 bool is_bswap (
void)
const {
return get_role() ==
ROLE_BSWAP; }
3703 bool is_readflags (
void)
const {
return get_role() ==
ROLE_READFLAGS; }
3725 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)); }
3733 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)); }
3735 bool is_mov(
void)
const {
return opcode == m_mov || (opcode == m_f2f && l.
size == d.
size); }
3736 bool is_like_move(
void)
const {
return is_mov() || is_mcode_xdsu(opcode) || opcode == m_low; }
3740 bool hexapi modifies_d(
void)
const;
3741 bool modifies_pair_mop(
void)
const {
return d.
t ==
mop_p && modifies_d(); }
3755 bool hexapi may_use_aliased_memory(
void)
const;
3760 int hexapi serialize(bytevec_t *b)
const;
3767 bool hexapi deserialize(
const uchar *bytes,
size_t nbytes,
int format_version);
3792#define MAXRANGE bitrange_t(0, USHRT_MAX)
3811#define MBL_PRIV 0x0001
3813#define MBL_NONFAKE 0x0000
3814#define MBL_FAKE 0x0002
3815#define MBL_GOTO 0x0004
3816#define MBL_TCAL 0x0008
3817#define MBL_PUSH 0x0010
3818#define MBL_DMT64 0x0020
3819#define MBL_COMB 0x0040
3820#define MBL_PROP 0x0080
3821#define MBL_DEAD 0x0100
3822#define MBL_LIST 0x0200
3823#define MBL_INCONST 0x0400
3824#define MBL_CALL 0x0800
3825#define MBL_BACKPROP 0x1000
3826#define MBL_NORET 0x2000
3827#define MBL_DSLOT 0x4000
3828#define MBL_VALRANGES 0x8000
3829#define MBL_KEEP 0x10000
3863 void mark_lists_dirty(
void) { flags &= ~MBL_LIST; request_propagation(); }
3864 void request_propagation(
void) { flags |=
MBL_PROP; }
3865 bool needs_propagation(
void)
const {
return (flags &
MBL_PROP) != 0; }
3866 void request_demote64(
void) { flags |=
MBL_DMT64; }
3867 bool lists_dirty(
void)
const {
return (flags &
MBL_LIST) == 0; }
3869 int make_lists_ready(
void)
3871 if ( lists_ready() )
3873 return build_lists(
false);
3877 int npred(
void)
const {
return predset.size(); }
3879 int nsucc(
void)
const {
return succset.size(); }
3881 int pred(
int n)
const {
return predset[n]; }
3883 int succ(
int n)
const {
return succset[n]; }
3887 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
3888 bool empty(
void)
const {
return head ==
nullptr; }
3897 void hexapi dump(
void)
const;
3898 AS_PRINTF(2, 0) void
hexapi vdump_block(const
char *title, va_list va) const;
3899 AS_PRINTF(2, 3)
void dump_block(const
char *title, ...)
const
3902 va_start(va, title);
3903 vdump_block(title, va);
3975 int hexapi optimize_block(
void);
3981 int hexapi build_lists(
bool kill_deads);
3989 int hexapi optimize_useless_jump(
void);
4006 void hexapi append_use_list(
4010 bitrange_t mask=MAXRANGE)
const;
4019 void hexapi append_def_list(
4022 maymust_t maymust)
const;
4064 {
return find_first_use(list, i1, i2, maymust) !=
nullptr; }
4080 return CONST_CAST(
minsn_t*)(find_first_use(list,
4081 CONST_CAST(
const minsn_t*)(i1),
4097 maymust_t maymust=MAY_ACCESS)
const
4099 return find_redefinition(list, i1, i2, maymust) !=
nullptr;
4114 maymust_t maymust=MAY_ACCESS)
const;
4119 maymust_t maymust=MAY_ACCESS)
const
4121 return CONST_CAST(
minsn_t*)(find_redefinition(list,
4122 CONST_CAST(
const minsn_t*)(i1),
4156#define FD_BACKWARD 0x0000
4157#define FD_FORWARD 0x0001
4158#define FD_USE 0x0000
4159#define FD_DEF 0x0002
4160#define FD_DIRTY 0x0004
4171 return find_access(op, p_i1, i2, fdflags|
FD_DEF);
4179 return find_access(op, p_i1, i2, fdflags|
FD_USE);
4186 bool hexapi get_valranges(
4196 bool hexapi get_valranges(
4204#define VR_AT_START 0x0000
4206#define VR_AT_END 0x0001
4209#define VR_EXACT 0x0002
4221 size_t hexapi get_reginsn_qty(
void)
const;
4223 bool is_call_block(
void)
const {
return tail !=
nullptr && is_mcode_call(tail->
opcode); }
4224 bool is_unknown_call(
void)
const {
return tail !=
nullptr && tail->
is_unknown_call(); }
4225 bool is_nway(
void)
const {
return type ==
BLT_NWAY; }
4226 bool is_branch(
void)
const {
return type ==
BLT_2WAY && tail->
d.
t ==
mop_b; }
4227 bool is_simple_goto_block(
void)
const
4229 return get_reginsn_qty() == 1
4230 && tail->
opcode == m_goto
4233 bool is_simple_jcnd_block()
const
4237 && get_reginsn_qty() == 1
4238 && is_mcode_convertible_to_set(tail->
opcode);
4322 return strcmp(text.c_str(), r.text.c_str());
4326typedef qvector<hexwarn_t> hexwarns_t;
4359 func_t *pfn =
nullptr;
4364 ea_t start(
void)
const {
return (pfn !=
nullptr ? *pfn : ranges[0]).start_ea; }
4365 bool empty(
void)
const {
return pfn ==
nullptr && ranges.empty(); }
4366 void clear(
void) { pfn =
nullptr; ranges.clear(); }
4367 bool is_snippet(
void)
const {
return pfn ==
nullptr; }
4368 bool hexapi range_contains(ea_t ea)
const;
4369 bool is_fragmented(
void)
const
4371 int n_frags = ranges.size();
4372 if ( pfn !=
nullptr )
4373 n_frags += pfn->tailqty + 1;
4381 const rangevec_t *ranges =
nullptr;
4382 const range_t *rptr =
nullptr;
4384 bool set(
const rangevec_t &r);
4385 bool next_code(
void);
4386 ea_t current(
void)
const {
return cur; }
4393 func_item_iterator_t fii;
4394 bool func_items_done =
true;
4398 if ( mbr.
pfn !=
nullptr )
4400 ok = fii.set(mbr.
pfn);
4402 func_items_done =
false;
4404 if ( rii.set(mbr.
ranges) )
4408 bool next_code(
void)
4411 if ( !func_items_done )
4413 ok = fii.next_code();
4415 func_items_done =
true;
4418 ok = rii.next_code();
4421 ea_t current(
void)
const
4423 return func_items_done ? rii.current() : fii.current();
4430 const range_t *rptr =
nullptr;
4431 const range_t *rend =
nullptr;
4432 bool set(
const rangevec_t &r) { rptr = r.begin(); rend = r.end();
return rptr != rend; }
4433 bool next(
void) {
return ++rptr != rend; }
4434 const range_t &chunk(
void)
const {
return *rptr; }
4441 func_tail_iterator_t fii;
4442 bool is_snippet(
void)
const {
return rii.rptr !=
nullptr; }
4445 if ( mbr.is_snippet() )
4446 return rii.set(mbr.
ranges);
4448 return fii.set(mbr.
pfn);
4457 const range_t &chunk(
void)
const
4459 return is_snippet() ? rii.chunk() : fii.chunk();
4470 DECLARE_UNCOPYABLE(
mba_t)
4476#define MBA_PRCDEFS 0x00000001
4477#define MBA_NOFUNC 0x00000002
4478#define MBA_PATTERN 0x00000004
4479#define MBA_LOADED 0x00000008
4480#define MBA_RETFP 0x00000010
4481#define MBA_SPLINFO 0x00000020
4482#define MBA_PASSREGS 0x00000040
4483#define MBA_THUNK 0x00000080
4484#define MBA_CMNSTK 0x00000100
4487#define MBA_PREOPT 0x00000200
4488#define MBA_CMBBLK 0x00000400
4489#define MBA_ASRTOK 0x00000800
4490#define MBA_CALLS 0x00001000
4491#define MBA_ASRPROP 0x00002000
4492#define MBA_SAVRST 0x00004000
4493#define MBA_RETREF 0x00008000
4494#define MBA_GLBOPT 0x00010000
4495#define MBA_LVARS0 0x00040000
4496#define MBA_LVARS1 0x00080000
4497#define MBA_DELPAIRS 0x00100000
4498#define MBA_CHVARS 0x00200000
4501#define MBA_SHORT 0x00400000
4502#define MBA_COLGDL 0x00800000
4503#define MBA_INSGDL 0x01000000
4504#define MBA_NICE 0x02000000
4505#define MBA_REFINE 0x04000000
4506#define MBA_WINGR32 0x10000000
4507#define MBA_NUMADDR 0x20000000
4508#define MBA_VALNUM 0x40000000
4510#define MBA_INITIAL_FLAGS (MBA_INSGDL|MBA_NICE|MBA_CMBBLK|MBA_REFINE\
4511 |MBA_PRCDEFS|MBA_WINGR32|MBA_VALNUM)
4513#define MBA2_LVARNAMES_OK 0x00000001
4514#define MBA2_LVARS_RENAMED 0x00000002
4515#define MBA2_OVER_CHAINS 0x00000004
4516#define MBA2_VALRNG_DONE 0x00000008
4517#define MBA2_IS_CTR 0x00000010
4518#define MBA2_IS_DTR 0x00000020
4519#define MBA2_ARGIDX_OK 0x00000040
4520#define MBA2_NO_DUP_CALLS 0x00000080
4521#define MBA2_NO_DUP_LVARS 0x00000100
4522#define MBA2_UNDEF_RETVAR 0x00000200
4523#define MBA2_ARGIDX_SORTED 0x00000400
4525#define MBA2_CODE16_BIT 0x00000800
4526#define MBA2_STACK_RETVAL 0x00001000
4527#define MBA2_HAS_OUTLINES 0x00002000
4528#define MBA2_NO_FRAME 0x00004000
4529#define MBA2_PROP_COMPLEX 0x00008000
4531#define MBA2_DONT_VERIFY 0x80000000
4535#define MBA2_INITIAL_FLAGS (MBA2_LVARNAMES_OK|MBA2_LVARS_RENAMED)
4537#define MBA2_ALL_FLAGS 0x0000FFFF
4539 bool precise_defeas(
void)
const {
return (flags &
MBA_PRCDEFS) != 0; }
4540 bool optimized(
void)
const {
return (flags &
MBA_GLBOPT) != 0; }
4541 bool short_display(
void)
const {
return (flags &
MBA_SHORT ) != 0; }
4542 bool show_reduction(
void)
const {
return (flags &
MBA_COLGDL) != 0; }
4543 bool graph_insns(
void)
const {
return (flags &
MBA_INSGDL) != 0; }
4544 bool loaded_gdl(
void)
const {
return (flags &
MBA_LOADED) != 0; }
4545 bool should_beautify(
void)
const {
return (flags &
MBA_NICE ) != 0; }
4546 bool rtype_refined(
void)
const {
return (flags &
MBA_RETREF) != 0; }
4547 bool may_refine_rettype(
void)
const {
return (flags &
MBA_REFINE) != 0; }
4548 bool use_wingraph32(
void)
const {
return (flags &
MBA_WINGR32) != 0; }
4549 bool display_numaddrs(
void)
const {
return (flags &
MBA_NUMADDR) != 0; }
4550 bool display_valnums(
void)
const {
return (flags &
MBA_VALNUM) != 0; }
4551 bool is_pattern(
void)
const {
return (flags &
MBA_PATTERN) != 0; }
4552 bool is_thunk(
void)
const {
return (flags &
MBA_THUNK) != 0; }
4553 bool saverest_done(
void)
const {
return (flags &
MBA_SAVRST) != 0; }
4554 bool callinfo_built(
void)
const {
return (flags &
MBA_CALLS) != 0; }
4555 bool really_alloc(
void)
const {
return (flags &
MBA_LVARS0) != 0; }
4556 bool lvars_allocated(
void)
const {
return (flags &
MBA_LVARS1) != 0; }
4557 bool chain_varnums_ok(
void)
const {
return (flags &
MBA_CHVARS) != 0; }
4558 bool returns_fpval(
void)
const {
return (flags &
MBA_RETFP) != 0; }
4559 bool has_passregs(
void)
const {
return (flags &
MBA_PASSREGS) != 0; }
4560 bool generated_asserts(
void)
const {
return (flags &
MBA_ASRTOK) != 0; }
4561 bool propagated_asserts(
void)
const {
return (flags &
MBA_ASRPROP) != 0; }
4562 bool deleted_pairs(
void)
const {
return (flags &
MBA_DELPAIRS) != 0; }
4563 bool common_stkvars_stkargs(
void)
const {
return (flags &
MBA_CMNSTK) != 0; }
4566 bool has_over_chains(
void)
const {
return (flags2 &
MBA2_OVER_CHAINS) != 0; }
4567 bool valranges_done(
void)
const {
return (flags2 &
MBA2_VALRNG_DONE) != 0; }
4568 bool argidx_ok(
void)
const {
return (flags2 &
MBA2_ARGIDX_OK) != 0; }
4570 bool code16_bit_removed(
void)
const {
return (flags2 &
MBA2_CODE16_BIT) != 0; }
4573 bool is_ctr(
void)
const {
return (flags2 &
MBA2_IS_CTR) != 0; }
4574 bool is_dtr(
void)
const {
return (flags2 &
MBA2_IS_DTR) != 0; }
4577 int get_mba_flags(
void)
const {
return flags; }
4578 int get_mba_flags2(
void)
const {
return flags2; }
4579 void set_mba_flags(
int f) { flags |= f; }
4580 void clr_mba_flags(
int f) { flags &= ~f; }
4581 void set_mba_flags2(
int f) { flags2 |= f; }
4582 void clr_mba_flags2(
int f) { flags2 &= ~f; }
4584 int calc_shins_flags(
void)
const
4586 int shins_flags = 0;
4587 if ( short_display() )
4589 if ( display_valnums() )
4591 if ( display_numaddrs() )
4638 sval_t
hexapi stkoff_vd2ida(sval_t off)
const;
4640 sval_t
hexapi stkoff_ida2vd(sval_t off)
const;
4641 sval_t argbase()
const
4643 return retsize + stacksize;
4645 static vdloc_t hexapi idaloc2vd(
const argloc_t &loc,
int width, sval_t spd);
4646 vdloc_t hexapi idaloc2vd(
const argloc_t &loc,
int width)
const;
4648 static argloc_t
hexapi vd2idaloc(
const vdloc_t &loc,
int width, sval_t spd);
4649 argloc_t
hexapi vd2idaloc(
const vdloc_t &loc,
int width)
const;
4651 bool is_stkarg(
const lvar_t &v)
const
4655 member_t *get_stkvar(sval_t vd_stkoff, uval_t *poff)
const;
4657 argloc_t get_ida_argloc(
const lvar_t &v)
const
4662 ea_t entry_ea = BADADDR;
4663 ea_t last_prolog_ea = BADADDR;
4664 ea_t first_epilog_ea = BADADDR;
4667 cm_t cc = CM_CC_UNKNOWN;
4668 sval_t tmpstk_size = 0;
4675 int shadow_args = 0;
4676 sval_t fullsize = 0;
4677 sval_t stacksize = 0;
4680 sval_t inargoff = 0;