Hex-Rays logo State-of-the-art binary code analysis tools
email icon
hexrays.hpp
Go to the documentation of this file.
1/*!
2 * Hex-Rays Decompiler project
3 * Copyright (c) 1990-2022 Hex-Rays
4 * ALL RIGHTS RESERVED.
5 * \mainpage
6 * There are 2 representations of the binary code in the decompiler:
7 * - microcode: processor instructions are translated into it and then
8 * the decompiler optimizes and transforms it
9 * - ctree: ctree is built from the optimized microcode and represents
10 * AST-like tree with C statements and expressions. It can
11 * be printed as C code.
12 *
13 * Microcode is represented by the following classes:
14 * - mba_t keeps general info about the decompiled code and
15 * array of basic blocks. usually mba_t is named 'mba'
16 * - mblock_t a basic block. includes list of instructions
17 * - minsn_t an instruction. contains 3 operands: left, right, and
18 * destination
19 * - mop_t an operand. depending on its type may hold various info
20 * like a number, register, stack variable, etc.
21 * - mlist_t list of memory or register locations; can hold vast areas
22 * of memory and multiple registers. this class is used
23 * very extensively in the decompiler. it may represent
24 * list of locations accessed by an instruction or even
25 * an entire basic block. it is also used as argument of
26 * many functions. for example, there is a function
27 * that searches for an instruction that refers to a mlist_t.
28
29 * See https://www.hex-rays.com/blog/microcode-in-pictures for some pictures.
30 *
31 * Ctree is represented by:
32 * - cfunc_t keeps general info about the decompiled code, including a
33 * pointer to mba_t. deleting cfunc_t will delete
34 * mba_t too (however, decompiler returns cfuncptr_t,
35 * which is a reference counting object and deletes the
36 * underlying function as soon as all references to it go
37 * out of scope). cfunc_t has 'body', which represents the
38 * decompiled function body as cinsn_t.
39 * - cinsn_t a C statement. can be a compound statement or any other
40 * legal C statements (like if, for, while, return,
41 * expression-statement, etc). depending on the statement
42 * type has pointers to additional info. for example, the
43 * 'if' statement has poiner to cif_t, which holds the
44 * 'if' condition, 'then' branch, and optionally 'else'
45 * branch. Please note that despite of the name cinsn_t
46 * we say "statements", not "instructions". For us
47 * instructions are part of microcode, not ctree.
48 * - cexpr_t a C expression. is used as part of a C statement, when
49 * necessary. cexpr_t has 'type' field, which keeps the
50 * expression type.
51 * - citem_t a base class for cinsn_t and cexpr_t, holds common info
52 * like the address, label, and opcode.
53 * - cnumber_t a constant 64-bit number. in addition to its value also
54 * holds information how to represent it: decimal, hex, or
55 * as a symbolic constant (enum member). please note that
56 * numbers are represented by another class (mnumber_t)
57 * in microcode.
58
59 * See https://www.hex-rays.com/blog/hex-rays-decompiler-primer
60 * for some pictures and more details.
61 *
62 * Both microcode and ctree use the following class:
63 * - lvar_t a local variable. may represent a stack or register
64 * variable. a variable has a name, type, location, etc.
65 * the list of variables is stored in mba->vars.
66 * - lvar_locator_t holds a variable location (vdloc_t) and its definition
67 * address.
68 * - vdloc_t describes a variable location, like a register number,
69 * a stack offset, or, in complex cases, can be a mix of
70 * register and stack locations. very similar to argloc_t,
71 * which is used in ida. the differences between argloc_t
72 * and vdloc_t are:
73 * - vdloc_t never uses ARGLOC_REG2
74 * - vdloc_t uses micro register numbers instead of
75 * processor register numbers
76 * - the stack offsets are never negative in vdloc_t, while
77 * in argloc_t there can be negative offsets
78 *
79 * The above are the most important classes in this header file. There are
80 * many auxiliary classes, please see their definitions in the header file.
81 *
82 * See also the description of \ref vmpage.
83 *
84 */
85
86#ifndef __HEXRAYS_HPP
87#define __HEXRAYS_HPP
88
89#include <pro.h>
90#include <fpro.h>
91#include <ida.hpp>
92#include <idp.hpp>
93#include <gdl.hpp>
94#include <ieee.h>
95#include <loader.hpp>
96#include <kernwin.hpp>
97#include <typeinf.hpp>
98#include <deque>
99#include <queue>
100
101/*!
102 * \page vmpage Virtual Machine used by Microcode
103 * We can imagine a virtual micro machine that executes microcode.
104 * This virtual micro machine has many registers.
105 * Each register is 8 bits wide. During translation of processor
106 * instructions into microcode, multibyte processor registers are mapped
107 * to adjacent microregisters. Processor condition codes are also
108 * represented by microregisters. The microregisters are grouped
109 * into following groups:
110 * - 0..7: condition codes
111 * - 8..n: all processor registers (including fpu registers, if necessary)
112 * this range may also include temporary registers used during
113 * the initial microcode generation
114 * - n.. : so called kernel registers; they are used during optimization
115 * see is_kreg()
116 *
117 * Each micro-instruction (minsn_t) has zero to three operands.
118 * Some of the possible operands types are:
119 * - immediate value
120 * - register
121 * - memory reference
122 * - result of another micro-instruction
123 *
124 * The operands (mop_t) are l (left), r (right), d (destination).
125 * An example of a microinstruction:
126 *
127 * add r0.4, #8.4, r2.4
128 *
129 * which means 'add constant 8 to r0 and place the result into r2'.
130 * where
131 * - the left operand is 'r0', its size is 4 bytes (r0.4)
132 * - the right operand is a constant '8', its size is 4 bytes (#8.4)
133 * - the destination operand is 'r2', its size is 4 bytes (r2.4)
134 * Note that 'd' is almost always the destination but there are exceptions.
135 * See mcode_modifies_d(). For example, stx does not modify 'd'.
136 * See the opcode map below for the list of microinstructions and their
137 * operands. Most instructions are very simple and do not need
138 * detailed explanations. There are no side effects in microinstructions.
139 *
140 * Each operand has a size specifier. The following sizes can be used in
141 * practically all contexts: 1, 2, 4, 8, 16 bytes. Floating types may have
142 * other sizes. Functions may return objects of arbitrary size, as well as
143 * operations upon UDT's (user-defined types, i.e. are structs and unions).
144 *
145 * Memory is considered to consist of several segments.
146 * A memory reference is made using a (selector, offset) pair.
147 * A selector is always 2 bytes long. An offset can be 4 or 8 bytes long,
148 * depending on the bitness of the target processor.
149 * Currently the selectors are not used very much. The decompiler tries to
150 * resolve (selector, offset) pairs into direct memory references at each
151 * opportunity and then operates on mop_v operands. In other words,
152 * while the decompiler can handle segmented memory models, internally
153 * it still uses simple linear addresses.
154 *
155 * The following memory regions are recognized:
156 * - GLBLOW global memory: low part, everything below the stack
157 * - LVARS stack: local variables
158 * - RETADDR stack: return address
159 * - SHADOW stack: shadow arguments
160 * - ARGS stack: regular stack arguments
161 * - GLBHIGH global memory: high part, everything above the stack
162 * Any stack region may be empty. Objects residing in one memory region
163 * are considered to be completely distinct from objects in other regions.
164 * We allocate the stack frame in some memory region, which is not
165 * allocated for any purposes in IDA. This permits us to use linear addresses
166 * for all memory references, including the stack frame.
167 *
168 * If the operand size is bigger than 1 then the register
169 * operand references a block of registers. For example:
170 *
171 * ldc #1.4, r8.4
172 *
173 * loads the constant 1 to registers 8, 9, 10, 11:
174 *
175 * #1 -> r8
176 * #0 -> r9
177 * #0 -> r10
178 * #0 -> r11
179 *
180 * This example uses little-endian byte ordering.
181 * Big-endian byte ordering is supported too. Registers are always little-
182 * endian, regardless of the memory endianness.
183 *
184 * Each instruction has 'next' and 'prev' fields that are used to form
185 * a doubly linked list. Such lists are present for each basic block (mblock_t).
186 * Basic blocks have other attributes, including:
187 * - dead_at_start: list of dead locations at the block start
188 * - maybuse: list of locations the block may use
189 * - maybdef: list of locations the block may define (or spoil)
190 * - mustbuse: list of locations the block will certainly use
191 * - mustbdef: list of locations the block will certainly define
192 * - dnu: list of locations the block will certainly define
193 * but will not use (registers or non-aliasable stkack vars)
194 *
195 * These lists are represented by the mlist_t class. It consists of 2 parts:
196 * - rlist_t: list of microregisters (possibly including virtual stack locations)
197 * - ivlset_t: list of memory locations represented as intervals
198 * we use linear addresses in this list.
199 * The mlist_t class is used quite often. For example, to find what an operand
200 * can spoil, we build its 'maybe-use' list. Then we can find out if this list
201 * is accessed using the is_accessed() or is_accessed_globally() functions.
202 *
203 * All basic blocks of the decompiled function constitute an array called
204 * mba_t (array of microblocks). This is a huge class that has too
205 * many fields to describe here (some of the fields are not visible in the sdk)
206 * The most importants ones are:
207 * - stack frame: frregs, stacksize, etc
208 * - memory: aliased, restricted, and other ranges
209 * - type: type of the current function, its arguments (argidx) and
210 * local variables (vars)
211 * - natural: array of pointers to basic blocks. the basic blocks
212 * are also accessible as a doubly linked list starting from 'blocks'.
213 * - bg: control flow graph. the graph gives access to the use-def
214 * chains that describe data dependencies between basic blocks
215 *
216 */
217
218#ifdef __NT__
219#pragma warning(push)
220#pragma warning(disable:4062) // enumerator 'x' in switch of enum 'y' is not handled
221#pragma warning(disable:4265) // virtual functions without virtual destructor
222#endif
223
224#define hexapi ///< Public functions are marked with this keyword
225
226// Warning suppressions for PVS Studio:
227//-V:2:654 The condition '2' of loop is always true.
228//-V::719 The switch statement does not cover all values
229//-V:verify:678
230//-V:chain_keeper_t:690 copy ctr will be generated
231//-V:add_block:656 call to the same function
232//-V:add:792 The 'add' function located to the right of the operator '|' will be called regardless of the value of the left operand
233//-V:sub:792 The 'sub' function located to the right of the operator '|' will be called regardless of the value of the left operand
234//-V:intersect:792 The 'intersect' function located to the right of the operator '|' will be called regardless of the value of the left operand
235// Lint suppressions:
236//lint -sem(mop_t::_make_cases, custodial(1))
237//lint -sem(mop_t::_make_pair, custodial(1))
238//lint -sem(mop_t::_make_callinfo, custodial(1))
239//lint -sem(mop_t::_make_insn, custodial(1))
240//lint -sem(mop_t::make_insn, custodial(1))
241
242// Microcode level forward definitions:
243class mop_t; // microinstruction operand
244class mop_pair_t; // pair of operands. example, :(edx.4,eax.4).8
245class mop_addr_t; // address of an operand. example: &global_var
246class mcallinfo_t; // function call info. example: <cdecl:"int x" #10.4>.8
247class mcases_t; // jump table cases. example: {0 => 12, 1 => 13}
248class minsn_t; // microinstruction
249class mblock_t; // basic block
250class mba_t; // array of blocks, represents microcode for a function
251class codegen_t; // helper class to generate the initial microcode
252class mbl_graph_t; // control graph of microcode
253struct vdui_t; // widget representing the pseudocode window
254struct hexrays_failure_t; // decompilation failure object, is thrown by exceptions
255struct mba_stats_t; // statistics about decompilation of a function
256struct mlist_t; // list of memory and register locations
257struct voff_t; // value offset (microregister number or stack offset)
258typedef std::set<voff_t> voff_set_t;
259struct vivl_t; // value interval (register or stack range)
260typedef int mreg_t; ///< Micro register
261
262// Ctree level forward definitions:
263struct cfunc_t; // result of decompilation, the highest level object
264struct citem_t; // base class for cexpr_t and cinsn_t
265struct cexpr_t; // C expression
266struct cinsn_t; // C statement
267struct cblock_t; // C statement block (sequence of statements)
268struct cswitch_t; // C switch statement
269struct carg_t; // call argument
270struct carglist_t; // vector of call arguments
271
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;
281
282// Function frames must be smaller than this value, otherwise
283// the decompiler will bail out with MERR_HUGESTACK
284#define MAX_SUPPORTED_STACK_SIZE 0x100000 // 1MB
285
286//-------------------------------------------------------------------------
287// Original version of macro DEFINE_MEMORY_ALLOCATION_FUNCS
288// (uses decompiler-specific memory allocation functions)
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 /*size*/, 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
297
298void *hexapi hexrays_alloc(size_t size);
299void hexapi hexrays_free(void *ptr);
300
301typedef uint64 uvlr_t;
302typedef int64 svlr_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;
307
308enum cmpop_t
309{ // the order of comparisons is the same as in microcode opcodes
310 CMP_NZ,
311 CMP_Z,
312 CMP_AE,
313 CMP_B,
314 CMP_A,
315 CMP_BE,
316 CMP_GT,
317 CMP_GE,
318 CMP_LT,
319 CMP_LE,
320};
321
322//-------------------------------------------------------------------------
323// value-range class to keep possible operand value(s).
325{
326protected:
327 int flags;
328#define VLR_TYPE 0x0F // valrng_t type
329#define VLR_NONE 0x00 // no values
330#define VLR_ALL 0x01 // all values
331#define VLR_IVLS 0x02 // union of disjoint intervals
332#define VLR_RANGE 0x03 // strided range
333#define VLR_SRANGE 0x04 // strided range with signed bound
334#define VLR_BITS 0x05 // known bits
335#define VLR_SECT 0x06 // intersection of sub-ranges
336 // each sub-range should be simple or union
337#define VLR_UNION 0x07 // union of sub-ranges
338 // each sub-range should be simple or
339 // intersection
340#define VLR_UNK 0x08 // unknown value (like 'null' in SQL)
341 int size; // operand size: 1..8 bytes
342 // all values must fall within the size
343 union
344 {
345 struct // VLR_RANGE/VLR_SRANGE
346 { // values that are between VALUE and LIMIT
347 // and conform to: value+stride*N
348 uvlr_t value; // initial value
349 uvlr_t limit; // final value
350 // we adjust LIMIT to be on the STRIDE lattice
351 svlr_t stride; // stride between values
352 };
353 struct // VLR_BITS
354 {
355 uvlr_t zeroes; // bits known to be clear
356 uvlr_t ones; // bits known to be set
357 };
358 char reserved[sizeof(qvector<int>)];
359 // VLR_IVLS/VLR_SECT/VLR_UNION
360 };
361 void hexapi clear(void);
362 void hexapi copy(const valrng_t &r);
363 valrng_t &hexapi assign(const valrng_t &r);
364
365public:
366 explicit valrng_t(int size_ = MAX_VLR_SIZE)
367 : flags(VLR_NONE), size(size_), value(0), limit(0), stride(0) {}
368 valrng_t(const valrng_t &r) { copy(r); }
369 ~valrng_t(void) { clear(); }
370 valrng_t &operator=(const valrng_t &r) { return assign(r); }
371 void swap(valrng_t &r) { qswap(*this, r); }
372 DECLARE_COMPARISONS(valrng_t);
373 DEFINE_MEMORY_ALLOCATION_FUNCS()
374
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);
380
381 // reduce size
382 // it takes the low part of size NEW_SIZE
383 // it returns "true" if size is changed successfully.
384 // e.g.: valrng_t vr(2); vr.set_eq(0x1234);
385 // vr.reduce_size(1);
386 // uvlr_t v; vr.cvt_to_single_value(&v);
387 // assert(v == 0x34);
388 bool hexapi reduce_size(int new_size);
389
390 // Perform intersection or union or inversion.
391 // \return did we change something in THIS?
392 bool hexapi intersect_with(const valrng_t &r);
393 bool hexapi unite_with(const valrng_t &r);
394 void hexapi inverse(); // works for VLR_IVLS only
395
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;
400
401 void hexapi print(qstring *vout) const;
402 const char *hexapi dstr(void) const;
403
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;
406
407 int get_size() const { return size; }
408 static uvlr_t max_value(int size_)
409 {
410 return size_ == MAX_VLR_SIZE
411 ? MAX_VALUE
412 : (uvlr_t(1) << (size_ * 8)) - 1;
413 }
414 static uvlr_t min_svalue(int size_)
415 {
416 return size_ == MAX_VLR_SIZE
417 ? MIN_SVALUE
418 : (uvlr_t(1) << (size_ * 8 - 1));
419 }
420 static uvlr_t max_svalue(int size_)
421 {
422 return size_ == MAX_VLR_SIZE
423 ? MAX_SVALUE
424 : (uvlr_t(1) << (size_ * 8 - 1)) - 1;
425 }
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); }
429};
430DECLARE_TYPE_AS_MOVABLE(valrng_t);
431
432//-------------------------------------------------------------------------
433// Are we looking for 'must access' or 'may access' information?
434// 'must access' means that the code will always access the specified location(s)
435// 'may access' means that the code may in some cases access the specified location(s)
436// Example: ldx cs.2, r0.4, r1.4
437// MUST_ACCESS: r0.4 and r1.4, usually displayed as r0.8 because r0 and r1 are adjacent
438// MAY_ACCESS: r0.4 and r1.4, and all aliasable memory, because
439// ldx may access any part of the aliasable memory
440typedef int maymust_t;
441const maymust_t
442 // One of the following two bits should be specified:
443 MUST_ACCESS = 0x00, // access information we can count on
444 MAY_ACCESS = 0x01, // access information we should take into account
445 // Optionally combined with the following bits:
446 MAYMUST_ACCESS_MASK = 0x01,
447
448 ONE_ACCESS_TYPE = 0x20, // for find_first_use():
449 // use only the specified maymust access type
450 // (by default it inverts the access type for def-lists)
451 INCLUDE_SPOILED_REGS = 0x40, // for build_def_list() with MUST_ACCESS:
452 // include spoiled registers in the list
453 EXCLUDE_PASS_REGS = 0x80, // for build_def_list() with MAY_ACCESS:
454 // exclude pass_regs from the list
455 FULL_XDSU = 0x100, // for build_def_list():
456 // if xds/xdu source and targets are the same
457 // treat it as if xdsu redefines the entire destination
458 WITH_ASSERTS = 0x200, // for find_first_use():
459 // do not ignore assertions
460 EXCLUDE_VOLATILE = 0x400, // for build_def_list():
461 // exclude volatile memory from the list
462 INCLUDE_UNUSED_SRC = 0x800, // for build_use_list():
463 // do not exclude unused source bytes for m_and/m_or insns
464 INCLUDE_DEAD_RETREGS = 0x1000, // for build_def_list():
465 // include dead returned registers in the list
466 INCLUDE_RESTRICTED = 0x2000,// for MAY_ACCESS: include restricted memory
467 CALL_SPOILS_ONLY_ARGS = 0x4000;// for build_def_list() & MAY_ACCESS:
468 // do not include global memory into the
469 // spoiled list of a call
470
471inline THREAD_SAFE bool is_may_access(maymust_t maymust)
472{
473 return (maymust & MAYMUST_ACCESS_MASK) != MUST_ACCESS;
474}
475
476//-------------------------------------------------------------------------
477/// \defgroup MERR_ Microcode error codes
478//@{
480{
481 MERR_OK = 0, ///< ok
482 MERR_BLOCK = 1, ///< no error, switch to new block
483 MERR_INTERR = -1, ///< internal error
484 MERR_INSN = -2, ///< cannot convert to microcode
485 MERR_MEM = -3, ///< not enough memory
486 MERR_BADBLK = -4, ///< bad block found
487 MERR_BADSP = -5, ///< positive sp value has been found
488 MERR_PROLOG = -6, ///< prolog analysis failed
489 MERR_SWITCH = -7, ///< wrong switch idiom
490 MERR_EXCEPTION = -8, ///< exception analysis failed
491 MERR_HUGESTACK = -9, ///< stack frame is too big
492 MERR_LVARS = -10, ///< local variable allocation failed
493 MERR_BITNESS = -11, ///< 16-bit functions cannot be decompiled
494 MERR_BADCALL = -12, ///< could not determine call arguments
495 MERR_BADFRAME = -13, ///< function frame is wrong
496 MERR_UNKTYPE = -14, ///< undefined type %s (currently unused error code)
497 MERR_BADIDB = -15, ///< inconsistent database information
498 MERR_SIZEOF = -16, ///< wrong basic type sizes in compiler settings
499 MERR_REDO = -17, ///< redecompilation has been requested
500 MERR_CANCELED = -18, ///< decompilation has been cancelled
501 MERR_RECDEPTH = -19, ///< max recursion depth reached during lvar allocation
502 MERR_OVERLAP = -20, ///< variables would overlap: %s
503 MERR_PARTINIT = -21, ///< partially initialized variable %s
504 MERR_COMPLEX = -22, ///< too complex function
505 MERR_LICENSE = -23, ///< no license available
506 MERR_ONLY32 = -24, ///< only 32-bit functions can be decompiled for the current database
507 MERR_ONLY64 = -25, ///< only 64-bit functions can be decompiled for the current database
508 MERR_BUSY = -26, ///< already decompiling a function
509 MERR_FARPTR = -27, ///< far memory model is supported only for pc
510 MERR_EXTERN = -28, ///< special segments cannot be decompiled
511 MERR_FUNCSIZE = -29, ///< too big function
512 MERR_BADRANGES = -30, ///< bad input ranges
513 MERR_BADARCH = -31, ///< current architecture is not supported
514 MERR_DSLOT = -32, ///< bad instruction in the delay slot
515 MERR_STOP = -33, ///< no error, stop the analysis
516 MERR_CLOUD = -34, ///< cloud: %s
517 MERR_MAX_ERR = 34,
518 MERR_LOOP = -35, ///< internal code: redo last loop (never reported)
519};
520//@}
521
522/// Get textual description of an error code
523/// \param out the output buffer for the error description
524/// \param code \ref MERR_
525/// \param mba the microcode array
526/// \return the error address
527
528ea_t hexapi get_merror_desc(qstring *out, merror_t code, mba_t *mba);
529
530//-------------------------------------------------------------------------
531// List of microinstruction opcodes.
532// The order of setX and jX insns is important, it is used in the code.
533
534// Instructions marked with *F may have the FPINSN bit set and operate on fp values
535// Instructions marked with +F must have the FPINSN bit set. They always operate on fp values
536// Other instructions do not operate on fp values.
537
538enum mcode_t
539{
540 m_nop = 0x00, // nop // no operation
541 m_stx = 0x01, // stx l, {r=sel, d=off} // store register to memory *F
542 m_ldx = 0x02, // ldx {l=sel,r=off}, d // load register from memory *F
543 m_ldc = 0x03, // ldc l=const, d // load constant
544 m_mov = 0x04, // mov l, d // move *F
545 m_neg = 0x05, // neg l, d // negate
546 m_lnot = 0x06, // lnot l, d // logical not
547 m_bnot = 0x07, // bnot l, d // bitwise not
548 m_xds = 0x08, // xds l, d // extend (signed)
549 m_xdu = 0x09, // xdu l, d // extend (unsigned)
550 m_low = 0x0A, // low l, d // take low part
551 m_high = 0x0B, // high l, d // take high part
552 m_add = 0x0C, // add l, r, d // l + r -> dst
553 m_sub = 0x0D, // sub l, r, d // l - r -> dst
554 m_mul = 0x0E, // mul l, r, d // l * r -> dst
555 m_udiv = 0x0F, // udiv l, r, d // l / r -> dst
556 m_sdiv = 0x10, // sdiv l, r, d // l / r -> dst
557 m_umod = 0x11, // umod l, r, d // l % r -> dst
558 m_smod = 0x12, // smod l, r, d // l % r -> dst
559 m_or = 0x13, // or l, r, d // bitwise or
560 m_and = 0x14, // and l, r, d // bitwise and
561 m_xor = 0x15, // xor l, r, d // bitwise xor
562 m_shl = 0x16, // shl l, r, d // shift logical left
563 m_shr = 0x17, // shr l, r, d // shift logical right
564 m_sar = 0x18, // sar l, r, d // shift arithmetic right
565 m_cfadd = 0x19, // cfadd l, r, d=carry // calculate carry bit of (l+r)
566 m_ofadd = 0x1A, // ofadd l, r, d=overf // calculate overflow bit of (l+r)
567 m_cfshl = 0x1B, // cfshl l, r, d=carry // calculate carry bit of (l<<r)
568 m_cfshr = 0x1C, // cfshr l, r, d=carry // calculate carry bit of (l>>r)
569 m_sets = 0x1D, // sets l, d=byte SF=1 Sign
570 m_seto = 0x1E, // seto l, r, d=byte OF=1 Overflow of (l-r)
571 m_setp = 0x1F, // setp l, r, d=byte PF=1 Unordered/Parity *F
572 m_setnz = 0x20, // setnz l, r, d=byte ZF=0 Not Equal *F
573 m_setz = 0x21, // setz l, r, d=byte ZF=1 Equal *F
574 m_setae = 0x22, // setae l, r, d=byte CF=0 Above or Equal *F
575 m_setb = 0x23, // setb l, r, d=byte CF=1 Below *F
576 m_seta = 0x24, // seta l, r, d=byte CF=0 & ZF=0 Above *F
577 m_setbe = 0x25, // setbe l, r, d=byte CF=1 | ZF=1 Below or Equal *F
578 m_setg = 0x26, // setg l, r, d=byte SF=OF & ZF=0 Greater
579 m_setge = 0x27, // setge l, r, d=byte SF=OF Greater or Equal
580 m_setl = 0x28, // setl l, r, d=byte SF!=OF Less
581 m_setle = 0x29, // setle l, r, d=byte SF!=OF | ZF=1 Less or Equal
582 m_jcnd = 0x2A, // jcnd l, d // d is mop_v or mop_b
583 m_jnz = 0x2B, // jnz l, r, d // ZF=0 Not Equal *F
584 m_jz = 0x2C, // jz l, r, d // ZF=1 Equal *F
585 m_jae = 0x2D, // jae l, r, d // CF=0 Above or Equal *F
586 m_jb = 0x2E, // jb l, r, d // CF=1 Below *F
587 m_ja = 0x2F, // ja l, r, d // CF=0 & ZF=0 Above *F
588 m_jbe = 0x30, // jbe l, r, d // CF=1 | ZF=1 Below or Equal *F
589 m_jg = 0x31, // jg l, r, d // SF=OF & ZF=0 Greater
590 m_jge = 0x32, // jge l, r, d // SF=OF Greater or Equal
591 m_jl = 0x33, // jl l, r, d // SF!=OF Less
592 m_jle = 0x34, // jle l, r, d // SF!=OF | ZF=1 Less or Equal
593 m_jtbl = 0x35, // jtbl l, r=mcases // Table jump
594 m_ijmp = 0x36, // ijmp {r=sel, d=off} // indirect unconditional jump
595 m_goto = 0x37, // goto l // l is mop_v or mop_b
596 m_call = 0x38, // call l d // l is mop_v or mop_b or mop_h
597 m_icall = 0x39, // icall {l=sel, r=off} d // indirect call
598 m_ret = 0x3A, // ret
599 m_push = 0x3B, // push l
600 m_pop = 0x3C, // pop d
601 m_und = 0x3D, // und d // undefine
602 m_ext = 0x3E, // ext in1, in2, out1 // external insn, not microcode *F
603 m_f2i = 0x3F, // f2i l, d int(l) => d; convert fp -> integer +F
604 m_f2u = 0x40, // f2u l, d uint(l)=> d; convert fp -> uinteger +F
605 m_i2f = 0x41, // i2f l, d fp(l) => d; convert integer -> fp +F
606 m_u2f = 0x42, // i2f l, d fp(l) => d; convert uinteger -> fp +F
607 m_f2f = 0x43, // f2f l, d l => d; change fp precision +F
608 m_fneg = 0x44, // fneg l, d -l => d; change sign +F
609 m_fadd = 0x45, // fadd l, r, d l + r => d; add +F
610 m_fsub = 0x46, // fsub l, r, d l - r => d; subtract +F
611 m_fmul = 0x47, // fmul l, r, d l * r => d; multiply +F
612 m_fdiv = 0x48, // fdiv l, r, d l / r => d; divide +F
613#define m_max 0x49 // first unused opcode
614};
615
616/// Must an instruction with the given opcode be the last one in a block?
617/// Such opcodes are called closing opcodes.
618/// \param mcode instruction opcode
619/// \param including_calls should m_call/m_icall be considered as the closing opcodes?
620/// If this function returns true, the opcode cannot appear in the middle
621/// of a block. Calls are a special case: unknown calls (\ref is_unknown_call)
622/// are considered as closing opcodes.
623
624THREAD_SAFE bool hexapi must_mcode_close_block(mcode_t mcode, bool including_calls);
625
626
627/// May opcode be propagated?
628/// Such opcodes can be used in sub-instructions (nested instructions)
629/// There is a handful of non-propagatable opcodes, like jumps, ret, nop, etc
630/// All other regular opcodes are propagatable and may appear in a nested
631/// instruction.
632
633THREAD_SAFE bool hexapi is_mcode_propagatable(mcode_t mcode);
634
635
636// Is add or sub instruction?
637inline THREAD_SAFE bool is_mcode_addsub(mcode_t mcode) { return mcode == m_add || mcode == m_sub; }
638// Is xds or xdu instruction? We use 'xdsu' as a shortcut for 'xds or xdu'
639inline THREAD_SAFE bool is_mcode_xdsu(mcode_t mcode) { return mcode == m_xds || mcode == m_xdu; }
640// Is a 'set' instruction? (an instruction that sets a condition code)
641inline THREAD_SAFE bool is_mcode_set(mcode_t mcode) { return mcode >= m_sets && mcode <= m_setle; }
642// Is a 1-operand 'set' instruction? Only 'sets' is in this group
643inline THREAD_SAFE bool is_mcode_set1(mcode_t mcode) { return mcode == m_sets; }
644// Is a 1-operand conditional jump instruction? Only 'jcnd' is in this group
645inline THREAD_SAFE bool is_mcode_j1(mcode_t mcode) { return mcode == m_jcnd; }
646// Is a conditional jump?
647inline THREAD_SAFE bool is_mcode_jcond(mcode_t mcode) { return mcode >= m_jcnd && mcode <= m_jle; }
648// Is a 'set' instruction that can be converted into a conditional jump?
649inline THREAD_SAFE bool is_mcode_convertible_to_jmp(mcode_t mcode) { return mcode >= m_setnz && mcode <= m_setle; }
650// Is a conditional jump instruction that can be converted into a 'set'?
651inline THREAD_SAFE bool is_mcode_convertible_to_set(mcode_t mcode) { return mcode >= m_jnz && mcode <= m_jle; }
652// Is a call instruction? (direct or indirect)
653inline THREAD_SAFE bool is_mcode_call(mcode_t mcode) { return mcode == m_call || mcode == m_icall; }
654// Must be an FPU instruction?
655inline THREAD_SAFE bool is_mcode_fpu(mcode_t mcode) { return mcode >= m_f2i; }
656// Is a commutative instruction?
657inline THREAD_SAFE bool is_mcode_commutative(mcode_t mcode)
658{
659 return mcode == m_add
660 || mcode == m_mul
661 || mcode == m_or
662 || mcode == m_and
663 || mcode == m_xor
664 || mcode == m_setz
665 || mcode == m_setnz
666 || mcode == m_cfadd
667 || mcode == m_ofadd;
668}
669// Is a shift instruction?
670inline THREAD_SAFE bool is_mcode_shift(mcode_t mcode)
671{
672 return mcode == m_shl
673 || mcode == m_shr
674 || mcode == m_sar;
675}
676// Is a kind of div or mod instruction?
677inline THREAD_SAFE bool is_mcode_divmod(mcode_t op)
678{
679 return op == m_udiv || op == m_sdiv || op == m_umod || op == m_smod;
680}
681// Is an instruction with the selector/offset pair?
682inline THREAD_SAFE bool has_mcode_seloff(mcode_t op)
683{
684 return op == m_ldx || op == m_stx || op == m_icall || op == m_ijmp;
685}
686
687// Convert setX opcode into corresponding jX opcode
688// This function relies on the order of setX and jX opcodes!
689inline THREAD_SAFE mcode_t set2jcnd(mcode_t code)
690{
691 return mcode_t(code - m_setnz + m_jnz);
692}
693
694// Convert setX opcode into corresponding jX opcode
695// This function relies on the order of setX and jX opcodes!
696inline THREAD_SAFE mcode_t jcnd2set(mcode_t code)
697{
698 return mcode_t(code + m_setnz - m_jnz);
699}
700
701// Negate a conditional opcode.
702// Conditional jumps can be negated, example: jle -> jg
703// 'Set' instruction can be negated, example: seta -> setbe
704// If the opcode cannot be negated, return m_nop
705THREAD_SAFE mcode_t hexapi negate_mcode_relation(mcode_t code);
706
707
708// Swap a conditional opcode.
709// Only conditional jumps and set instructions can be swapped.
710// The returned opcode the one required for swapped operands.
711// Example "x > y" is the same as "y < x", therefore swap(m_jg) is m_jl.
712// If the opcode cannot be swapped, return m_nop
713
714THREAD_SAFE mcode_t hexapi swap_mcode_relation(mcode_t code);
715
716// Return the opcode that performs signed operation.
717// Examples: jae -> jge; udiv -> sdiv
718// If the opcode cannot be transformed into signed form, simply return it.
719
720THREAD_SAFE mcode_t hexapi get_signed_mcode(mcode_t code);
721
722
723// Return the opcode that performs unsigned operation.
724// Examples: jl -> jb; xds -> xdu
725// If the opcode cannot be transformed into unsigned form, simply return it.
726
727THREAD_SAFE mcode_t hexapi get_unsigned_mcode(mcode_t code);
728
729// Does the opcode perform a signed operation?
730inline THREAD_SAFE bool is_signed_mcode(mcode_t code) { return get_unsigned_mcode(code) != code; }
731// Does the opcode perform a unsigned operation?
732inline THREAD_SAFE bool is_unsigned_mcode(mcode_t code) { return get_signed_mcode(code) != code; }
733
734
735// Does the 'd' operand gets modified by the instruction?
736// Example: "add l,r,d" modifies d, while instructions
737// like jcnd, ijmp, stx does not modify it.
738// Note: this function returns 'true' for m_ext but it may be wrong.
739// Use minsn_t::modifies_d() if you have minsn_t.
740
741THREAD_SAFE bool hexapi mcode_modifies_d(mcode_t mcode);
742
743
744// Processor condition codes are mapped to the first microregisters
745// The order is important, see mop_t::is_cc()
746const mreg_t mr_none = mreg_t(-1);
747const mreg_t mr_cf = mreg_t(0); // carry bit
748const mreg_t mr_zf = mreg_t(1); // zero bit
749const mreg_t mr_sf = mreg_t(2); // sign bit
750const mreg_t mr_of = mreg_t(3); // overflow bit
751const mreg_t mr_pf = mreg_t(4); // parity bit
752const int cc_count = mr_pf - mr_cf + 1; // number of condition code registers
753const mreg_t mr_cc = mreg_t(5); // synthetic condition code, used internally
754const mreg_t mr_first = mreg_t(8); // the first processor specific register
755
756//-------------------------------------------------------------------------
757/// Operand locator.
758/// It is used to denote a particular operand in the ctree, for example,
759/// when the user right clicks on a constant and requests to represent it, say,
760/// as a hexadecimal number.
762{
763private:
764 // forbid the default constructor, force the user to initialize objects of this class.
765 operand_locator_t(void) {}
766public:
767 ea_t ea; ///< address of the original processor instruction
768 int opnum; ///< operand number in the instruction
769 operand_locator_t(ea_t _ea, int _opnum) : ea(_ea), opnum(_opnum) {}
770 DECLARE_COMPARISONS(operand_locator_t);
771 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
772};
773
774//-------------------------------------------------------------------------
775/// Number representation.
776/// This structure holds information about a number format.
778{
779 flags_t flags; ///< ida flags, which describe number radix, enum, etc
780 char opnum; ///< operand number: 0..UA_MAXOP
781 char props; ///< properties: combination of NF_ bits (\ref NF_)
782/// \defgroup NF_ Number format property bits
783/// Used in number_format_t::props
784//@{
785#define NF_FIXED 0x01 ///< number format has been defined by the user
786#define NF_NEGDONE 0x02 ///< temporary internal bit: negation has been performed
787#define NF_BINVDONE 0x04 ///< temporary internal bit: inverting bits is done
788#define NF_NEGATE 0x08 ///< The user asked to negate the constant
789#define NF_BITNOT 0x10 ///< The user asked to invert bits of the constant
790#define NF_VALID 0x20 ///< internal bit: stroff or enum is valid
791 ///< for enums: this bit is set immediately
792 ///< for stroffs: this bit is set at the end of decompilation
793//@}
794 uchar serial; ///< for enums: constant serial number
795 char org_nbytes; ///< original number size in bytes
796 qstring type_name; ///< for stroffs: structure for offsetof()\n
797 ///< for enums: enum name
798 /// Contructor
799 number_format_t(int _opnum=0)
800 : flags(0), opnum(char(_opnum)), props(0), serial(0), org_nbytes(0) {}
801 /// Get number radix
802 /// \return 2,8,10, or 16
803 int get_radix(void) const { return ::get_radix(flags, opnum); }
804 /// Is number representation fixed?
805 /// Fixed representation cannot be modified by the decompiler
806 bool is_fixed(void) const { return props != 0; }
807 /// Is a hexadecimal number?
808 bool is_hex(void) const { return ::is_numop(flags, opnum) && get_radix() == 16; }
809 /// Is a decimal number?
810 bool is_dec(void) const { return ::is_numop(flags, opnum) && get_radix() == 10; }
811 /// Is a octal number?
812 bool is_oct(void) const { return ::is_numop(flags, opnum) && get_radix() == 8; }
813 /// Is a symbolic constant?
814 bool is_enum(void) const { return ::is_enum(flags, opnum); }
815 /// Is a character constant?
816 bool is_char(void) const { return ::is_char(flags, opnum); }
817 /// Is a structure field offset?
818 bool is_stroff(void) const { return ::is_stroff(flags, opnum); }
819 /// Is a number?
820 bool is_numop(void) const { return !is_enum() && !is_char() && !is_stroff(); }
821 /// Does the number need to be negated or bitwise negated?
822 /// Returns true if the user requested a negation but it is not done yet
823 bool needs_to_be_inverted(void) const
824 {
825 return (props & (NF_NEGATE|NF_BITNOT)) != 0 // the user requested it
826 && (props & (NF_NEGDONE|NF_BINVDONE)) == 0; // not done yet
827 }
828 // symbolic constants and struct offsets cannot easily change
829 // their sign or size without a cast. only simple numbers can do that.
830 // for example, by modifying the expression type we can convert:
831 // 10u -> 10
832 // but replacing the type of a symbol constant would lead to an inconsistency.
833 bool has_unmutable_type() const
834 {
835 return (props & NF_VALID) != 0 && (is_stroff() || is_enum());
836 }
837 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
838};
839
840// Number formats are attached to (ea,opnum) pairs
841typedef std::map<operand_locator_t, number_format_t> user_numforms_t;
842
843//-------------------------------------------------------------------------
844/// Base helper class to convert binary data structures into text.
845/// Other classes are derived from this class.
847{
848 qstring tmpbuf;
849 int hdrlines; ///< number of header lines (prototype+typedef+lvars)
850 ///< valid at the end of print process
851 /// Print.
852 /// This function is called to generate a portion of the output text.
853 /// The output text may contain color codes.
854 /// \return the number of printed characters
855 /// \param indent number of spaces to generate as prefix
856 /// \param format printf-style format specifier
857 /// \return length of printed string
858 AS_PRINTF(3, 4) virtual int hexapi print(int indent, const char *format,...);
859 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
860};
861
862/// Helper class to convert cfunc_t into text.
864{
865 const cfunc_t *func; ///< cfunc_t to generate text for
866 char lastchar; ///< internal: last printed character
867 /// Constructor
868 vc_printer_t(const cfunc_t *f) : func(f), lastchar(0) {}
869 /// Are we generating one-line text representation?
870 /// \return \c true if the output will occupy one line without line breaks
871 virtual bool idaapi oneliner(void) const newapi { return false; }
872};
873
874/// Helper class to convert binary data structures into text and put into a file.
876{
877 FILE *fp; ///< Output file pointer
878 /// Print.
879 /// This function is called to generate a portion of the output text.
880 /// The output text may contain color codes.
881 /// \return the number of printed characters
882 /// \param indent number of spaces to generate as prefix
883 /// \param format printf-style format specifier
884 /// \return length of printed string
885 AS_PRINTF(3, 4) int hexapi print(int indent, const char *format, ...) override;
886 /// Constructor
887 file_printer_t(FILE *_fp) : fp(_fp) {}
888};
889
890/// Helper class to convert cfunc_t into a text string
892{
893 bool with_tags; ///< Generate output with color tags
894 qstring &s; ///< Reference to the output string
895 /// Constructor
896 qstring_printer_t(const cfunc_t *f, qstring &_s, bool tags)
897 : vc_printer_t(f), with_tags(tags), s(_s) {}
898 /// Print.
899 /// This function is called to generate a portion of the output text.
900 /// The output text may contain color codes.
901 /// \return the number of printed characters
902 /// \param indent number of spaces to generate as prefix
903 /// \param format printf-style format specifier
904 /// \return length of the printed string
905 AS_PRINTF(3, 4) int hexapi print(int indent, const char *format, ...) override;
906};
907
908//-------------------------------------------------------------------------
909/// \defgroup type Type string related declarations
910/// Type related functions and class.
911//@{
912
913/// Print the specified type info.
914/// This function can be used from a debugger by typing "tif->dstr()"
915
916const char *hexapi dstr(const tinfo_t *tif);
917
918
919/// Verify a type string.
920/// \return true if type string is correct
921
922bool hexapi is_type_correct(const type_t *ptr);
923
924
925/// Is a small structure or union?
926/// \return true if the type is a small UDT (user defined type).
927/// Small UDTs fit into a register (or pair or registers) as a rule.
928
929bool hexapi is_small_udt(const tinfo_t &tif);
930
931
932/// Is definitely a non-boolean type?
933/// \return true if the type is a non-boolean type (non bool and well defined)
934
935bool hexapi is_nonbool_type(const tinfo_t &type);
936
937
938/// Is a boolean type?
939/// \return true if the type is a boolean type
940
941bool hexapi is_bool_type(const tinfo_t &type);
942
943
944/// Is a pointer or array type?
945inline THREAD_SAFE bool is_ptr_or_array(type_t t)
946{
947 return is_type_ptr(t) || is_type_array(t);
948}
949
950/// Is a pointer, array, or function type?
951inline THREAD_SAFE bool is_paf(type_t t)
952{
953 return is_ptr_or_array(t) || is_type_func(t);
954}
955
956/// Is struct/union/enum definition (not declaration)?
957inline THREAD_SAFE bool is_inplace_def(const tinfo_t &type)
958{
959 return type.is_decl_complex() && !type.is_typeref();
960}
961
962/// Calculate number of partial subtypes.
963/// \return number of partial subtypes. The bigger is this number, the uglier is the type.
964
965int hexapi partial_type_num(const tinfo_t &type);
966
967
968/// Get a type of a floating point value with the specified width
969/// \returns type info object
970/// \param width width of the desired type
971
972tinfo_t hexapi get_float_type(int width);
973
974
975/// Create a type info by width and sign.
976/// Returns a simple type (examples: int, short) with the given width and sign.
977/// \param srcwidth size of the type in bytes
978/// \param sign sign of the type
979
980tinfo_t hexapi get_int_type_by_width_and_sign(int srcwidth, type_sign_t sign);
981
982
983/// Create a partial type info by width.
984/// Returns a partially defined type (examples: _DWORD, _BYTE) with the given width.
985/// \param size size of the type in bytes
986
987tinfo_t hexapi get_unk_type(int size);
988
989
990/// Generate a dummy pointer type
991/// \param ptrsize size of pointed object
992/// \param isfp is floating point object?
993
994tinfo_t hexapi dummy_ptrtype(int ptrsize, bool isfp);
995
996
997/// Get type of a structure field.
998/// This function performs validity checks of the field type. Wrong types are rejected.
999/// \param mptr structure field
1000/// \param type pointer to the variable where the type is returned. This parameter can be nullptr.
1001/// \return false if failed
1002
1003bool hexapi get_member_type(const member_t *mptr, tinfo_t *type);
1004
1005
1006/// Create a pointer type.
1007/// This function performs the following conversion: "type" -> "type*"
1008/// \param type object type.
1009/// \return "type*". for example, if 'char' is passed as the argument,
1010// the function will return 'char *'
1011
1012tinfo_t hexapi make_pointer(const tinfo_t &type);
1013
1014
1015/// Create a reference to a named type.
1016/// \param name type name
1017/// \return type which refers to the specified name. For example, if name is "DWORD",
1018/// the type info which refers to "DWORD" is created.
1019
1020tinfo_t hexapi create_typedef(const char *name);
1021
1022
1023/// Create a reference to an ordinal type.
1024/// \param n ordinal number of the type
1025/// \return type which refers to the specified ordinal. For example, if n is 1,
1026/// the type info which refers to ordinal type 1 is created.
1027
1028inline tinfo_t create_typedef(int n)
1029{
1030 tinfo_t tif;
1031 tif.create_typedef(nullptr, n);
1032 return tif;
1033}
1034
1035/// Type source (where the type information comes from)
1037{
1038 GUESSED_NONE, // not guessed, specified by the user
1039 GUESSED_WEAK, // not guessed, comes from idb
1040 GUESSED_FUNC, // guessed as a function
1041 GUESSED_DATA, // guessed as a data item
1042 TS_NOELL = 0x8000000, // can be used in set_type() to avoid merging into ellipsis
1043 TS_SHRINK = 0x4000000, // can be used in set_type() to prefer smaller arguments
1044 TS_DONTREF = 0x2000000, // do not mark type as referenced (referenced_types)
1045 TS_MASK = 0xE000000, // all high bits
1046};
1047
1048
1049/// Get a global type.
1050/// Global types are types of addressable objects and struct/union/enum types
1051/// \param id address or id of the object
1052/// \param tif buffer for the answer
1053/// \param guess what kind of types to consider
1054/// \return success
1055
1056bool hexapi get_type(uval_t id, tinfo_t *tif, type_source_t guess);
1057
1058
1059/// Set a global type.
1060/// \param id address or id of the object
1061/// \param tif new type info
1062/// \param source where the type comes from
1063/// \param force true means to set the type as is, false means to merge the
1064/// new type with the possibly existing old type info.
1065/// \return success
1066
1067bool hexapi set_type(uval_t id, const tinfo_t &tif, type_source_t source, bool force=false);
1068
1069//@}
1070
1071//-------------------------------------------------------------------------
1072// We use our own class to store argument and variable locations.
1073// It is called vdloc_t that stands for 'vd location'.
1074// 'vd' is the internal name of the decompiler, it stands for 'visual decompiler'.
1075// The main differences between vdloc and argloc_t:
1076// ALOC_REG1: the offset is always 0, so it is not used. the register number
1077// uses the whole ~VLOC_MASK field.
1078// ALOCK_STKOFF: stack offsets are always positive because they are based on
1079// the lowest value of sp in the function.
1080class vdloc_t : public argloc_t
1081{
1082 int regoff(void); // inaccessible & undefined: regoff() should not be used
1083public:
1084 // Get the register number.
1085 // This function works only for ALOC_REG1 and ALOC_REG2 location types.
1086 // It uses all available bits for register number for ALOC_REG1
1087 int reg1(void) const { return atype() == ALOC_REG2 ? argloc_t::reg1() : get_reginfo(); }
1088
1089 // Set vdloc to point to the specified register without cleaning it up.
1090 // This is a dangerous function, use set_reg1() instead unless you understand
1091 // what it means to cleanup an argloc.
1092 void _set_reg1(int r1) { argloc_t::_set_reg1(r1, r1>>16); }
1093
1094 // Set vdloc to point to the specified register.
1095 void set_reg1(int r1) { cleanup_argloc(this); _set_reg1(r1); }
1096
1097 // Use member functions of argloc_t for other location types.
1098
1099 // Return textual representation.
1100 // Note: this and all other dstr() functions can be used from a debugger.
1101 // It is much easier than to inspect the memory contents byte by byte.
1102 const char *hexapi dstr(int width=0) const;
1103 DECLARE_COMPARISONS(vdloc_t);
1104 bool hexapi is_aliasable(const mba_t *mb, int size) const;
1105};
1106
1107/// Print vdloc.
1108/// Since vdloc does not always carry the size info, we pass it as NBYTES..
1109void hexapi print_vdloc(qstring *vout, const vdloc_t &loc, int nbytes);
1110
1111//-------------------------------------------------------------------------
1112/// Do two arglocs overlap?
1113bool hexapi arglocs_overlap(const vdloc_t &loc1, size_t w1, const vdloc_t &loc2, size_t w2);
1114
1115/// Local variable locator.
1116/// Local variables are located using definition ea and location.
1117/// Each variable must have a unique locator, this is how we tell them apart.
1119{
1120 vdloc_t location; ///< Variable location.
1121 ea_t defea; ///< Definition address. Usually, this is the address
1122 ///< of the instruction that initializes the variable.
1123 ///< In some cases it can be a fictional address.
1124
1125 lvar_locator_t(void) : defea(BADADDR) {}
1126 lvar_locator_t(const vdloc_t &loc, ea_t ea) : location(loc), defea(ea) {}
1127 /// Get offset of the varialbe in the stack frame.
1128 /// \return a non-negative value for stack variables. The value is
1129 /// an offset from the bottom of the stack frame in terms of
1130 /// vd-offsets.
1131 /// negative values mean error (not a stack variable)
1132 sval_t get_stkoff(void) const
1133 {
1134 return location.is_stkoff() ? location.stkoff() : -1;
1135 }
1136 /// Is variable located on one register?
1137 bool is_reg1(void) const { return location.is_reg1(); }
1138 /// Is variable located on two registers?
1139 bool is_reg2(void) const { return location.is_reg2(); }
1140 /// Is variable located on register(s)?
1141 bool is_reg_var(void) const { return location.is_reg(); }
1142 /// Is variable located on the stack?
1143 bool is_stk_var(void) const { return location.is_stkoff(); }
1144 /// Is variable scattered?
1145 bool is_scattered(void) const { return location.is_scattered(); }
1146 /// Get the register number of the variable
1147 mreg_t get_reg1(void) const { return location.reg1(); }
1148 /// Get the number of the second register (works only for ALOC_REG2 lvars)
1149 mreg_t get_reg2(void) const { return location.reg2(); }
1150 /// Get information about scattered variable
1151 const scattered_aloc_t &get_scattered(void) const { return location.scattered(); }
1152 scattered_aloc_t &get_scattered(void) { return location.scattered(); }
1153 DECLARE_COMPARISONS(lvar_locator_t);
1154 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
1155 // Debugging: get textual representation of a lvar locator.
1156 const char *hexapi dstr(void) const;
1157};
1158
1159/// Definition of a local variable (register or stack) #var #lvar
1161{
1162 friend class mba_t;
1163 int flags; ///< \ref CVAR_
1164/// \defgroup CVAR_ Local variable property bits
1165/// Used in lvar_t::flags
1166//@{
1167#define CVAR_USED 0x00000001 ///< is used in the code?
1168#define CVAR_TYPE 0x00000002 ///< the type is defined?
1169#define CVAR_NAME 0x00000004 ///< has nice name?
1170#define CVAR_MREG 0x00000008 ///< corresponding mregs were replaced?
1171#define CVAR_NOWD 0x00000010 ///< width is unknown
1172#define CVAR_UNAME 0x00000020 ///< user-defined name
1173#define CVAR_UTYPE 0x00000040 ///< user-defined type
1174#define CVAR_RESULT 0x00000080 ///< function result variable
1175#define CVAR_ARG 0x00000100 ///< function argument
1176#define CVAR_FAKE 0x00000200 ///< fake variable (return var or va_list)
1177#define CVAR_OVER 0x00000400 ///< overlapping variable
1178#define CVAR_FLOAT 0x00000800 ///< used in a fpu insn
1179#define CVAR_SPOILED 0x00001000 ///< internal flag, do not use: spoiled var
1180#define CVAR_MAPDST 0x00002000 ///< other variables are mapped to this var
1181#define CVAR_PARTIAL 0x00004000 ///< variable type is partialy defined
1182#define CVAR_THISARG 0x00008000 ///< 'this' argument of c++ member functions
1183#define CVAR_FORCED 0x00010000 ///< variable was created by an explicit request
1184 ///< otherwise we could reuse an existing var
1185#define CVAR_REGNAME 0x00020000 ///< has a register name (like _RAX): if lvar
1186 ///< is used by an m_ext instruction
1187#define CVAR_NOPTR 0x00040000 ///< variable cannot be a pointer (user choice)
1188#define CVAR_DUMMY 0x00080000 ///< dummy argument (added to fill a hole in
1189 ///< the argument list)
1190#define CVAR_NOTARG 0x00100000 ///< variable cannot be an input argument
1191#define CVAR_AUTOMAP 0x00200000 ///< variable was automatically mapped
1192#define CVAR_BYREF 0x00400000 ///< the address of the variable was taken
1193#define CVAR_INASM 0x00800000 ///< variable is used in instructions translated
1194 ///< into __asm {...}
1195#define CVAR_UNUSED 0x01000000 ///< user-defined __unused attribute
1196 ///< meaningful only if: is_arg_var() && !mba->final_type
1197#define CVAR_SHARED 0x02000000 ///< variable is mapped to several chains
1198//@}
1199
1200public:
1201 qstring name; ///< variable name.
1202 ///< use mba_t::set_nice_lvar_name() and
1203 ///< mba_t::set_user_lvar_name() to modify it
1204 qstring cmt; ///< variable comment string
1205 tinfo_t tif; ///< variable type
1206 int width = 0; ///< variable size in bytes
1207 int defblk = -1; ///< first block defining the variable.
1208 ///< 0 for args, -1 if unknown
1209 uint64 divisor = 0; ///< max known divisor of the variable
1210
1211 lvar_t(void) : flags(CVAR_USED) {}
1212 lvar_t(const qstring &n, const vdloc_t &l, ea_t e, const tinfo_t &t, int w, int db)
1213 : lvar_locator_t(l, e), flags(CVAR_USED), name(n), tif(t), width(w), defblk(db)
1214 {
1215 }
1216 // Debugging: get textual representation of a local variable.
1217 const char *hexapi dstr(void) const;
1218
1219 /// Is the variable used in the code?
1220 bool used(void) const { return (flags & CVAR_USED) != 0; }
1221 /// Has the variable a type?
1222 bool typed(void) const { return (flags & CVAR_TYPE) != 0; }
1223 /// Have corresponding microregs been replaced by references to this variable?
1224 bool mreg_done(void) const { return (flags & CVAR_MREG) != 0; }
1225 /// Does the variable have a nice name?
1226 bool has_nice_name(void) const { return (flags & CVAR_NAME) != 0; }
1227 /// Do we know the width of the variable?
1228 bool is_unknown_width(void) const { return (flags & CVAR_NOWD) != 0; }
1229 /// Has any user-defined information?
1230 bool has_user_info(void) const
1231 {
1232 return (flags & (CVAR_UNAME|CVAR_UTYPE|CVAR_NOPTR|CVAR_UNUSED)) != 0
1233 || !cmt.empty();
1234 }
1235 /// Has user-defined name?
1236 bool has_user_name(void) const { return (flags & CVAR_UNAME) != 0; }
1237 /// Has user-defined type?
1238 bool has_user_type(void) const { return (flags & CVAR_UTYPE) != 0; }
1239 /// Is the function result?
1240 bool is_result_var(void) const { return (flags & CVAR_RESULT) != 0; }
1241 /// Is the function argument?
1242 bool is_arg_var(void) const { return (flags & CVAR_ARG) != 0; }
1243 /// Is the promoted function argument?
1244 bool hexapi is_promoted_arg(void) const;
1245 /// Is fake return variable?
1246 bool is_fake_var(void) const { return (flags & CVAR_FAKE) != 0; }
1247 /// Is overlapped variable?
1248 bool is_overlapped_var(void) const { return (flags & CVAR_OVER) != 0; }
1249 /// Used by a fpu insn?
1250 bool is_floating_var(void) const { return (flags & CVAR_FLOAT) != 0; }
1251 /// Is spoiled var? (meaningful only during lvar allocation)
1252 bool is_spoiled_var(void) const { return (flags & CVAR_SPOILED) != 0; }
1253 /// Variable type should be handled as a partial one
1254 bool is_partialy_typed(void) const { return (flags & CVAR_PARTIAL) != 0; }
1255 /// Variable type should not be a pointer
1256 bool is_noptr_var(void) const { return (flags & CVAR_NOPTR) != 0; }
1257 /// Other variable(s) map to this var?
1258 bool is_mapdst_var(void) const { return (flags & CVAR_MAPDST) != 0; }
1259 /// Is 'this' argument of a C++ member function?
1260 bool is_thisarg(void) const { return (flags & CVAR_THISARG) != 0; }
1261 /// Is a forced variable?
1262 bool is_forced_var(void) const { return (flags & CVAR_FORCED) != 0; }
1263 /// Has a register name? (like _RAX)
1264 bool has_regname(void) const { return (flags & CVAR_REGNAME) != 0; }
1265 /// Is variable used in an instruction translated into __asm?
1266 bool in_asm(void) const { return (flags & CVAR_INASM) != 0; }
1267 /// Is a dummy argument (added to fill a hole in the argument list)
1268 bool is_dummy_arg(void) const { return (flags & CVAR_DUMMY) != 0; }
1269 /// Is a local variable? (local variable cannot be an input argument)
1270 bool is_notarg(void) const { return (flags & CVAR_NOTARG) != 0; }
1271 /// Was the variable automatically mapped to another variable?
1272 bool is_automapped(void) const { return (flags & CVAR_AUTOMAP) != 0; }
1273 /// Was the address of the variable taken?
1274 bool is_used_byref(void) const { return (flags & CVAR_BYREF) != 0; }
1275 /// Was declared as __unused by the user? See CVAR_UNUSED
1276 bool is_decl_unused(void) const { return (flags & CVAR_UNUSED) != 0; }
1277 /// Is lvar mapped to several chains
1278 bool is_shared(void) const { return (flags & CVAR_SHARED) != 0; }
1279 void set_used(void) { flags |= CVAR_USED; }
1280 void clear_used(void) { flags &= ~CVAR_USED; }
1281 void set_typed(void) { flags |= CVAR_TYPE; clr_noptr_var(); }
1282 void set_non_typed(void) { flags &= ~CVAR_TYPE; }
1283 void clr_user_info(void) { flags &= ~(CVAR_UNAME|CVAR_UTYPE|CVAR_NOPTR); }
1284 void set_user_name(void) { flags |= CVAR_NAME|CVAR_UNAME; }
1285 void set_user_type(void) { flags |= CVAR_TYPE|CVAR_UTYPE; }
1286 void clr_user_type(void) { flags &= ~CVAR_UTYPE; }
1287 void clr_user_name(void) { flags &= ~CVAR_UNAME; }
1288 void set_mreg_done(void) { flags |= CVAR_MREG; }
1289 void clr_mreg_done(void) { flags &= ~CVAR_MREG; }
1290 void set_unknown_width(void) { flags |= CVAR_NOWD; }
1291 void clr_unknown_width(void) { flags &= ~CVAR_NOWD; }
1292 void set_arg_var(void) { flags |= CVAR_ARG; }
1293 void clr_arg_var(void) { flags &= ~(CVAR_ARG|CVAR_THISARG); }
1294 void set_fake_var(void) { flags |= CVAR_FAKE; }
1295 void clr_fake_var(void) { flags &= ~CVAR_FAKE; }
1296 void set_overlapped_var(void) { flags |= CVAR_OVER; }
1297 void clr_overlapped_var(void) { flags &= ~CVAR_OVER; }
1298 void set_floating_var(void) { flags |= CVAR_FLOAT; }
1299 void clr_floating_var(void) { flags &= ~CVAR_FLOAT; }
1300 void set_spoiled_var(void) { flags |= CVAR_SPOILED; }
1301 void clr_spoiled_var(void) { flags &= ~CVAR_SPOILED; }
1302 void set_mapdst_var(void) { flags |= CVAR_MAPDST; }
1303 void clr_mapdst_var(void) { flags &= ~CVAR_MAPDST; }
1304 void set_partialy_typed(void) { flags |= CVAR_PARTIAL; }
1305 void clr_partialy_typed(void) { flags &= ~CVAR_PARTIAL; }
1306 void set_noptr_var(void) { flags |= CVAR_NOPTR; }
1307 void clr_noptr_var(void) { flags &= ~CVAR_NOPTR; }
1308 void set_thisarg(void) { flags |= CVAR_THISARG; }
1309 void clr_thisarg(void) { flags &= ~CVAR_THISARG; }
1310 void set_forced_var(void) { flags |= CVAR_FORCED; }
1311 void clr_forced_var(void) { flags &= ~CVAR_FORCED; }
1312 void set_dummy_arg(void) { flags |= CVAR_DUMMY; }
1313 void clr_dummy_arg(void) { flags &= ~CVAR_DUMMY; }
1314 void set_notarg(void) { clr_arg_var(); flags |= CVAR_NOTARG; }
1315 void clr_notarg(void) { flags &= ~CVAR_NOTARG; }
1316 void set_automapped(void) { flags |= CVAR_AUTOMAP; }
1317 void clr_automapped(void) { flags &= ~CVAR_AUTOMAP; }
1318 void set_used_byref(void) { flags |= CVAR_BYREF; }
1319 void clr_used_byref(void) { flags &= ~CVAR_BYREF; }
1320 void set_decl_unused(void) { flags |= CVAR_UNUSED; }
1321 void clr_decl_unused(void) { flags &= ~CVAR_UNUSED; }
1322 void set_shared(void) { flags |= CVAR_SHARED; }
1323 void clr_shared(void) { flags &= ~CVAR_SHARED; }
1324
1325 /// Do variables overlap?
1326 bool has_common(const lvar_t &v) const
1327 {
1328 return arglocs_overlap(location, width, v.location, v.width);
1329 }
1330 /// Does the variable overlap with the specified location?
1331 bool has_common_bit(const vdloc_t &loc, asize_t width2) const
1332 {
1333 return arglocs_overlap(location, width, loc, width2);
1334 }
1335 /// Get variable type
1336 const tinfo_t &type(void) const { return tif; }
1337 tinfo_t &type(void) { return tif; }
1338
1339 /// Check if the variable accept the specified type.
1340 /// Some types are forbidden (void, function types, wrong arrays, etc)
1341 bool hexapi accepts_type(const tinfo_t &t, bool may_change_thisarg=false);
1342 /// Set variable type
1343 /// Note: this function does not modify the idb, only the lvar instance
1344 /// in the memory. For permanent changes see modify_user_lvars()
1345 /// Also, the variable type is not considered as final by the decompiler
1346 /// and may be modified later by the type derivation.
1347 /// In some cases set_final_var_type() may work better, but it does not
1348 /// do persistent changes to the database neither.
1349 /// \param t new type
1350 /// \param may_fail if false and type is bad, interr
1351 /// \return success
1352 bool hexapi set_lvar_type(const tinfo_t &t, bool may_fail=false);
1353
1354 /// Set final variable type.
1355 void set_final_lvar_type(const tinfo_t &t)
1356 {
1357 set_lvar_type(t);
1358 set_typed();
1359 }
1360
1361 /// Change the variable width.
1362 /// We call the variable size 'width', it is represents the number of bytes.
1363 /// This function may change the variable type using set_lvar_type().
1364 /// \param w new width
1365 /// \param svw_flags combination of SVW_... bits
1366 /// \return success
1367 bool hexapi set_width(int w, int svw_flags=0);
1368#define SVW_INT 0x00 // integer value
1369#define SVW_FLOAT 0x01 // floating point value
1370#define SVW_SOFT 0x02 // may fail and return false;
1371 // if this bit is not set and the type is bad, interr
1372
1373 /// Append local variable to mlist.
1374 /// \param mba ptr to the current mba_t
1375 /// \param lst list to append to
1376 /// \param pad_if_scattered if true, append padding bytes in case of scattered lvar
1377 void hexapi append_list(const mba_t *mba, mlist_t *lst, bool pad_if_scattered=false) const;
1378
1379 /// Is the variable aliasable?
1380 /// \param mba ptr to the current mba_t
1381 /// Aliasable variables may be modified indirectly (through a pointer)
1382 bool is_aliasable(const mba_t *mba) const
1383 {
1384 return location.is_aliasable(mba, width);
1385 }
1386
1387};
1388DECLARE_TYPE_AS_MOVABLE(lvar_t);
1389
1390/// Vector of local variables
1391struct lvars_t : public qvector<lvar_t>
1392{
1393 /// Find input variable at the specified location.
1394 /// \param argloc variable location
1395 /// \param _size variable size
1396 /// \return -1 if failed, otherwise the index into the variables vector.
1397 int find_input_lvar(const vdloc_t &argloc, int _size) { return find_lvar(argloc, _size, 0); }
1398
1399
1400 /// Find stack variable at the specified location.
1401 /// \param spoff offset from the minimal sp
1402 /// \param width variable size
1403 /// \return -1 if failed, otherwise the index into the variables vector.
1404 int hexapi find_stkvar(sval_t spoff, int width);
1405
1406
1407 /// Find variable at the specified location.
1408 /// \param ll variable location
1409 /// \return pointer to variable or nullptr
1410 lvar_t *hexapi find(const lvar_locator_t &ll);
1411
1412
1413 /// Find variable at the specified location.
1414 /// \param location variable location
1415 /// \param width variable size
1416 /// \param defblk definition block of the lvar. -1 means any block
1417 /// \return -1 if failed, otherwise the index into the variables vector.
1418 int hexapi find_lvar(const vdloc_t &location, int width, int defblk=-1) const;
1419};
1420
1421/// Saved user settings for local variables: name, type, comment.
1423{
1424 lvar_locator_t ll; ///< Variable locator
1425 qstring name; ///< Name
1426 tinfo_t type; ///< Type
1427 qstring cmt; ///< Comment
1428 ssize_t size; ///< Type size (if not initialized then -1)
1429 int flags; ///< \ref LVINF_
1430/// \defgroup LVINF_ saved user lvar info property bits
1431/// Used in lvar_saved_info_t::flags
1432//@{
1433#define LVINF_KEEP 0x0001 ///< preserve saved user settings regardless of vars
1434 ///< for example, if a var loses all its
1435 ///< user-defined attributes or even gets
1436 ///< destroyed, keep its lvar_saved_info_t.
1437 ///< this is used for ephemeral variables that
1438 ///< get destroyed by macro recognition.
1439#define LVINF_FORCE 0x0002 ///< force allocation of a new variable.
1440 ///< forces the decompiler to create a new
1441 ///< variable at ll.defea
1442#define LVINF_NOPTR 0x0004 ///< variable type should not be a pointer
1443#define LVINF_NOMAP 0x0008 ///< forbid automatic mapping of the variable
1444#define LVINF_UNUSED 0x0010 ///< unused argument, corresponds to CVAR_UNUSED
1445//@}
1446 lvar_saved_info_t(void) : size(BADSIZE), flags(0) {}
1447 bool has_info(void) const
1448 {
1449 return !name.empty()
1450 || !type.empty()
1451 || !cmt.empty()
1452 || is_forced_lvar()
1453 || is_noptr_lvar()
1454 || is_nomap_lvar();
1455 }
1456 bool operator==(const lvar_saved_info_t &r) const
1457 {
1458 return name == r.name
1459 && cmt == r.cmt
1460 && ll == r.ll
1461 && type == r.type;
1462 }
1463 bool operator!=(const lvar_saved_info_t &r) const { return !(*this == r); }
1464 bool is_kept(void) const { return (flags & LVINF_KEEP) != 0; }
1465 void clear_keep(void) { flags &= ~LVINF_KEEP; }
1466 void set_keep(void) { flags |= LVINF_KEEP; }
1467 bool is_forced_lvar(void) const { return (flags & LVINF_FORCE) != 0; }
1468 void set_forced_lvar(void) { flags |= LVINF_FORCE; }
1469 void clr_forced_lvar(void) { flags &= ~LVINF_FORCE; }
1470 bool is_noptr_lvar(void) const { return (flags & LVINF_NOPTR) != 0; }
1471 void set_noptr_lvar(void) { flags |= LVINF_NOPTR; }
1472 void clr_noptr_lvar(void) { flags &= ~LVINF_NOPTR; }
1473 bool is_nomap_lvar(void) const { return (flags & LVINF_NOMAP) != 0; }
1474 void set_nomap_lvar(void) { flags |= LVINF_NOMAP; }
1475 void clr_nomap_lvar(void) { flags &= ~LVINF_NOMAP; }
1476 bool is_unused_lvar(void) const { return (flags & LVINF_UNUSED) != 0; }
1477 void set_unused_lvar(void) { flags |= LVINF_UNUSED; }
1478 void clr_unused_lvar(void) { flags &= ~LVINF_UNUSED; }
1479};
1480DECLARE_TYPE_AS_MOVABLE(lvar_saved_info_t);
1481typedef qvector<lvar_saved_info_t> lvar_saved_infos_t;
1482
1483/// Local variable mapping (is used to merge variables)
1484typedef std::map<lvar_locator_t, lvar_locator_t> lvar_mapping_t;
1485
1486/// All user-defined information about local variables
1488{
1489 /// User-specified names, types, comments for lvars. Variables without
1490 /// user-specified info are not present in this vector.
1491 lvar_saved_infos_t lvvec;
1492
1493 /// Local variable mapping (used for merging variables)
1495
1496 /// Delta to add to IDA stack offset to calculate Hex-Rays stack offsets.
1497 /// Should be set by the caller before calling save_user_lvar_settings();
1499
1500 /// Various flags. Possible values are from \ref ULV_
1502/// \defgroup ULV_ lvar_uservec_t property bits
1503/// Used in lvar_uservec_t::ulv_flags
1504//@{
1505#define ULV_PRECISE_DEFEA 0x0001 ///< Use precise defea's for lvar locations
1506//@}
1507
1508 lvar_uservec_t(void) : stkoff_delta(0), ulv_flags(ULV_PRECISE_DEFEA) {}
1509 void swap(lvar_uservec_t &r)
1510 {
1511 lvvec.swap(r.lvvec);
1512 lmaps.swap(r.lmaps);
1513 std::swap(stkoff_delta, r.stkoff_delta);
1514 std::swap(ulv_flags, r.ulv_flags);
1515 }
1516 void clear()
1517 {
1518 lvvec.clear();
1519 lmaps.clear();
1520 stkoff_delta = 0;
1521 ulv_flags = ULV_PRECISE_DEFEA;
1522 }
1523 bool empty() const
1524 {
1525 return lvvec.empty()
1526 && lmaps.empty()
1527 && stkoff_delta == 0
1528 && ulv_flags == ULV_PRECISE_DEFEA;
1529 }
1530
1531 /// find saved user settings for given var
1533 {
1534 for ( lvar_saved_infos_t::iterator p=lvvec.begin(); p != lvvec.end(); ++p )
1535 {
1536 if ( p->ll == vloc )
1537 return p;
1538 }
1539 return nullptr;
1540 }
1541
1542 /// Preserve user settings for given var
1543 void keep_info(const lvar_t &v)
1544 {
1545 lvar_saved_info_t *p = find_info(v);
1546 if ( p != nullptr )
1547 p->set_keep();
1548 }
1549};
1550
1551/// Restore user defined local variable settings in the database.
1552/// \param func_ea entry address of the function
1553/// \param lvinf ptr to output buffer
1554/// \return success
1555
1556bool hexapi restore_user_lvar_settings(lvar_uservec_t *lvinf, ea_t func_ea);
1557
1558
1559/// Save user defined local variable settings into the database.
1560/// \param func_ea entry address of the function
1561/// \param lvinf user-specified info about local variables
1562
1563void hexapi save_user_lvar_settings(ea_t func_ea, const lvar_uservec_t &lvinf);
1564
1565
1566/// Helper class to modify saved local variable settings.
1568{
1569 /// Modify lvar settings.
1570 /// Returns: true-modified
1571 virtual bool idaapi modify_lvars(lvar_uservec_t *lvinf) = 0;
1572};
1573
1574/// Modify saved local variable settings.
1575/// \param entry_ea function start address
1576/// \param mlv local variable modifier
1577/// \return true if modified variables
1578
1579bool hexapi modify_user_lvars(ea_t entry_ea, user_lvar_modifier_t &mlv);
1580
1581
1582/// Modify saved local variable settings of one variable.
1583/// \param func_ea function start address
1584/// \param info local variable info attrs
1585/// \param mli_flags bits that specify which attrs defined by INFO are to be set
1586/// \return true if modified, false if invalid MLI_FLAGS passed
1587
1589 ea_t func_ea,
1590 uint mli_flags,
1591 const lvar_saved_info_t &info);
1592
1593/// \defgroup MLI_ user info bits
1594//@{
1595#define MLI_NAME 0x01 ///< apply lvar name
1596#define MLI_TYPE 0x02 ///< apply lvar type
1597#define MLI_CMT 0x04 ///< apply lvar comment
1598#define MLI_SET_FLAGS 0x08 ///< set LVINF_... bits
1599#define MLI_CLR_FLAGS 0x10 ///< clear LVINF_... bits
1600//@}
1601
1602
1603/// Find a variable by name.
1604/// \param out output buffer for the variable locator
1605/// \param func_ea function start address
1606/// \param varname variable name
1607/// \return success
1608/// Since VARNAME is not always enough to find the variable, it may decompile
1609/// the function.
1610
1611bool hexapi locate_lvar(
1612 lvar_locator_t *out,
1613 ea_t func_ea,
1614 const char *varname);
1615
1616
1617/// Rename a local variable.
1618/// \param func_ea function start address
1619/// \param oldname old name of the variable
1620/// \param newname new name of the variable
1621/// \return success
1622/// This is a convenience function.
1623/// For bulk renaming consider using modify_user_lvars.
1624
1625inline bool rename_lvar(
1626 ea_t func_ea,
1627 const char *oldname,
1628 const char *newname)
1629{
1630 lvar_saved_info_t info;
1631 if ( !locate_lvar(&info.ll, func_ea, oldname) )
1632 return false;
1633 info.name = newname;
1634 return modify_user_lvar_info(func_ea, MLI_NAME, info);
1635}
1636
1637//-------------------------------------------------------------------------
1638/// User-defined function calls
1640{
1641 qstring name; // name of the function
1642 tinfo_t tif; // function prototype
1643 DECLARE_COMPARISONS(udcall_t)
1644 {
1645 int code = ::compare(name, r.name);
1646 if ( code == 0 )
1647 code = ::compare(tif, r.tif);
1648 return code;
1649 }
1650
1651 bool empty() const { return name.empty() && tif.empty(); }
1652};
1653
1654// All user-defined function calls (map address -> udcall)
1655typedef std::map<ea_t, udcall_t> udcall_map_t;
1656
1657/// Restore user defined function calls from the database.
1658/// \param udcalls ptr to output buffer
1659/// \param func_ea entry address of the function
1660/// \return success
1661
1662bool hexapi restore_user_defined_calls(udcall_map_t *udcalls, ea_t func_ea);
1663
1664
1665/// Save user defined local function calls into the database.
1666/// \param func_ea entry address of the function
1667/// \param udcalls user-specified info about user defined function calls
1668
1669void hexapi save_user_defined_calls(ea_t func_ea, const udcall_map_t &udcalls);
1670
1671
1672/// Convert function type declaration into internal structure
1673/// \param udc - pointer to output structure
1674/// \param decl - function type declaration
1675/// \param silent - if TRUE: do not show warning in case of incorrect type
1676/// \return success
1677
1678bool hexapi parse_user_call(udcall_t *udc, const char *decl, bool silent);
1679
1680
1681/// try to generate user-defined call for an instruction
1682/// \return \ref MERR_ code:
1683/// MERR_OK - user-defined call generated
1684/// else - error (MERR_INSN == inacceptable udc.tif)
1685
1687
1688
1689//-------------------------------------------------------------------------
1690/// Generic microcode generator class.
1691/// An instance of a derived class can be registered to be used for
1692/// non-standard microcode generation. Before microcode generation for an
1693/// instruction all registered object will be visited by the following way:
1694/// if ( filter->match(cdg) )
1695/// code = filter->apply(cdg);
1696/// if ( code == MERR_OK )
1697/// continue; // filter generated microcode, go to the next instruction
1699{
1700 /// check if the filter object is to be applied
1701 /// \return success
1702 virtual bool match(codegen_t &cdg) = 0;
1703
1704 /// generate microcode for an instruction
1705 /// \return MERR_... code:
1706 /// MERR_OK - user-defined microcode generated, go to the next instruction
1707 /// MERR_INSN - not generated - the caller should try the standard way
1708 /// else - error
1709 virtual merror_t apply(codegen_t &cdg) = 0;
1710};
1711
1712/// register/unregister non-standard microcode generator
1713/// \param filter - microcode generator object
1714/// \param install - TRUE - register the object, FALSE - unregister
1715/// \return success
1716bool hexapi install_microcode_filter(microcode_filter_t *filter, bool install=true);
1717
1718//-------------------------------------------------------------------------
1719/// Abstract class: User-defined call generator
1720/// derived classes should implement method 'match'
1722{
1723 udcall_t udc;
1724
1725public:
1726 ~udc_filter_t() { cleanup(); }
1727
1728 /// Cleanup the filter
1729 /// This function properly clears type information associated to this filter.
1730 void hexapi cleanup(void);
1731
1732 /// return true if the filter object should be applied to given instruction
1733 virtual bool match(codegen_t &cdg) override = 0;
1734
1735 bool hexapi init(const char *decl);
1736 virtual merror_t hexapi apply(codegen_t &cdg) override;
1737
1738 bool empty(void) const { return udc.empty(); }
1739};
1740
1741//-------------------------------------------------------------------------
1742typedef size_t mbitmap_t;
1743const size_t bitset_width = sizeof(mbitmap_t) * CHAR_BIT;
1744const size_t bitset_align = bitset_width - 1;
1745const size_t bitset_shift = 6;
1746
1747/// Bit set class. See https://en.wikipedia.org/wiki/Bit_array
1749{
1750 mbitmap_t *bitmap; ///< pointer to bitmap
1751 size_t high; ///< highest bit+1 (multiply of bitset_width)
1752
1753public:
1754 bitset_t(void) : bitmap(nullptr), high(0) {}
1755 hexapi bitset_t(const bitset_t &m); // copy constructor
1756 ~bitset_t(void)
1757 {
1758 qfree(bitmap);
1759 bitmap = nullptr;
1760 }
1761 void swap(bitset_t &r)
1762 {
1763 std::swap(bitmap, r.bitmap);
1764 std::swap(high, r.high);
1765 }
1766 bitset_t &operator=(const bitset_t &m) { return copy(m); }
1767 bitset_t &hexapi copy(const bitset_t &m); // assignment operator
1768 bool hexapi add(int bit); // add a bit
1769 bool hexapi add(int bit, int width); // add bits
1770 bool hexapi add(const bitset_t &ml); // add another bitset
1771 bool hexapi sub(int bit); // delete a bit
1772 bool hexapi sub(int bit, int width); // delete bits
1773 bool hexapi sub(const bitset_t &ml); // delete another bitset
1774 bool hexapi cut_at(int maxbit); // delete bits >= maxbit
1775 void hexapi shift_down(int shift); // shift bits down
1776 bool hexapi has(int bit) const; // test presence of a bit
1777 bool hexapi has_all(int bit, int width) const; // test presence of bits
1778 bool hexapi has_any(int bit, int width) const; // test presence of bits
1779 void print(
1780 qstring *vout,
1781 int (*get_bit_name)(qstring *out, int bit, int width, void *ud)=nullptr,
1782 void *ud=nullptr) const;
1783 const char *hexapi dstr(void) const;
1784 bool hexapi empty(void) const; // is empty?
1785 int hexapi count(void) const; // number of set bits
1786 int hexapi count(int bit) const; // get number set bits starting from 'bit'
1787 int hexapi last(void) const; // get the number of the last bit (-1-no bits)
1788 void clear(void) { high = 0; } // make empty
1789 void hexapi fill_with_ones(int maxbit);
1790 bool hexapi fill_gaps(int total_nbits);
1791 bool hexapi has_common(const bitset_t &ml) const; // has common elements?
1792 bool hexapi intersect(const bitset_t &ml); // intersect sets. returns true if changed
1793 bool hexapi is_subset_of(const bitset_t &ml) const; // is subset of?
1794 bool includes(const bitset_t &ml) const { return ml.is_subset_of(*this); }
1795 void extract(intvec_t &out) const;
1796 DECLARE_COMPARISONS(bitset_t);
1797 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
1799 {
1800 friend class bitset_t;
1801 int i;
1802 public:
1803 iterator(int n=-1) : i(n) {}
1804 bool operator==(const iterator &n) const { return i == n.i; }
1805 bool operator!=(const iterator &n) const { return i != n.i; }
1806 int operator*(void) const { return i; }
1807 };
1808 typedef iterator const_iterator;
1809 iterator itat(int n) const { return iterator(goup(n)); }
1810 iterator begin(void) const { return itat(0); }
1811 iterator end(void) const { return iterator(high); }
1812 int front(void) const { return *begin(); }
1813 int back(void) const { return *end(); }
1814 void inc(iterator &p, int n=1) const { p.i = goup(p.i+n); }
1815private:
1816 int hexapi goup(int reg) const;
1817};
1818DECLARE_TYPE_AS_MOVABLE(bitset_t);
1819typedef qvector<bitset_t> array_of_bitsets;
1820
1821//-------------------------------------------------------------------------
1822template <class T>
1823struct ivl_tpl // an interval
1824{
1825 ivl_tpl() = delete;
1826public:
1827 T off;
1828 T size;
1829 ivl_tpl(T _off, T _size) : off(_off), size(_size) {}
1830 bool valid() const { return last() >= off; }
1831 T end() const { return off + size; }
1832 T last() const { return off + size - 1; }
1833
1834 DEFINE_MEMORY_ALLOCATION_FUNCS()
1835};
1836
1837//-------------------------------------------------------------------------
1839struct ivl_t : public uval_ivl_t
1840{
1841private:
1842 typedef ivl_tpl<uval_t> inherited;
1843
1844public:
1845 ivl_t(uval_t _off=0, uval_t _size=0) : inherited(_off,_size) {}
1846 bool empty(void) const { return size == 0; }
1847 void clear(void) { size = 0; }
1848 void print(qstring *vout) const;
1849 const char *hexapi dstr(void) const;
1850
1851 bool extend_to_cover(const ivl_t &r) // extend interval to cover 'r'
1852 {
1853 uval_t new_end = end();
1854 bool changed = false;
1855 if ( off > r.off )
1856 {
1857 off = r.off;
1858 changed = true;
1859 }
1860 if ( new_end < r.end() )
1861 {
1862 new_end = r.end();
1863 changed = true;
1864 }
1865 if ( changed )
1866 size = new_end - off;
1867 return changed;
1868 }
1869 void intersect(const ivl_t &r)
1870 {
1871 uval_t new_off = qmax(off, r.off);
1872 uval_t new_end = end();
1873 if ( new_end > r.end() )
1874 new_end = r.end();
1875 if ( new_off < new_end )
1876 {
1877 off = new_off;
1878 size = new_end - off;
1879 }
1880 else
1881 {
1882 size = 0;
1883 }
1884 }
1885
1886 // do *this and ivl overlap?
1887 bool overlap(const ivl_t &ivl) const
1888 {
1889 return interval::overlap(off, size, ivl.off, ivl.size);
1890 }
1891 // does *this include ivl?
1892 bool includes(const ivl_t &ivl) const
1893 {
1894 return interval::includes(off, size, ivl.off, ivl.size);
1895 }
1896 // does *this contain off2?
1897 bool contains(uval_t off2) const
1898 {
1899 return interval::contains(off, size, off2);
1900 }
1901
1902 DECLARE_COMPARISONS(ivl_t);
1903 static const ivl_t allmem;
1904#define ALLMEM ivl_t::allmem
1905};
1906DECLARE_TYPE_AS_MOVABLE(ivl_t);
1907
1908//-------------------------------------------------------------------------
1910{
1911 ivl_t ivl;
1912 const char *whole; // name of the whole interval
1913 const char *part; // prefix to use for parts of the interval (e.g. sp+4)
1914 ivl_with_name_t(): ivl(0, BADADDR), whole("<unnamed inteval>"), part(nullptr) {}
1915 DEFINE_MEMORY_ALLOCATION_FUNCS()
1916};
1917
1918//-------------------------------------------------------------------------
1919template <class Ivl, class T>
1920class ivlset_tpl // set of intervals
1921{
1922public:
1923 typedef qvector<Ivl> bag_t;
1924
1925protected:
1926 bag_t bag;
1927 bool verify(void) const;
1928 // we do not store the empty intervals in bag so size == 0 denotes
1929 // MAX_VALUE<T>+1, e.g. 0x100000000 for uint32
1930 static bool ivl_all_values(const Ivl &ivl) { return ivl.off == 0 && ivl.size == 0; }
1931
1932public:
1933 ivlset_tpl(void) {}
1934 ivlset_tpl(const Ivl &ivl) { if ( ivl.valid() ) bag.push_back(ivl); }
1935 DEFINE_MEMORY_ALLOCATION_FUNCS()
1936
1937 void swap(ivlset_tpl &r) { bag.swap(r.bag); }
1938 const Ivl &getivl(int idx) const { return bag[idx]; }
1939 const Ivl &lastivl(void) const { return bag.back(); }
1940 size_t nivls(void) const { return bag.size(); }
1941 bool empty(void) const { return bag.empty(); }
1942 void clear(void) { bag.clear(); }
1943 void qclear(void) { bag.qclear(); }
1944 bool all_values() const { return nivls() == 1 && ivl_all_values(bag[0]); }
1945 void set_all_values() { clear(); bag.push_back(Ivl(0, 0)); }
1946 bool single_value() const { return nivls() == 1 && bag[0].size == 1; }
1947 bool single_value(T v) const { return single_value() && bag[0].off == v; }
1948
1949 bool operator==(const Ivl &v) const { return nivls() == 1 && bag[0] == v; }
1950 bool operator!=(const Ivl &v) const { return !(*this == v); }
1951
1952 typedef typename bag_t::iterator iterator;
1953 typedef typename bag_t::const_iterator const_iterator;
1954 const_iterator begin(void) const { return bag.begin(); }
1955 const_iterator end(void) const { return bag.end(); }
1956 iterator begin(void) { return bag.begin(); }
1957 iterator end(void) { return bag.end(); }
1958};
1959
1960//-------------------------------------------------------------------------
1961/// Set of address intervals.
1962/// Bit arrays are efficient only for small sets. Potentially huge
1963/// sets, like memory ranges, require another representation.
1964/// ivlset_t is used for a list of memory locations in our decompiler.
1967{
1969 ivlset_t() {}
1970 ivlset_t(const ivl_t &ivl) : inherited(ivl) {}
1971 bool hexapi add(const ivl_t &ivl);
1972 bool add(ea_t ea, asize_t size) { return add(ivl_t(ea, size)); }
1973 bool hexapi add(const ivlset_t &ivs);
1974 bool hexapi addmasked(const ivlset_t &ivs, const ivl_t &mask);
1975 bool hexapi sub(const ivl_t &ivl);
1976 bool sub(ea_t ea, asize_t size) { return sub(ivl_t(ea, size)); }
1977 bool hexapi sub(const ivlset_t &ivs);
1978 bool hexapi has_common(const ivl_t &ivl, bool strict=false) const;
1979 void hexapi print(qstring *vout) const;
1980 const char *hexapi dstr(void) const;
1981 asize_t hexapi count(void) const;
1982 bool hexapi has_common(const ivlset_t &ivs) const;
1983 bool hexapi contains(uval_t off) const;
1984 bool hexapi includes(const ivlset_t &ivs) const;
1985 bool hexapi intersect(const ivlset_t &ivs);
1986
1987 DECLARE_COMPARISONS(ivlset_t);
1988
1989};
1990DECLARE_TYPE_AS_MOVABLE(ivlset_t);
1991typedef qvector<ivlset_t> array_of_ivlsets;
1992//-------------------------------------------------------------------------
1993// We use bitset_t to keep list of registers.
1994// This is the most optimal storage for them.
1995class rlist_t : public bitset_t
1996{
1997public:
1998 rlist_t(void) {}
1999 rlist_t(const rlist_t &m) : bitset_t(m)
2000 {
2001 }
2002 rlist_t(mreg_t reg, int width) { add(reg, width); }
2003 ~rlist_t(void) {}
2004 rlist_t &operator=(const rlist_t &) = default;
2005 void hexapi print(qstring *vout) const;
2006 const char *hexapi dstr(void) const;
2007};
2008DECLARE_TYPE_AS_MOVABLE(rlist_t);
2009
2010//-------------------------------------------------------------------------
2011// Microlist: list of register and memory locations
2013{
2014 rlist_t reg; // registers
2015 ivlset_t mem; // memory locations
2016
2017 mlist_t(void) {}
2018 mlist_t(const ivl_t &ivl) : mem(ivl) {}
2019 mlist_t(mreg_t r, int size) : reg(r, size) {}
2020
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)); } // also see append_def_list()
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;
2032 const char *hexapi dstr(void) 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); }
2044
2045 DECLARE_COMPARISONS(mlist_t);
2046 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2047};
2048DECLARE_TYPE_AS_MOVABLE(mlist_t);
2049typedef qvector<mlist_t> mlistvec_t;
2050DECLARE_TYPE_AS_MOVABLE(mlistvec_t);
2051
2052//-------------------------------------------------------------------------
2053/// Get list of temporary registers.
2054/// Tempregs are temporary registers that are used during code generation.
2055/// They do not map to regular processor registers. They are used only to
2056/// store temporary values during execution of one instruction.
2057/// Tempregs may not be used to pass a value from one block to another.
2058/// In other words, at the end of a block all tempregs must be dead.
2059const mlist_t &hexapi get_temp_regs(void);
2060
2061/// Is a kernel register?
2062/// Kernel registers are temporary registers that can be used freely.
2063/// They may be used to store values that cross instruction or basic block
2064/// boundaries. Kernel registers do not map to regular processor registers.
2065/// See also \ref mba_t::alloc_kreg()
2066bool hexapi is_kreg(mreg_t r);
2067
2068/// Map a processor register to a microregister.
2069/// \param reg processor register number
2070/// \return microregister register id or mr_none
2071mreg_t hexapi reg2mreg(int reg);
2072
2073/// Map a microregister to a processor register.
2074/// \param reg microregister number
2075/// \param width size of microregister in bytes
2076/// \return processor register id or -1
2077int hexapi mreg2reg(mreg_t reg, int width);
2078
2079/// Get the microregister name.
2080/// \param out output buffer, may be nullptr
2081/// \param reg microregister number
2082/// \param width size of microregister in bytes. may be bigger than the real
2083/// register size.
2084/// \param ud reserved, must be nullptr
2085/// \return width of the printed register. this value may be less than
2086/// the WIDTH argument.
2087
2088int hexapi get_mreg_name(qstring *out, mreg_t reg, int width, void *ud=nullptr);
2089
2090//-------------------------------------------------------------------------
2091/// User defined callback to optimize individual microcode instructions
2093{
2094 /// Optimize an instruction.
2095 /// \param blk current basic block. maybe nullptr, which means that
2096 /// the instruction must be optimized without context
2097 /// \param ins instruction to optimize; it is always a top-level instruction.
2098 /// the callback may not delete the instruction but may
2099 /// convert it into nop (see mblock_t::make_nop). to optimize
2100 /// sub-instructions, visit them using minsn_visitor_t.
2101 /// sub-instructions may not be converted into nop but
2102 /// can be converted to "mov x,x". for example:
2103 /// add x,0,x => mov x,x
2104 /// this callback may change other instructions in the block,
2105 /// but should do this with care, e.g. to no break the
2106 /// propagation algorithm if called with OPTI_NO_LDXOPT.
2107 /// \param optflags combination of \ref OPTI_ bits
2108 /// \return number of changes made to the instruction.
2109 /// if after this call the instruction's use/def lists have changed,
2110 /// you must mark the block level lists as dirty (see mark_lists_dirty)
2111 virtual int idaapi func(mblock_t *blk, minsn_t *ins, int optflags) = 0;
2112};
2113
2114/// Install an instruction level custom optimizer
2115/// \param opt an instance of optinsn_t. cannot be destroyed before calling
2116/// remove_optinsn_handler().
2118
2119/// Remove an instruction level custom optimizer
2121
2122/// User defined callback to optimize microcode blocks
2124{
2125 /// Optimize a block.
2126 /// This function usually performs the optimizations that require analyzing
2127 /// the entire block and/or its neighbors. For example it can recognize
2128 /// patterns and perform conversions like:
2129 /// b0: b0:
2130 /// ... ...
2131 /// jnz x, 0, @b2 => jnz x, 0, @b2
2132 /// b1: b1:
2133 /// add x, 0, y mov x, y
2134 /// ... ...
2135 /// \param blk Basic block to optimize as a whole.
2136 /// \return number of changes made to the block. See also mark_lists_dirty.
2137 virtual int idaapi func(mblock_t *blk) = 0;
2138};
2139
2140/// Install a block level custom optimizer.
2141/// \param opt an instance of optblock_t. cannot be destroyed before calling
2142/// remove_optblock_handler().
2144
2145/// Remove a block level custom optimizer
2147
2148
2149//-------------------------------------------------------------------------
2150// abstract graph interface
2151class simple_graph_t : public gdl_graph_t
2152{
2153public:
2154 qstring title;
2155 bool colored_gdl_edges;
2156private:
2157 friend class iterator;
2158 virtual int goup(int node) const newapi;
2159};
2160
2161//-------------------------------------------------------------------------
2162// Since our data structures are quite complex, we use the visitor pattern
2163// in many of our algorthims. This functionality is available for plugins too.
2164// https://en.wikipedia.org/wiki/Visitor_pattern
2165
2166// All our visitor callbacks return an integer value.
2167// Visiting is interrupted as soon an the return value is non-zero.
2168// This non-zero value is returned as the result of the for_all_... function.
2169// If for_all_... returns 0, it means that it successfully visited all items.
2170
2171/// The context info used by visitors
2173{
2174 mba_t *mba; // current microcode
2175 mblock_t *blk; // current block
2176 minsn_t *topins; // top level instruction (parent of curins or curins itself)
2177 minsn_t *curins; // currently visited instruction
2179 mba_t *_mba=nullptr,
2180 mblock_t *_blk=nullptr,
2181 minsn_t *_topins=nullptr)
2182 : mba(_mba), blk(_blk), topins(_topins), curins(nullptr) {}
2183 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2184 bool really_alloc(void) const;
2185};
2186
2187/// Micro instruction visitor.
2188/// See mba_t::for_all_topinsns, minsn_t::for_all_insns,
2189/// mblock_::for_all_insns, mba_t::for_all_insns
2191{
2193 mba_t *_mba=nullptr,
2194 mblock_t *_blk=nullptr,
2195 minsn_t *_topins=nullptr)
2196 : op_parent_info_t(_mba, _blk, _topins) {}
2197 virtual int idaapi visit_minsn(void) = 0;
2198};
2199
2200/// Micro operand visitor.
2201/// See mop_t::for_all_ops, minsn_t::for_all_ops, mblock_t::for_all_insns,
2202/// mba_t::for_all_insns
2204{
2206 mba_t *_mba=nullptr,
2207 mblock_t *_blk=nullptr,
2208 minsn_t *_topins=nullptr)
2209 : op_parent_info_t(_mba, _blk, _topins), prune(false) {}
2210 /// Should skip sub-operands of the current operand?
2211 /// visit_mop() may set 'prune=true' for that.
2212 bool prune;
2213 virtual int idaapi visit_mop(mop_t *op, const tinfo_t *type, bool is_target) = 0;
2214};
2215
2216/// Scattered mop: visit each of the scattered locations as a separate mop.
2217/// See mop_t::for_all_scattered_submops
2219{
2220 virtual int idaapi visit_scif_mop(const mop_t &r, int off) = 0;
2221};
2222
2223// Used operand visitor.
2224// See mblock_t::for_all_uses
2226{
2227 minsn_t *topins;
2228 minsn_t *curins;
2229 bool changed;
2230 mlist_t *list;
2231 mlist_mop_visitor_t(void): topins(nullptr), curins(nullptr), changed(false), list(nullptr) {}
2232 virtual int idaapi visit_mop(mop_t *op) = 0;
2233};
2234
2235//-------------------------------------------------------------------------
2236/// Instruction operand types
2237
2238typedef uint8 mopt_t;
2239const mopt_t
2240 mop_z = 0, ///< none
2241 mop_r = 1, ///< register (they exist until MMAT_LVARS)
2242 mop_n = 2, ///< immediate number constant
2243 mop_str = 3, ///< immediate string constant (user representation)
2244 mop_d = 4, ///< result of another instruction
2245 mop_S = 5, ///< local stack variable (they exist until MMAT_LVARS)
2246 mop_v = 6, ///< global variable
2247 mop_b = 7, ///< micro basic block (mblock_t)
2248 mop_f = 8, ///< list of arguments
2249 mop_l = 9, ///< local variable
2250 mop_a = 10, ///< mop_addr_t: address of operand (mop_l, mop_v, mop_S, mop_r)
2251 mop_h = 11, ///< helper function
2252 mop_c = 12, ///< mcases
2253 mop_fn = 13, ///< floating point constant
2254 mop_p = 14, ///< operand pair
2255 mop_sc = 15; ///< scattered
2256
2257const int NOSIZE = -1; ///< wrong or unexisting operand size
2258
2259//-------------------------------------------------------------------------
2260/// Reference to a local variable. Used by mop_l
2262{
2263 /// Pointer to the parent mba_t object.
2264 /// Since we need to access the 'mba->vars' array in order to retrieve
2265 /// the referenced variable, we keep a pointer to mba_t here.
2266 /// Note: this means this class and consequently mop_t, minsn_t, mblock_t
2267 /// are specific to a mba_t object and cannot migrate between
2268 /// them. fortunately this is not something we need to do.
2269 /// second, lvar_ref_t's appear only after MMAT_LVARS.
2270 mba_t *const mba;
2271 sval_t off; ///< offset from the beginning of the variable
2272 int idx; ///< index into mba->vars
2273 lvar_ref_t(mba_t *m, int i, sval_t o=0) : mba(m), off(o), idx(i) {}
2274 lvar_ref_t(const lvar_ref_t &r) : mba(r.mba), off(r.off), idx(r.idx) {}
2275 lvar_ref_t &operator=(const lvar_ref_t &r)
2276 {
2277 off = r.off;
2278 idx = r.idx;
2279 return *this;
2280 }
2281 DECLARE_COMPARISONS(lvar_ref_t);
2282 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2283 void swap(lvar_ref_t &r)
2284 {
2285 std::swap(off, r.off);
2286 std::swap(idx, r.idx);
2287 }
2288 lvar_t &hexapi var(void) const; ///< Retrieve the referenced variable
2289};
2290
2291//-------------------------------------------------------------------------
2292/// Reference to a stack variable. Used for mop_S
2294{
2295 /// Pointer to the parent mba_t object.
2296 /// We need it in order to retrieve the referenced stack variable.
2297 /// See notes for lvar_ref_t::mba.
2298 mba_t *const mba;
2299
2300 /// Offset to the stack variable from the bottom of the stack frame.
2301 /// It is called 'decompiler stkoff' and it is different from IDA stkoff.
2302 /// See a note and a picture about 'decompiler stkoff' below.
2303 sval_t off;
2304
2305 stkvar_ref_t(mba_t *m, sval_t o) : mba(m), off(o) {}
2306 DECLARE_COMPARISONS(stkvar_ref_t);
2307 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2308 void swap(stkvar_ref_t &r)
2309 {
2310 std::swap(off, r.off);
2311 }
2312 /// Retrieve the referenced stack variable.
2313 /// \param p_off if specified, will hold IDA stkoff after the call.
2314 /// \return pointer to the stack variable
2315 member_t *hexapi get_stkvar(uval_t *p_off=nullptr) const;
2316};
2317
2318//-------------------------------------------------------------------------
2319/// Scattered operand info. Used for mop_sc
2320struct scif_t : public vdloc_t
2321{
2322 /// Pointer to the parent mba_t object.
2323 /// Some operations may convert a scattered operand into something simpler,
2324 /// (a stack operand, for example). We will need to create stkvar_ref_t at
2325 /// that moment, this is why we need this pointer.
2326 /// See notes for lvar_ref_t::mba.
2328
2329 /// Usually scattered operands are created from a function prototype,
2330 /// which has the name information. We preserve it and use it to name
2331 /// the corresponding local variable.
2332 qstring name;
2333
2334 /// Scattered operands always have type info assigned to them
2335 /// because without it we won't be able to manipulte them.
2336 tinfo_t type;
2337
2338 scif_t(mba_t *_mba, tinfo_t *tif, qstring *n=nullptr) : mba(_mba)
2339 {
2340 if ( n != nullptr )
2341 n->swap(name);
2342 tif->swap(type);
2343 }
2344 scif_t &operator =(const vdloc_t &loc)
2345 {
2346 *(vdloc_t *)this = loc;
2347 return *this;
2348 }
2349};
2350
2351//-------------------------------------------------------------------------
2352/// An integer constant. Used for mop_n
2353/// We support 64-bit values but 128-bit values can be represented with mop_p
2355{
2356 uint64 value;
2357 uint64 org_value; // original value before changing the operand size
2358 mnumber_t(uint64 v, ea_t _ea=BADADDR, int n=0)
2359 : operand_locator_t(_ea, n), value(v), org_value(v) {}
2360 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2361 DECLARE_COMPARISONS(mnumber_t)
2362 {
2363 if ( value < r.value )
2364 return -1;
2365 if ( value > r.value )
2366 return -1;
2367 return 0;
2368 }
2369 // always use this function instead of manually modifying the 'value' field
2370 void update_value(uint64 val64)
2371 {
2372 value = val64;
2373 org_value = val64;
2374 }
2375};
2376
2377//-------------------------------------------------------------------------
2378/// Floating point constant. Used for mop_fn
2379/// For more details, please see the ieee.h file from IDA SDK.
2381{
2382 fpvalue_t fnum; ///< Internal representation of the number
2383 int nbytes; ///< Original size of the constant in bytes
2384 operator uint16 *(void) { return fnum.w; }
2385 operator const uint16 *(void) const { return fnum.w; }
2386 void hexapi print(qstring *vout) const;
2387 const char *hexapi dstr(void) const;
2388 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2389 DECLARE_COMPARISONS(fnumber_t)
2390 {
2391 return ecmp(fnum, r.fnum);
2392 }
2393};
2394
2395//-------------------------------------------------------------------------
2396/// \defgroup SHINS_ Bits to control how we print instructions
2397//@{
2398#define SHINS_NUMADDR 0x01 ///< display definition addresses for numbers
2399#define SHINS_VALNUM 0x02 ///< display value numbers
2400#define SHINS_SHORT 0x04 ///< do not display use-def chains and other attrs
2401#define SHINS_LDXEA 0x08 ///< display address of ldx expressions (not used)
2402//@}
2403
2404//-------------------------------------------------------------------------
2405/// How to handle side effect of change_size()
2406/// Sometimes we need to create a temporary operand and change its size in order
2407/// to check some hypothesis. If we revert our changes, we do not want that the
2408/// database (global variables, stack frame, etc) changes in any manner.
2410{
2411 NO_SIDEFF, ///< change operand size but ignore side effects
2412 ///< if you decide to keep the changed operand,
2413 ///< handle_new_size() must be called
2414 WITH_SIDEFF, ///< change operand size and handle side effects
2415 ONLY_SIDEFF, ///< only handle side effects
2416 ANY_REGSIZE = 0x80, ///< any register size is permitted
2417 ANY_FPSIZE = 0x100, ///< any size of floating operand is permitted
2418};
2419
2420//-------------------------------------------------------------------------
2421/// A microinstruction operand.
2422/// This is the smallest building block of our microcode.
2423/// Operands will be part of instructions, which are then grouped into basic blocks.
2424/// The microcode consists of an array of such basic blocks + some additional info.
2426{
2427 void hexapi copy(const mop_t &rop);
2428public:
2429 /// Operand type.
2431
2432 /// Operand properties.
2433 uint8 oprops;
2434#define OPROP_IMPDONE 0x01 ///< imported operand (a pointer) has been dereferenced
2435#define OPROP_UDT 0x02 ///< a struct or union
2436#define OPROP_FLOAT 0x04 ///< possibly floating value
2437#define OPROP_CCFLAGS 0x08 ///< mop_n: a pc-relative value
2438 ///< else: value of a condition code register (like mr_cc)
2439#define OPROP_UDEFVAL 0x10 ///< uses undefined value
2440#define OPROP_LOWADDR 0x20 ///< a low address offset
2441
2442 /// Value number.
2443 /// Zero means unknown.
2444 /// Operands with the same value number are equal.
2445 uint16 valnum;
2446
2447 /// Operand size.
2448 /// Usually it is 1,2,4,8 or NOSIZE but for UDTs other sizes are permitted
2449 int size;
2450
2451 /// The following union holds additional details about the operand.
2452 /// Depending on the operand type different kinds of info are stored.
2453 /// You should access these fields only after verifying the operand type.
2454 /// All pointers are owned by the operand and are freed by its destructor.
2455 union
2456 {
2457 mreg_t r; // mop_r register number
2458 mnumber_t *nnn; // mop_n immediate value
2459 minsn_t *d; // mop_d result (destination) of another instruction
2460 stkvar_ref_t *s; // mop_S stack variable
2461 ea_t g; // mop_v global variable (its linear address)
2462 int b; // mop_b block number (used in jmp,call instructions)
2463 mcallinfo_t *f; // mop_f function call information
2464 lvar_ref_t *l; // mop_l local variable
2465 mop_addr_t *a; // mop_a variable whose address is taken
2466 char *helper; // mop_h helper function name
2467 char *cstr; // mop_str utf8 string constant, user representation
2468 mcases_t *c; // mop_c cases
2469 fnumber_t *fpc; // mop_fn floating point constant
2470 mop_pair_t *pair; // mop_p operand pair
2471 scif_t *scif; // mop_sc scattered operand info
2472 };
2473 // -- End of data fields, member function declarations follow:
2474
2475 void set_impptr_done(void) { oprops |= OPROP_IMPDONE; }
2476 void set_udt(void) { oprops |= OPROP_UDT; }
2477 void set_undef_val(void) { oprops |= OPROP_UDEFVAL; }
2478 void set_lowaddr(void) { oprops |= OPROP_LOWADDR; }
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
2485 {
2486 return (oprops & OPROP_CCFLAGS) != 0
2487 && (t == mop_l || t == mop_v || t == mop_S || t == mop_r);
2488 }
2489 bool is_pcval(void) const
2490 {
2491 return t == mop_n && (oprops & OPROP_CCFLAGS) != 0;
2492 }
2493
2494 mop_t(void) { zero(); }
2495 mop_t(const mop_t &rop) { copy(rop); }
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); }
2498 mop_t &hexapi assign(const mop_t &rop);
2499 ~mop_t(void)
2500 {
2501 erase();
2502 }
2503 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2504 void zero(void) { t = mop_z; oprops = 0; valnum = 0; size = NOSIZE; nnn = nullptr; }
2505 void hexapi swap(mop_t &rop);
2506 void hexapi erase(void);
2507 void erase_but_keep_size(void) { int s2 = size; erase(); size = s2; }
2508
2509 void hexapi print(qstring *vout, int shins_flags=SHINS_SHORT|SHINS_VALNUM) const;
2510 const char *hexapi dstr(void) const; // use this function for debugging
2511
2512 //-----------------------------------------------------------------------
2513 // Operand creation
2514 //-----------------------------------------------------------------------
2515 /// Create operand from mlist_t.
2516 /// Example: if LST contains 4 bits for R0.4, our operand will be
2517 /// (t=mop_r, r=R0, size=4)
2518 /// \param mba pointer to microcode
2519 /// \param lst list of locations
2520 /// \param fullsize mba->fullsize
2521 /// \return success
2522 bool hexapi create_from_mlist(mba_t *mba, const mlist_t &lst, sval_t fullsize);
2523
2524 /// Create operand from ivlset_t.
2525 /// Example: if IVS contains [glbvar..glbvar+4), our operand will be
2526 /// (t=mop_v, g=&glbvar, size=4)
2527 /// \param mba pointer to microcode
2528 /// \param ivs set of memory intervals
2529 /// \param fullsize mba->fullsize
2530 /// \return success
2531 bool hexapi create_from_ivlset(mba_t *mba, const ivlset_t &ivs, sval_t fullsize);
2532
2533 /// Create operand from vdloc_t.
2534 /// Example: if LOC contains (type=ALOC_REG1, r=R0), our operand will be
2535 /// (t=mop_r, r=R0, size=_SIZE)
2536 /// \param mba pointer to microcode
2537 /// \param loc location
2538 /// \param _size operand size
2539 /// Note: this function cannot handle scattered locations.
2540 /// \return success
2541 void hexapi create_from_vdloc(mba_t *mba, const vdloc_t &loc, int _size);
2542
2543 /// Create operand from scattered vdloc_t.
2544 /// Example: if LOC is (ALOC_DIST, {EAX.4, EDX.4}) and TYPE is _LARGE_INTEGER,
2545 /// our operand will be
2546 /// (t=mop_sc, scif={EAX.4, EDX.4})
2547 /// \param mba pointer to microcode
2548 /// \param name name of the operand, if available
2549 /// \param type type of the operand, must be present
2550 /// \param loc a scattered location
2551 /// \return success
2552 void hexapi create_from_scattered_vdloc(
2553 mba_t *mba,
2554 const char *name,
2555 tinfo_t type,
2556 const vdloc_t &loc);
2557
2558 /// Create operand from an instruction.
2559 /// This function creates a nested instruction that can be used as an operand.
2560 /// Example: if m="add x,y,z", our operand will be (t=mop_d,d=m).
2561 /// The destination operand of 'add' (z) is lost.
2562 /// \param m instruction to embed into operand. may not be nullptr.
2563 void hexapi create_from_insn(const minsn_t *m);
2564
2565 /// Create an integer constant operand.
2566 /// \param _value value to store in the operand
2567 /// \param _size size of the value in bytes (1,2,4,8)
2568 /// \param _ea address of the processor instruction that made the value
2569 /// \param opnum operand number of the processor instruction
2570 void hexapi make_number(uint64 _value, int _size, ea_t _ea=BADADDR, int opnum=0);
2571
2572 /// Create a floating point constant operand.
2573 /// \param bytes pointer to the floating point value as used by the current
2574 /// processor (e.g. for x86 it must be in IEEE 754)
2575 /// \param _size number of bytes occupied by the constant.
2576 /// \return success
2577 bool hexapi make_fpnum(const void *bytes, size_t _size);
2578
2579 /// Create a register operand without erasing previous data.
2580 /// \param reg micro register number
2581 /// Note: this function does not erase the previous contents of the operand;
2582 /// call erase() if necessary
2584 {
2585 t = mop_r;
2586 r = reg;
2587 }
2588 void _make_reg(mreg_t reg, int _size)
2589 {
2590 t = mop_r;
2591 r = reg;
2592 size = _size;
2593 }
2594 /// Create a register operand.
2595 void make_reg(mreg_t reg) { erase(); _make_reg(reg); }
2596 void make_reg(mreg_t reg, int _size) { erase(); _make_reg(reg, _size); }
2597
2598 /// Create a local variable operand.
2599 /// \param mba pointer to microcode
2600 /// \param idx index into mba->vars
2601 /// \param off offset from the beginning of the variable
2602 /// Note: this function does not erase the previous contents of the operand;
2603 /// call erase() if necessary
2604 void _make_lvar(mba_t *mba, int idx, sval_t off=0)
2605 {
2606 t = mop_l;
2607 l = new lvar_ref_t(mba, idx, off);
2608 }
2609
2610 /// Create a global variable operand without erasing previous data.
2611 /// \param ea address of the variable
2612 /// Note: this function does not erase the previous contents of the operand;
2613 /// call erase() if necessary
2614 void hexapi _make_gvar(ea_t ea);
2615 /// Create a global variable operand.
2616 void hexapi make_gvar(ea_t ea);
2617
2618 /// Create a stack variable operand.
2619 /// \param mba pointer to microcode
2620 /// \param off decompiler stkoff
2621 /// Note: this function does not erase the previous contents of the operand;
2622 /// call erase() if necessary
2623 void _make_stkvar(mba_t *mba, sval_t off)
2624 {
2625 t = mop_S;
2626 s = new stkvar_ref_t(mba, off);
2627 }
2628 void make_stkvar(mba_t *mba, sval_t off) { erase(); _make_stkvar(mba, off); }
2629
2630 /// Create pair of registers.
2631 /// \param loreg register holding the low part of the value
2632 /// \param hireg register holding the high part of the value
2633 /// \param halfsize the size of each of loreg/hireg
2634 void hexapi make_reg_pair(int loreg, int hireg, int halfsize);
2635
2636 /// Create a nested instruction without erasing previous data.
2637 /// \param ins pointer to the instruction to encapsulate into the operand
2638 /// Note: this function does not erase the previous contents of the operand;
2639 /// call erase() if necessary
2640 /// See also create_from_insn, which is higher level
2641 void _make_insn(minsn_t *ins);
2642 /// Create a nested instruction.
2643 void make_insn(minsn_t *ins) { erase(); _make_insn(ins); }
2644
2645 /// Create a block reference operand without erasing previous data.
2646 /// \param blknum block number
2647 /// Note: this function does not erase the previous contents of the operand;
2648 /// call erase() if necessary
2649 void _make_blkref(int blknum)
2650 {
2651 t = mop_b;
2652 b = blknum;
2653 }
2654 /// Create a global variable operand.
2655 void make_blkref(int blknum) { erase(); _make_blkref(blknum); }
2656
2657 /// Create a helper operand.
2658 /// A helper operand usually keeps a built-in function name like "va_start"
2659 /// It is essentially just an arbitrary identifier without any additional info.
2660 void hexapi make_helper(const char *name);
2661
2662 /// Create a constant string operand.
2663 void _make_strlit(const char *str)
2664 {
2665 t = mop_str;
2666 cstr = ::qstrdup(str);
2667 }
2668 void _make_strlit(qstring *str) // str is consumed
2669 {
2670 t = mop_str;
2671 cstr = str->extract();
2672 }
2673
2674 /// Create a call info operand without erasing previous data.
2675 /// \param fi callinfo
2676 /// Note: this function does not erase the previous contents of the operand;
2677 /// call erase() if necessary
2679 {
2680 t = mop_f;
2681 f = fi;
2682 }
2683
2684 /// Create a 'switch cases' operand without erasing previous data.
2685 /// Note: this function does not erase the previous contents of the operand;
2686 /// call erase() if necessary
2687 void _make_cases(mcases_t *_cases)
2688 {
2689 t = mop_c;
2690 c = _cases;
2691 }
2692
2693 /// Create a pair operand without erasing previous data.
2694 /// Note: this function does not erase the previous contents of the operand;
2695 /// call erase() if necessary
2697 {
2698 t = mop_p;
2699 pair = _pair;
2700 }
2701
2702 //-----------------------------------------------------------------------
2703 // Various operand tests
2704 //-----------------------------------------------------------------------
2705 bool empty(void) const { return t == mop_z; }
2706 /// Is a register operand?
2707 /// See also get_mreg_name()
2708 bool is_reg(void) const { return t == mop_r; }
2709 /// Is the specified register?
2710 bool is_reg(mreg_t _r) const { return t == mop_r && r == _r; }
2711 /// Is the specified register of the specified size?
2712 bool is_reg(mreg_t _r, int _size) const { return t == mop_r && r == _r && size == _size; }
2713 /// Is a list of arguments?
2714 bool is_arglist(void) const { return t == mop_f; }
2715 /// Is a condition code?
2716 bool is_cc(void) const { return is_reg() && r >= mr_cf && r < mr_first; }
2717 /// Is a bit register?
2718 /// This includes condition codes and eventually other bit registers
2719 static bool hexapi is_bit_reg(mreg_t reg);
2720 bool is_bit_reg(void) const { return is_reg() && is_bit_reg(r); }
2721 /// Is a kernel register?
2722 bool is_kreg(void) const;
2723 /// Is a block reference to the specified block?
2724 bool is_mob(int serial) const { return t == mop_b && b == serial; }
2725 /// Is a scattered operand?
2726 bool is_scattered(void) const { return t == mop_sc; }
2727 /// Is address of a global memory cell?
2728 bool is_glbaddr() const;
2729 /// Is address of the specified global memory cell?
2730 bool is_glbaddr(ea_t ea) const;
2731 /// Is address of a stack variable?
2732 bool is_stkaddr() const;
2733 /// Is a sub-instruction?
2734 bool is_insn(void) const { return t == mop_d; }
2735 /// Is a sub-instruction with the specified opcode?
2736 bool is_insn(mcode_t code) const;
2737 /// Has any side effects?
2738 /// \param include_ldx_and_divs consider ldx/div/mod as having side effects?
2739 bool has_side_effects(bool include_ldx_and_divs=false) const;
2740 /// Is it possible for the operand to use aliased memory?
2741 bool hexapi may_use_aliased_memory(void) const;
2742
2743 /// Are the possible values of the operand only 0 and 1?
2744 /// This function returns true for 0/1 constants, bit registers,
2745 /// the result of 'set' insns, etc.
2746 bool hexapi is01(void) const;
2747
2748 /// Does the high part of the operand consist of the sign bytes?
2749 /// \param nbytes number of bytes that were sign extended.
2750 /// the remaining size-nbytes high bytes must be sign bytes
2751 /// Example: is_sign_extended_from(xds.4(op.1), 1) -> true
2752 /// because the high 3 bytes are certainly sign bits
2753 bool hexapi is_sign_extended_from(int nbytes) const;
2754
2755 /// Does the high part of the operand consist of zero bytes?
2756 /// \param nbytes number of bytes that were zero extended.
2757 /// the remaining size-nbytes high bytes must be zero
2758 /// Example: is_zero_extended_from(xdu.8(op.1), 2) -> true
2759 /// because the high 6 bytes are certainly zero
2760 bool hexapi is_zero_extended_from(int nbytes) const;
2761
2762 /// Does the high part of the operand consist of zero or sign bytes?
2763 bool is_extended_from(int nbytes, bool is_signed) const
2764 {
2765 if ( is_signed )
2766 return is_sign_extended_from(nbytes);
2767 else
2768 return is_zero_extended_from(nbytes);
2769 }
2770
2771 //-----------------------------------------------------------------------
2772 // Comparisons
2773 //-----------------------------------------------------------------------
2774 /// Compare operands.
2775 /// This is the main comparison function for operands.
2776 /// \param rop operand to compare with
2777 /// \param eqflags combination of \ref EQ_ bits
2778 bool hexapi equal_mops(const mop_t &rop, int eqflags) const;
2779 bool operator==(const mop_t &rop) const { return equal_mops(rop, 0); }
2780 bool operator!=(const mop_t &rop) const { return !equal_mops(rop, 0); }
2781
2782 /// Lexographical operand comparison.
2783 /// It can be used to store mop_t in various containers, like std::set
2784 bool operator <(const mop_t &rop) const { return lexcompare(rop) < 0; }
2785 friend int lexcompare(const mop_t &a, const mop_t &b) { return a.lexcompare(b); }
2786 int hexapi lexcompare(const mop_t &rop) const;
2787
2788 //-----------------------------------------------------------------------
2789 // Visiting operand parts
2790 //-----------------------------------------------------------------------
2791 /// Visit the operand and all its sub-operands.
2792 /// This function visits the current operand as well.
2793 /// \param mv visitor object
2794 /// \param type operand type
2795 /// \param is_target is a destination operand?
2796 int hexapi for_all_ops(
2797 mop_visitor_t &mv,
2798 const tinfo_t *type=nullptr,
2799 bool is_target=false);
2800
2801 /// Visit all sub-operands of a scattered operand.
2802 /// This function does not visit the current operand, only its sub-operands.
2803 /// All sub-operands are synthetic and are destroyed after the visitor.
2804 /// This function works only with scattered operands.
2805 /// \param sv visitor object
2806 int hexapi for_all_scattered_submops(scif_visitor_t &sv) const;
2807
2808 //-----------------------------------------------------------------------
2809 // Working with mop_n operands
2810 //-----------------------------------------------------------------------
2811 /// Retrieve value of a constant integer operand.
2812 /// These functions can be called only for mop_n operands.
2813 /// See is_constant() that can be called on any operand.
2814 uint64 value(bool is_signed) const { return extend_sign(nnn->value, size, is_signed); }
2815 int64 signed_value(void) const { return value(true); }
2816 uint64 unsigned_value(void) const { return value(false); }
2817 void update_numop_value(uint64 val)
2818 {
2819 nnn->update_value(extend_sign(val, size, false));
2820 }
2821
2822 /// Retrieve value of a constant integer operand.
2823 /// \param out pointer to the output buffer
2824 /// \param is_signed should treat the value as signed
2825 /// \return true if the operand is mop_n
2826 bool hexapi is_constant(uint64 *out=nullptr, bool is_signed=true) const;
2827
2828 bool is_equal_to(uint64 n, bool is_signed=true) const
2829 {
2830 uint64 v;
2831 return is_constant(&v, is_signed) && v == n;
2832 }
2833 bool is_zero(void) const { return is_equal_to(0, false); }
2834 bool is_one(void) const { return is_equal_to(1, false); }
2835 bool is_positive_constant(void) const
2836 {
2837 uint64 v;
2838 return is_constant(&v, true) && int64(v) > 0;
2839 }
2840 bool is_negative_constant(void) const
2841 {
2842 uint64 v;
2843 return is_constant(&v, true) && int64(v) < 0;
2844 }
2845
2846 //-----------------------------------------------------------------------
2847 // Working with mop_S operands
2848 //-----------------------------------------------------------------------
2849 /// Retrieve the referenced stack variable.
2850 /// \param p_off if specified, will hold IDA stkoff after the call.
2851 /// \return pointer to the stack variable
2852 member_t *get_stkvar(uval_t *p_off) const { return s->get_stkvar(p_off); }
2853
2854 /// Get the referenced stack offset.
2855 /// This function can also handle mop_sc if it is entirely mapped into
2856 /// a continuous stack region.
2857 /// \param p_off the output buffer
2858 /// \return success
2859 bool hexapi get_stkoff(sval_t *p_off) const;
2860
2861 //-----------------------------------------------------------------------
2862 // Working with mop_d operands
2863 //-----------------------------------------------------------------------
2864 /// Get subinstruction of the operand.
2865 /// If the operand has a subinstruction with the specified opcode, return it.
2866 /// \param code desired opcode
2867 /// \return pointer to the instruction or nullptr
2868 const minsn_t *get_insn(mcode_t code) const;
2869 minsn_t *get_insn(mcode_t code);
2870
2871 //-----------------------------------------------------------------------
2872 // Transforming operands
2873 //-----------------------------------------------------------------------
2874 /// Make the low part of the operand.
2875 /// This function takes into account the memory endianness (byte sex)
2876 /// \param width the desired size of the operand part in bytes
2877 /// \return success
2878 bool hexapi make_low_half(int width);
2879
2880 /// Make the high part of the operand.
2881 /// This function takes into account the memory endianness (byte sex)
2882 /// \param width the desired size of the operand part in bytes
2883 /// \return success
2884 bool hexapi make_high_half(int width);
2885
2886 /// Make the first part of the operand.
2887 /// This function does not care about the memory endianness
2888 /// \param width the desired size of the operand part in bytes
2889 /// \return success
2890 bool hexapi make_first_half(int width);
2891
2892 /// Make the second part of the operand.
2893 /// This function does not care about the memory endianness
2894 /// \param width the desired size of the operand part in bytes
2895 /// \return success
2896 bool hexapi make_second_half(int width);
2897
2898 /// Shift the operand.
2899 /// This function shifts only the beginning of the operand.
2900 /// The operand size will be changed.
2901 /// Examples: shift_mop(AH.1, -1) -> AX.2
2902 /// shift_mop(qword_00000008.8, 4) -> dword_0000000C.4
2903 /// shift_mop(xdu.8(op.4), 4) -> #0.4
2904 /// shift_mop(#0x12345678.4, 3) -> #12.1
2905 /// \param offset shift count (the number of bytes to shift)
2906 /// \return success
2907 bool hexapi shift_mop(int offset);
2908
2909 /// Change the operand size.
2910 /// Examples: change_size(AL.1, 2) -> AX.2
2911 /// change_size(qword_00000008.8, 4) -> dword_00000008.4
2912 /// change_size(xdu.8(op.4), 4) -> op.4
2913 /// change_size(#0x12345678.4, 1) -> #0x78.1
2914 /// \param nsize new operand size
2915 /// \param sideff may modify the database because of the size change?
2916 /// \return success
2917 bool hexapi change_size(int nsize, side_effect_t sideff=WITH_SIDEFF);
2918 bool double_size(side_effect_t sideff=WITH_SIDEFF) { return change_size(size*2, sideff); }
2919
2920 /// Move subinstructions with side effects out of the operand.
2921 /// If we decide to delete an instruction operand, it is a good idea to
2922 /// call this function. Alternatively we should skip such operands
2923 /// by calling mop_t::has_side_effects()
2924 /// For example, if we transform: jnz x, x, @blk => goto @blk
2925 /// then we must call this function before deleting the X operands.
2926 /// \param blk current block
2927 /// \param top top level instruction that contains our operand
2928 /// \param moved_calls pointer to the boolean that will track if all side
2929 /// effects get handled correctly. must be false initially.
2930 /// \return false failed to preserve a side effect, it is not safe to
2931 /// delete the operand
2932 /// true no side effects or successfully preserved them
2933 bool hexapi preserve_side_effects(
2934 mblock_t *blk,
2935 minsn_t *top,
2936 bool *moved_calls=nullptr);
2937
2938 /// Apply a unary opcode to the operand.
2939 /// \param mcode opcode to apply. it must accept 'l' and 'd' operands
2940 /// but not 'r'. examples: m_low/m_high/m_xds/m_xdu
2941 /// \param ea value of minsn_t::ea for the newly created insruction
2942 /// \param newsize new operand size
2943 /// Example: apply_ld_mcode(m_low) will convert op => low(op)
2944 void hexapi apply_ld_mcode(mcode_t mcode, ea_t ea, int newsize);
2945 void apply_xdu(ea_t ea, int newsize) { apply_ld_mcode(m_xdu, ea, newsize); }
2946 void apply_xds(ea_t ea, int newsize) { apply_ld_mcode(m_xds, ea, newsize); }
2947};
2948DECLARE_TYPE_AS_MOVABLE(mop_t);
2949
2950/// Pair of operands
2952{
2953public:
2954 mop_t lop; ///< low operand
2955 mop_t hop; ///< high operand
2956 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2957};
2958
2959/// Address of an operand (mop_l, mop_v, mop_S, mop_r)
2960class mop_addr_t : public mop_t
2961{
2962public:
2963 int insize; // how many bytes of the pointed operand can be read
2964 int outsize; // how many bytes of the pointed operand can be written
2965
2966 mop_addr_t(): insize(NOSIZE), outsize(NOSIZE) {}
2967 mop_addr_t(const mop_addr_t &ra)
2968 : mop_t(ra), insize(ra.insize), outsize(ra.outsize) {}
2969 mop_addr_t(const mop_t &ra, int isz, int osz)
2970 : mop_t(ra), insize(isz), outsize(osz) {}
2971
2972 mop_addr_t &operator=(const mop_addr_t &rop)
2973 {
2974 *(mop_t *)this = mop_t(rop);
2975 insize = rop.insize;
2976 outsize = rop.outsize;
2977 return *this;
2978 }
2979 int lexcompare(const mop_addr_t &ra) const
2980 {
2981 int code = mop_t::lexcompare(ra);
2982 return code != 0 ? code
2983 : insize != ra.insize ? (insize-ra.insize)
2984 : outsize != ra.outsize ? (outsize-ra.outsize)
2985 : 0;
2986 }
2987};
2988
2989/// A call argument
2990class mcallarg_t : public mop_t // #callarg
2991{
2992public:
2993 ea_t ea = BADADDR; ///< address where the argument was initialized.
2994 ///< BADADDR means unknown.
2995 tinfo_t type; ///< formal argument type
2996 qstring name; ///< formal argument name
2997 argloc_t argloc; ///< ida argloc
2998 uint32 flags = 0; ///< FAI_...
2999
3000 mcallarg_t() {}
3001 mcallarg_t(const mop_t &rarg) : mop_t(rarg) {}
3002 void copy_mop(const mop_t &op) { *(mop_t *)this = op; }
3003 void hexapi print(qstring *vout, int shins_flags=SHINS_SHORT|SHINS_VALNUM) const;
3004 const char *hexapi dstr(void) const;
3005 void hexapi set_regarg(mreg_t mr, int sz, const tinfo_t &tif);
3006 void set_regarg(mreg_t mr, const tinfo_t &tif)
3007 {
3008 set_regarg(mr, tif.get_size(), tif);
3009 }
3010 void set_regarg(mreg_t mr, char dt, type_sign_t sign = type_unsigned)
3011 {
3012 int sz = get_dtype_size(dt);
3013 set_regarg(mr, sz, get_int_type_by_width_and_sign(sz, sign));
3014 }
3015 void make_int(int val, ea_t val_ea, int opno = 0)
3016 {
3017 type = tinfo_t(BTF_INT);
3018 make_number(val, inf_get_cc_size_i(), val_ea, opno);
3019 }
3020 void make_uint(int val, ea_t val_ea, int opno = 0)
3021 {
3022 type = tinfo_t(BTF_UINT);
3023 make_number(val, inf_get_cc_size_i(), val_ea, opno);
3024 }
3025};
3026DECLARE_TYPE_AS_MOVABLE(mcallarg_t);
3027typedef qvector<mcallarg_t> mcallargs_t;
3028
3029/// Function roles.
3030/// They are used to calculate use/def lists and to recognize functions
3031/// without using string comparisons.
3033{
3034 ROLE_UNK, ///< unknown function role
3035 ROLE_EMPTY, ///< empty, does not do anything (maybe spoils regs)
3036 ROLE_MEMSET, ///< memset(void *dst, uchar value, size_t count);
3037 ROLE_MEMSET32, ///< memset32(void *dst, uint32 value, size_t count);
3038 ROLE_MEMSET64, ///< memset64(void *dst, uint64 value, size_t count);
3039 ROLE_MEMCPY, ///< memcpy(void *dst, const void *src, size_t count);
3040 ROLE_STRCPY, ///< strcpy(char *dst, const char *src);
3041 ROLE_STRLEN, ///< strlen(const char *src);
3042 ROLE_STRCAT, ///< strcat(char *dst, const char *src);
3043 ROLE_TAIL, ///< char *tail(const char *str);
3044 ROLE_BUG, ///< BUG() helper macro: never returns, causes exception
3045 ROLE_ALLOCA, ///< alloca() function
3046 ROLE_BSWAP, ///< bswap() function (any size)
3047 ROLE_PRESENT, ///< present() function (used in patterns)
3048 ROLE_CONTAINING_RECORD, ///< CONTAINING_RECORD() macro
3049 ROLE_FASTFAIL, ///< __fastfail()
3050 ROLE_READFLAGS, ///< __readeflags, __readcallersflags
3051 ROLE_IS_MUL_OK, ///< is_mul_ok
3052 ROLE_SATURATED_MUL, ///< saturated_mul
3053 ROLE_BITTEST, ///< [lock] bt
3054 ROLE_BITTESTANDSET, ///< [lock] bts
3055 ROLE_BITTESTANDRESET, ///< [lock] btr
3057 ROLE_VA_ARG, ///< va_arg() macro
3058 ROLE_VA_COPY, ///< va_copy() function
3059 ROLE_VA_START, ///< va_start() function
3060 ROLE_VA_END, ///< va_end() function
3061 ROLE_ROL, ///< rotate left
3062 ROLE_ROR, ///< rotate right
3063 ROLE_CFSUB3, ///< carry flag after subtract with carry
3064 ROLE_OFSUB3, ///< overflow flag after subtract with carry
3065 ROLE_ABS, ///< integer absolute value
3066 ROLE_3WAYCMP0, ///< 3-way compare helper, returns -1/0/1
3067 ROLE_3WAYCMP1, ///< 3-way compare helper, returns 0/1/2
3068 ROLE_WMEMCPY, ///< wchar_t *wmemcpy(wchar_t *dst, const wchar_t *src, size_t n)
3069 ROLE_WMEMSET, ///< wchar_t *wmemset(wchar_t *dst, wchar_t wc, size_t n)
3070 ROLE_WCSCPY, ///< wchar_t *wcscpy(wchar_t *dst, const wchar_t *src);
3071 ROLE_WCSLEN, ///< size_t wcslen(const wchar_t *s)
3072 ROLE_WCSCAT, ///< wchar_t *wcscat(wchar_t *dst, const wchar_t *src)
3073 ROLE_SSE_CMP4, ///< e.g. _mm_cmpgt_ss
3074 ROLE_SSE_CMP8, ///< e.g. _mm_cmpgt_sd
3075};
3076
3077/// \defgroup FUNC_NAME_ Well known function names
3078//@{
3079#define FUNC_NAME_MEMCPY "memcpy"
3080#define FUNC_NAME_WMEMCPY "wmemcpy"
3081#define FUNC_NAME_MEMSET "memset"
3082#define FUNC_NAME_WMEMSET "wmemset"
3083#define FUNC_NAME_MEMSET32 "memset32"
3084#define FUNC_NAME_MEMSET64 "memset64"
3085#define FUNC_NAME_STRCPY "strcpy"
3086#define FUNC_NAME_WCSCPY "wcscpy"
3087#define FUNC_NAME_STRLEN "strlen"
3088#define FUNC_NAME_WCSLEN "wcslen"
3089#define FUNC_NAME_STRCAT "strcat"
3090#define FUNC_NAME_WCSCAT "wcscat"
3091#define FUNC_NAME_TAIL "tail"
3092#define FUNC_NAME_VA_ARG "va_arg"
3093#define FUNC_NAME_EMPTY "$empty"
3094#define FUNC_NAME_PRESENT "$present"
3095#define FUNC_NAME_CONTAINING_RECORD "CONTAINING_RECORD"
3096//@}
3097
3098
3099// the default 256 function arguments is too big, we use a lower value
3100#undef MAX_FUNC_ARGS
3101#define MAX_FUNC_ARGS 64
3102
3103/// Information about a call
3104class mcallinfo_t // #callinfo
3105{
3106public:
3107 ea_t callee; ///< address of the called function, if known
3108 int solid_args; ///< number of solid args.
3109 ///< there may be variadic args in addtion
3110 int call_spd; ///< sp value at call insn
3111 int stkargs_top; ///< first offset past stack arguments
3112 cm_t cc; ///< calling convention
3113 mcallargs_t args; ///< call arguments
3114 mopvec_t retregs; ///< return register(s) (e.g., AX, AX:DX, etc.)
3115 ///< this vector is built from return_regs
3116 tinfo_t return_type; ///< type of the returned value
3117 argloc_t return_argloc; ///< location of the returned value
3118
3119 mlist_t return_regs; ///< list of values returned by the function
3120 mlist_t spoiled; ///< list of spoiled locations (includes return_regs)
3121 mlist_t pass_regs; ///< passthrough registers: registers that depend on input
3122 ///< values (subset of spoiled)
3123 ivlset_t visible_memory; ///< what memory is visible to the call?
3124 mlist_t dead_regs; ///< registers defined by the function but never used.
3125 ///< upon propagation we do the following:
3126 ///< - dead_regs += return_regs
3127 ///< - retregs.clear() since the call is propagated
3128 int flags; ///< combination of \ref FCI_... bits
3129/// \defgroup FCI_ Call properties
3130//@{
3131#define FCI_PROP 0x001 ///< call has been propagated
3132#define FCI_DEAD 0x002 ///< some return registers were determined dead
3133#define FCI_FINAL 0x004 ///< call type is final, should not be changed
3134#define FCI_NORET 0x008 ///< call does not return
3135#define FCI_PURE 0x010 ///< pure function
3136#define FCI_NOSIDE 0x020 ///< call does not have side effects
3137#define FCI_SPLOK 0x040 ///< spoiled/visible_memory lists have been
3138 ///< optimized. for some functions we can reduce them
3139 ///< as soon as information about the arguments becomes
3140 ///< available. in order not to try optimize them again
3141 ///< we use this bit.
3142#define FCI_HASCALL 0x080 ///< A function is an synthetic helper combined
3143 ///< from several instructions and at least one
3144 ///< of them was a call to a real functions
3145#define FCI_HASFMT 0x100 ///< A variadic function with recognized
3146 ///< printf- or scanf-style format string
3147#define FCI_EXPLOCS 0x400 ///< all arglocs are specified explicitly
3148//@}
3149 funcrole_t role; ///< function role
3150 type_attrs_t fti_attrs; ///< extended function attributes
3151
3152 mcallinfo_t(ea_t _callee=BADADDR, int _sargs=0)
3153 : callee(_callee), solid_args(_sargs), call_spd(0), stkargs_top(0),
3154 cc(CM_CC_INVALID), flags(0), role(ROLE_UNK) {}
3155 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
3156 int hexapi lexcompare(const mcallinfo_t &f) const;
3157 bool hexapi set_type(const tinfo_t &type);
3158 tinfo_t hexapi get_type(void) const;
3159 bool is_vararg(void) const { return is_vararg_cc(cc); }
3160 void hexapi print(qstring *vout, int size=-1, int shins_flags=SHINS_SHORT|SHINS_VALNUM) const;
3161 const char *hexapi dstr(void) const;
3162};
3163
3164/// List of switch cases and targets
3165class mcases_t // #cases
3166{
3167public:
3168 casevec_t values; ///< expression values for each target
3169 intvec_t targets; ///< target block numbers
3170
3171 void swap(mcases_t &r) { values.swap(r.values); targets.swap(r.targets); }
3172 DECLARE_COMPARISONS(mcases_t);
3173 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
3174 bool empty(void) const { return targets.empty(); }
3175 size_t size(void) const { return targets.size(); }
3176 void resize(int s) { values.resize(s); targets.resize(s); }
3177 void hexapi print(qstring *vout) const;
3178 const char *hexapi dstr(void) const;
3179};
3180
3181//-------------------------------------------------------------------------
3182/// Value offset (microregister number or stack offset)
3184{
3185 sval_t off; ///< register number or stack offset
3186 mopt_t type; ///< mop_r - register, mop_S - stack, mop_z - undefined
3187
3188 voff_t() : off(-1), type(mop_z) {}
3189 voff_t(mopt_t _type, sval_t _off) : off(_off), type(_type) {}
3190 voff_t(const mop_t &op) : off(-1), type(mop_z)
3191 {
3192 if ( op.is_reg() || op.t == mop_S )
3193 set(op.t, op.is_reg() ? op.r : op.s->off);
3194 }
3195
3196 void set(mopt_t _type, sval_t _off) { type = _type; off = _off; }
3197 void set_stkoff(sval_t stkoff) { set(mop_S, stkoff); }
3198 void set_reg(mreg_t mreg) { set(mop_r, mreg); }
3199 void undef() { set(mop_z, -1); }
3200
3201 bool defined() const { return type != mop_z; }
3202 bool is_reg() const { return type == mop_r; }
3203 bool is_stkoff() const { return type == mop_S; }
3204 mreg_t get_reg() const { QASSERT(51892, is_reg()); return off; }
3205 sval_t get_stkoff() const { QASSERT(51893, is_stkoff()); return off; }
3206
3207 void inc(sval_t delta) { off += delta; }
3208 voff_t add(int width) const { return voff_t(type, off+width); }
3209 sval_t diff(const voff_t &r) const { QASSERT(51894, type == r.type); return off - r.off; }
3210
3211 DECLARE_COMPARISONS(voff_t)
3212 {
3213 int code = ::compare(type, r.type);
3214 return code != 0 ? code : ::compare(off, r.off);
3215 }
3216};
3217
3218//-------------------------------------------------------------------------
3219/// Value interval (register or stack range)
3221{
3222 int size; ///< Interval size in bytes
3223
3224 vivl_t(mopt_t _type = mop_z, sval_t _off = -1, int _size = 0)
3225 : voff_t(_type, _off), size(_size) {}
3226 vivl_t(const class chain_t &ch);
3227 vivl_t(const mop_t &op) : voff_t(op), size(op.size) {}
3228
3229 // Make a value interval
3230 void set(mopt_t _type, sval_t _off, int _size = 0)
3231 { voff_t::set(_type, _off); size = _size; }
3232 void set(const voff_t &voff, int _size)
3233 { set(voff.type, voff.off, _size); }
3234 void set_stkoff(sval_t stkoff, int sz = 0) { set(mop_S, stkoff, sz); }
3235 void set_reg (mreg_t mreg, int sz = 0) { set(mop_r, mreg, sz); }
3236
3237 /// Extend a value interval using another value interval of the same type
3238 /// \return success
3239 bool hexapi extend_to_cover(const vivl_t &r);
3240
3241 /// Intersect value intervals the same type
3242 /// \return size of the resulting intersection
3243 uval_t hexapi intersect(const vivl_t &r);
3244
3245 /// Do two value intervals overlap?
3246 bool overlap(const vivl_t &r) const
3247 {
3248 return type == r.type
3249 && interval::overlap(off, size, r.off, r.size);
3250 }
3251 /// Does our value interval include another?
3252 bool includes(const vivl_t &r) const
3253 {
3254 return type == r.type
3255 && interval::includes(off, size, r.off, r.size);
3256 }
3257
3258 /// Does our value interval contain the specified value offset?
3259 bool contains(const voff_t &voff2) const
3260 {
3261 return type == voff2.type
3262 && interval::contains(off, size, voff2.off);
3263 }
3264
3265 // Comparisons
3266 DECLARE_COMPARISONS(vivl_t)
3267 {
3268 int code = voff_t::compare(r);
3269 return code; //return code != 0 ? code : ::compare(size, r.size);
3270 }
3271 bool operator==(const mop_t &mop) const
3272 {
3273 return type == mop.t && off == (mop.is_reg() ? mop.r : mop.s->off);
3274 }
3275 void hexapi print(qstring *vout) const;
3276 const char *hexapi dstr(void) const;
3277};
3278
3279//-------------------------------------------------------------------------
3280/// ud (use->def) and du (def->use) chain.
3281/// We store in chains only the block numbers, not individual instructions
3282/// See https://en.wikipedia.org/wiki/Use-define_chain
3283class chain_t : public intvec_t // sequence of block numbers
3284{
3285 voff_t k; ///< Value offset of the chain.
3286 ///< (what variable is this chain about)
3287
3288public:
3289 int width; ///< size of the value in bytes
3290 int varnum; ///< allocated variable index (-1 - not allocated yet)
3291 uchar flags; ///< combination \ref CHF_ bits
3292/// \defgroup CHF_ Chain properties
3293//@{
3294#define CHF_INITED 0x01 ///< is chain initialized? (valid only after lvar allocation)
3295#define CHF_REPLACED 0x02 ///< chain operands have been replaced?
3296#define CHF_OVER 0x04 ///< overlapped chain
3297#define CHF_FAKE 0x08 ///< fake chain created by widen_chains()
3298#define CHF_PASSTHRU 0x10 ///< pass-thru chain, must use the input variable to the block
3299#define CHF_TERM 0x20 ///< terminating chain; the variable does not survive across the block
3300//@}
3301 chain_t() : width(0), varnum(-1), flags(CHF_INITED) {}
3302 chain_t(mopt_t t, sval_t off, int w=1, int v=-1)
3303 : k(t, off), width(w), varnum(v), flags(CHF_INITED) {}
3304 chain_t(const voff_t &_k, int w=1)
3305 : k(_k), width(w), varnum(-1), flags(CHF_INITED) {}
3306 void set_value(const chain_t &r)
3307 { width = r.width; varnum = r.varnum; flags = r.flags; *(intvec_t *)this = (intvec_t &)r; }
3308 const voff_t &key() const { return k; }
3309 bool is_inited(void) const { return (flags & CHF_INITED) != 0; }
3310 bool is_reg(void) const { return k.is_reg(); }
3311 bool is_stkoff(void) const { return k.is_stkoff(); }
3312 bool is_replaced(void) const { return (flags & CHF_REPLACED) != 0; }
3313 bool is_overlapped(void) const { return (flags & CHF_OVER) != 0; }
3314 bool is_fake(void) const { return (flags & CHF_FAKE) != 0; }
3315 bool is_passreg(void) const { return (flags & CHF_PASSTHRU) != 0; }
3316 bool is_term(void) const { return (flags & CHF_TERM) != 0; }
3317 void set_inited(bool b) { setflag(flags, CHF_INITED, b); }
3318 void set_replaced(bool b) { setflag(flags, CHF_REPLACED, b); }
3319 void set_overlapped(bool b) { setflag(flags, CHF_OVER, b); }
3320 void set_term(bool b) { setflag(flags, CHF_TERM, b); }
3321 mreg_t get_reg() const { return k.get_reg(); }
3322 sval_t get_stkoff() const { return k.get_stkoff(); }
3323 bool overlap(const chain_t &r) const
3324 { return k.type == r.k.type && interval::overlap(k.off, width, r.k.off, r.width); }
3325 bool includes(const chain_t &r) const
3326 { return k.type == r.k.type && interval::includes(k.off, width, r.k.off, r.width); }
3327 const voff_t endoff() const { return k.add(width); }
3328
3329 bool operator<(const chain_t &r) const { return key() < r.key(); }
3330
3331 void hexapi print(qstring *vout) const;
3332 const char *hexapi dstr(void) const;
3333 /// Append the contents of the chain to the specified list of locations.
3334 void hexapi append_list(const mba_t *mba, mlist_t *list) const;
3335 void clear_varnum(void) { varnum = -1; set_replaced(false); }
3336};
3337
3338//-------------------------------------------------------------------------
3339#if defined(__NT__)
3340#define SIZEOF_BLOCK_CHAINS 24
3341#elif defined(__MAC__)
3342#define SIZEOF_BLOCK_CHAINS 32
3343#else
3344#define SIZEOF_BLOCK_CHAINS 56
3345#endif
3346/// Chains of one block.
3347/// Please note that this class is based on std::map and it must be accessed
3348/// using the block_chains_begin(), block_chains_find() and similar functions.
3349/// This is required because different compilers use different implementations
3350/// of std::map. However, since the size of std::map depends on the compilation
3351/// options, we replace it with a byte array.
3353{
3354 size_t body[SIZEOF_BLOCK_CHAINS/sizeof(size_t)]; // opaque std::set, uncopyable
3355public:
3356
3357 /// Get chain for the specified register
3358 /// \param reg register number
3359 /// \param width size of register in bytes
3360 const chain_t *get_reg_chain(mreg_t reg, int width=1) const
3361 { return get_chain((chain_t(mop_r, reg, width))); }
3362 chain_t *get_reg_chain(mreg_t reg, int width=1)
3363 { return get_chain((chain_t(mop_r, reg, width))); }
3364
3365 /// Get chain for the specified stack offset
3366 /// \param off stack offset
3367 /// \param width size of stack value in bytes
3368 const chain_t *get_stk_chain(sval_t off, int width=1) const
3369 { return get_chain(chain_t(mop_S, off, width)); }
3370 chain_t *get_stk_chain(sval_t off, int width=1)
3371 { return get_chain(chain_t(mop_S, off, width)); }
3372
3373 /// Get chain for the specified value offset.
3374 /// \param k value offset (register number or stack offset)
3375 /// \param width size of value in bytes
3376 const chain_t *get_chain(const voff_t &k, int width=1) const
3377 { return get_chain(chain_t(k, width)); }
3378 chain_t *get_chain(const voff_t &k, int width=1)
3379 { return (chain_t*)((const block_chains_t *)this)->get_chain(k, width); }
3380
3381 /// Get chain similar to the specified chain
3382 /// \param ch chain to search for. only its 'k' and 'width' are used.
3383 const chain_t *hexapi get_chain(const chain_t &ch) const;
3384 chain_t *get_chain(const chain_t &ch)
3385 { return (chain_t*)((const block_chains_t *)this)->get_chain(ch); }
3386
3387 void hexapi print(qstring *vout) const;
3388 const char *hexapi dstr(void) const;
3389 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
3390};
3391//-------------------------------------------------------------------------
3392/// Chain visitor class
3394{
3395 block_chains_t *parent; ///< parent of the current chain
3396 chain_visitor_t(void) : parent(nullptr) {}
3397 virtual int idaapi visit_chain(int nblock, chain_t &ch) = 0;
3398};
3399
3400//-------------------------------------------------------------------------
3401/// Graph chains.
3402/// This class represents all ud and du chains of the decompiled function
3403typedef qvector<block_chains_t> block_chains_vec_t;
3405{
3406 int lock; ///< are chained locked? (in-use)
3407public:
3408 graph_chains_t(void) : lock(0) {}
3409 ~graph_chains_t(void) { QASSERT(50444, !lock); }
3410 /// Visit all chains
3411 /// \param cv chain visitor
3412 /// \param gca_flags combination of GCA_ bits
3413 int hexapi for_all_chains(chain_visitor_t &cv, int gca_flags);
3414 /// \defgroup GCA_ chain visitor flags
3415 //@{
3416#define GCA_EMPTY 0x01 ///< include empty chains
3417#define GCA_SPEC 0x02 ///< include chains for special registers
3418#define GCA_ALLOC 0x04 ///< enumerate only allocated chains
3419#define GCA_NALLOC 0x08 ///< enumerate only non-allocated chains
3420#define GCA_OFIRST 0x10 ///< consider only chains of the first block
3421#define GCA_OLAST 0x20 ///< consider only chains of the last block
3422 //@}
3423 /// Are the chains locked?
3424 /// It is a good idea to lock the chains before using them. This ensures
3425 /// that they won't be recalculated and reallocated during the use.
3426 /// See the \ref chain_keeper_t class for that.
3427 bool is_locked(void) const { return lock != 0; }
3428 /// Lock the chains
3429 void acquire(void) { lock++; }
3430 /// Unlock the chains
3431 void hexapi release(void);
3432 void swap(graph_chains_t &r)
3433 {
3434 qvector<block_chains_t>::swap(r);
3435 std::swap(lock, r.lock);
3436 }
3437};
3438//-------------------------------------------------------------------------
3439/// Microinstruction class #insn
3441{
3442 void hexapi init(ea_t _ea);
3443 void hexapi copy(const minsn_t &m);
3444public:
3445 mcode_t opcode; ///< instruction opcode
3446 int iprops; ///< combination of \ref IPROP_ bits
3447 minsn_t *next; ///< next insn in doubly linked list. check also nexti()
3448 minsn_t *prev; ///< prev insn in doubly linked list. check also previ()
3449 ea_t ea; ///< instruction address
3450 mop_t l; ///< left operand
3451 mop_t r; ///< right operand
3452 mop_t d; ///< destination operand
3453
3454 /// \defgroup IPROP_ instruction property bits
3455 //@{
3456 // bits to be used in patterns:
3457#define IPROP_OPTIONAL 0x0001 ///< optional instruction
3458#define IPROP_PERSIST 0x0002 ///< persistent insn; they are not destroyed
3459#define IPROP_WILDMATCH 0x0004 ///< match multiple insns
3460
3461 // instruction attributes:
3462#define IPROP_CLNPOP 0x0008 ///< the purpose of the instruction is to clean stack
3463 ///< (e.g. "pop ecx" is often used for that)
3464#define IPROP_FPINSN 0x0010 ///< floating point insn
3465#define IPROP_FARCALL 0x0020 ///< call of a far function using push cs/call sequence
3466#define IPROP_TAILCALL 0x0040 ///< tail call
3467#define IPROP_ASSERT 0x0080 ///< assertion: usually mov #val, op.
3468 ///< assertions are used to help the optimizer.
3469 ///< assertions are ignored when generating ctree
3470
3471 // instruction history:
3472#define IPROP_SPLIT 0x0700 ///< the instruction has been split:
3473#define IPROP_SPLIT1 0x0100 ///< into 1 byte
3474#define IPROP_SPLIT2 0x0200 ///< into 2 bytes
3475#define IPROP_SPLIT4 0x0300 ///< into 4 bytes
3476#define IPROP_SPLIT8 0x0400 ///< into 8 bytes
3477#define IPROP_COMBINED 0x0800 ///< insn has been modified because of a partial reference
3478#define IPROP_EXTSTX 0x1000 ///< this is m_ext propagated into m_stx
3479#define IPROP_IGNLOWSRC 0x2000 ///< low part of the instruction source operand
3480 ///< has been created artificially
3481 ///< (this bit is used only for 'and x, 80...')
3482#define IPROP_INV_JX 0x4000 ///< inverted conditional jump
3483#define IPROP_WAS_NORET 0x8000 ///< was noret icall
3484#define IPROP_MULTI_MOV 0x10000 ///< the minsn was generated as part of insn that moves multiple registers
3485 ///< (example: STM on ARM may transfer multiple registers)
3486
3487 ///< bits that can be set by plugins:
3488#define IPROP_DONT_PROP 0x20000 ///< may not propagate
3489#define IPROP_DONT_COMB 0x40000 ///< may not combine this instruction with others
3490#define IPROP_MBARRIER 0x80000 ///< this instruction acts as a memory barrier
3491 ///< (instructions accessing memory may not be reordered past it)
3492#define IPROP_UNMERGED 0x100000 ///< 'goto' instruction was transformed info 'call'
3493 //@}
3494
3495 bool is_optional(void) const { return (iprops & IPROP_OPTIONAL) != 0; }
3496 bool is_combined(void) const { return (iprops & IPROP_COMBINED) != 0; }
3497 bool is_farcall(void) const { return (iprops & IPROP_FARCALL) != 0; }
3498 bool is_cleaning_pop(void) const { return (iprops & IPROP_CLNPOP) != 0; }
3499 bool is_extstx(void) const { return (iprops & IPROP_EXTSTX) != 0; }
3500 bool is_tailcall(void) const { return (iprops & IPROP_TAILCALL) != 0; }
3501 bool is_fpinsn(void) const { return (iprops & IPROP_FPINSN) != 0; }
3502 bool is_assert(void) const { return (iprops & IPROP_ASSERT) != 0; }
3503 bool is_persistent(void) const { return (iprops & IPROP_PERSIST) != 0; }
3504 bool is_wild_match(void) const { return (iprops & IPROP_WILDMATCH) != 0; }
3505 bool is_propagatable(void) const { return (iprops & IPROP_DONT_PROP) == 0; }
3506 bool is_ignlowsrc(void) const { return (iprops & IPROP_IGNLOWSRC) != 0; }
3507 bool is_inverted_jx(void) const { return (iprops & IPROP_INV_JX) != 0; }
3508 bool was_noret_icall(void) const { return (iprops & IPROP_WAS_NORET) != 0; }
3509 bool is_multimov(void) const { return (iprops & IPROP_MULTI_MOV) != 0; }
3510 bool is_combinable(void) const { return (iprops & IPROP_DONT_COMB) == 0; }
3511 bool was_split(void) const { return (iprops & IPROP_SPLIT) != 0; }
3512 bool is_mbarrier(void) const { return (iprops & IPROP_MBARRIER) != 0; }
3513 bool was_unmerged(void) const { return (iprops & IPROP_UNMERGED) != 0; }
3514
3515 void set_optional(void) { iprops |= IPROP_OPTIONAL; }
3516 void hexapi set_combined(void);
3517 void clr_combined(void) { iprops &= ~IPROP_COMBINED; }
3518 void set_farcall(void) { iprops |= IPROP_FARCALL; }
3519 void set_cleaning_pop(void) { iprops |= IPROP_CLNPOP; }
3520 void set_extstx(void) { iprops |= IPROP_EXTSTX; }
3521 void set_tailcall(void) { iprops |= IPROP_TAILCALL; }
3522 void clr_tailcall(void) { iprops &= ~IPROP_TAILCALL; }
3523 void set_fpinsn(void) { iprops |= IPROP_FPINSN; }
3524 void clr_fpinsn(void) { iprops &= ~IPROP_FPINSN; }
3525 void set_assert(void) { iprops |= IPROP_ASSERT; }
3526 void clr_assert(void) { iprops &= ~IPROP_ASSERT; }
3527 void set_persistent(void) { iprops |= IPROP_PERSIST; }
3528 void set_wild_match(void) { iprops |= IPROP_WILDMATCH; }
3529 void clr_propagatable(void) { iprops |= IPROP_DONT_PROP; }
3530 void set_ignlowsrc(void) { iprops |= IPROP_IGNLOWSRC; }
3531 void clr_ignlowsrc(void) { iprops &= ~IPROP_IGNLOWSRC; }
3532 void set_inverted_jx(void) { iprops |= IPROP_INV_JX; }
3533 void set_noret_icall(void) { iprops |= IPROP_WAS_NORET; }
3534 void clr_noret_icall(void) { iprops &= ~IPROP_WAS_NORET; }
3535 void set_multimov(void) { iprops |= IPROP_MULTI_MOV; }
3536 void clr_multimov(void) { iprops &= ~IPROP_MULTI_MOV; }
3537 void set_combinable(void) { iprops &= ~IPROP_DONT_COMB; }
3538 void clr_combinable(void) { iprops |= IPROP_DONT_COMB; }
3539 void set_mbarrier(void) { iprops |= IPROP_MBARRIER; }
3540 void set_unmerged(void) { iprops |= IPROP_UNMERGED; }
3541 void set_split_size(int s)
3542 { // s may be only 1,2,4,8. other values are ignored
3543 iprops &= ~IPROP_SPLIT;
3544 iprops |= (s == 1 ? IPROP_SPLIT1
3545 : s == 2 ? IPROP_SPLIT2
3546 : s == 4 ? IPROP_SPLIT4
3547 : s == 8 ? IPROP_SPLIT8 : 0);
3548 }
3549 int get_split_size(void) const
3550 {
3551 int cnt = (iprops & IPROP_SPLIT) >> 8;
3552 return cnt == 0 ? 0 : 1 << (cnt-1);
3553 }
3554
3555 /// Constructor
3556 minsn_t(ea_t _ea) { init(_ea); }
3557 minsn_t(const minsn_t &m) { next = prev = nullptr; copy(m); } //-V1077 uninitialized: opcode, iprops, ea
3558 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
3559
3560 /// Assignment operator. It does not copy prev/next fields.
3561 minsn_t &operator=(const minsn_t &m) { copy(m); return *this; }
3562
3563 /// Swap two instructions.
3564 /// The prev/next fields are not modified by this function
3565 /// because it would corrupt the doubly linked list.
3566 void hexapi swap(minsn_t &m);
3567
3568 /// Generate insn text into the buffer
3569 void hexapi print(qstring *vout, int shins_flags=SHINS_SHORT|SHINS_VALNUM) const;
3570
3571 /// Get displayable text without tags in a static buffer
3572 const char *hexapi dstr(void) const;
3573
3574 /// Change the instruction address.
3575 /// This function modifies subinstructions as well.
3576 void hexapi setaddr(ea_t new_ea);
3577
3578 /// Optimize one instruction without context.
3579 /// This function does not have access to the instruction context (the
3580 /// previous and next instructions in the list, the block number, etc).
3581 /// It performs only basic optimizations that are available without this info.
3582 /// \param optflags combination of \ref OPTI_ bits
3583 /// \return number of changes, 0-unchanged
3584 /// See also mblock_t::optimize_insn()
3585 int optimize_solo(int optflags=0) { return optimize_subtree(nullptr, nullptr, nullptr, nullptr, optflags); }
3586 /// \defgroup OPTI_ optimization flags
3587 //@{
3588#define OPTI_ADDREXPRS 0x0001 ///< optimize all address expressions (&x+N; &x-&y)
3589#define OPTI_MINSTKREF 0x0002 ///< may update minstkref
3590#define OPTI_COMBINSNS 0x0004 ///< may combine insns (only for optimize_insn)
3591#define OPTI_NO_LDXOPT 0x0008 ///< the function is called after the
3592 ///< propagation attempt, we do not optimize
3593 ///< low/high(ldx) in this case
3594 //@}
3595
3596 /// Optimize instruction in its context.
3597 /// Do not use this function, use mblock_t::optimize()
3598 int hexapi optimize_subtree(
3599 mblock_t *blk,
3600 minsn_t *top,
3601 minsn_t *parent,
3602 ea_t *converted_call,
3603 int optflags=OPTI_MINSTKREF);
3604
3605 /// Visit all instruction operands.
3606 /// This function visits subinstruction operands as well.
3607 /// \param mv operand visitor
3608 /// \return non-zero value returned by mv.visit_mop() or zero
3609 int hexapi for_all_ops(mop_visitor_t &mv);
3610
3611 /// Visit all instructions.
3612 /// This function visits the instruction itself and all its subinstructions.
3613 /// \param mv instruction visitor
3614 /// \return non-zero value returned by mv.visit_mop() or zero
3615 int hexapi for_all_insns(minsn_visitor_t &mv);
3616
3617 /// Convert instruction to nop.
3618 /// This function erases all info but the prev/next fields.
3619 /// In most cases it is better to use mblock_t::make_nop(), which also
3620 /// marks the block lists as dirty.
3621 void hexapi _make_nop(void);
3622
3623 /// Compare instructions.
3624 /// This is the main comparison function for instructions.
3625 /// \param m instruction to compare with
3626 /// \param eqflags combination of \ref EQ_ bits
3627 bool hexapi equal_insns(const minsn_t &m, int eqflags) const; // intelligent comparison
3628 /// \defgroup EQ_ comparison bits
3629 //@{
3630#define EQ_IGNSIZE 0x0001 ///< ignore source operand sizes
3631#define EQ_IGNCODE 0x0002 ///< ignore instruction opcodes
3632#define EQ_CMPDEST 0x0004 ///< compare instruction destinations
3633#define EQ_OPTINSN 0x0008 ///< optimize mop_d operands
3634 //@}
3635
3636 /// Lexographical comparison
3637 /// It can be used to store minsn_t in various containers, like std::set
3638 bool operator <(const minsn_t &ri) const { return lexcompare(ri) < 0; }
3639 int hexapi lexcompare(const minsn_t &ri) const;
3640
3641 //-----------------------------------------------------------------------
3642 // Call instructions
3643 //-----------------------------------------------------------------------
3644 /// Is a non-returing call?
3645 /// \param flags combination of NORET_... bits
3646 bool hexapi is_noret_call(int flags=0);
3647#define NORET_IGNORE_WAS_NORET_ICALL 0x01 // ignore was_noret_icall() bit
3648#define NORET_FORBID_ANALYSIS 0x02 // forbid additional analysis
3649
3650 /// Is an unknown call?
3651 /// Unknown calls are calls without the argument list (mcallinfo_t).
3652 /// Usually the argument lists are determined by mba_t::analyze_calls().
3653 /// Unknown calls exist until the MMAT_CALLS maturity level.
3654 /// See also \ref mblock_t::is_call_block
3655 bool is_unknown_call(void) const { return is_mcode_call(opcode) && d.empty(); }
3656
3657 /// Is a helper call with the specified name?
3658 /// Helper calls usually have well-known function names (see \ref FUNC_NAME_)
3659 /// but they may have any other name. The decompiler does not assume any
3660 /// special meaning for non-well-known names.
3661 bool hexapi is_helper(const char *name) const;
3662
3663 /// Find a call instruction.
3664 /// Check for the current instruction and its subinstructions.
3665 /// \param with_helpers consider helper calls as well?
3666 minsn_t *hexapi find_call(bool with_helpers=false) const;
3667
3668 /// Does the instruction contain a call?
3669 bool contains_call(bool with_helpers=false) const { return find_call(with_helpers) != nullptr; }
3670
3671 /// Does the instruction have a side effect?
3672 /// \param include_ldx_and_divs consider ldx/div/mod as having side effects?
3673 /// stx is always considered as having side effects.
3674 /// Apart from ldx/std only call may have side effects.
3675 bool hexapi has_side_effects(bool include_ldx_and_divs=false) const;
3676
3677 /// Get the function role of a call
3678 funcrole_t get_role(void) const { return d.is_arglist() ? d.f->role : ROLE_UNK; }
3679 bool is_memcpy(void) const { return get_role() == ROLE_MEMCPY; }
3680 bool is_memset(void) const { return get_role() == ROLE_MEMSET; }
3681 bool is_alloca(void) const { return get_role() == ROLE_ALLOCA; }
3682 bool is_bswap (void) const { return get_role() == ROLE_BSWAP; }
3683 bool is_readflags (void) const { return get_role() == ROLE_READFLAGS; }
3684
3685 //-----------------------------------------------------------------------
3686 // Misc
3687 //-----------------------------------------------------------------------
3688 /// Does the instruction have the specified opcode?
3689 /// This function searches subinstructions as well.
3690 /// \param mcode opcode to search for.
3691 bool contains_opcode(mcode_t mcode) const { return find_opcode(mcode) != nullptr; }
3692
3693 /// Find a (sub)insruction with the specified opcode.
3694 /// \param mcode opcode to search for.
3695 const minsn_t *find_opcode(mcode_t mcode) const { return (CONST_CAST(minsn_t*)(this))->find_opcode(mcode); }
3696 minsn_t *hexapi find_opcode(mcode_t mcode);
3697
3698 /// Find an operand that is a subinsruction with the specified opcode.
3699 /// This function checks only the 'l' and 'r' operands of the current insn.
3700 /// \param[out] other pointer to the other operand
3701 /// (&r if we return &l and vice versa)
3702 /// \param op opcode to search for
3703 /// \return &l or &r or nullptr
3704 const minsn_t *hexapi find_ins_op(const mop_t **other, mcode_t op=m_nop) const;
3705 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)); }
3706
3707 /// Find a numeric operand of the current instruction.
3708 /// This function checks only the 'l' and 'r' operands of the current insn.
3709 /// \param[out] other pointer to the other operand
3710 /// (&r if we return &l and vice versa)
3711 /// \return &l or &r or nullptr
3712 const mop_t *hexapi find_num_op(const mop_t **other) const;
3713 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)); }
3714
3715 bool is_mov(void) const { return opcode == m_mov || (opcode == m_f2f && l.size == d.size); }
3716 bool is_like_move(void) const { return is_mov() || is_mcode_xdsu(opcode) || opcode == m_low; }
3717
3718 /// Does the instruction modify its 'd' operand?
3719 /// Some instructions (e.g. m_stx) do not modify the 'd' operand.
3720 bool hexapi modifies_d(void) const;
3721 bool modifies_pair_mop(void) const { return d.t == mop_p && modifies_d(); }
3722
3723 /// Is the instruction in the specified range of instructions?
3724 /// \param m1 beginning of the range in the doubly linked list
3725 /// \param m2 end of the range in the doubly linked list (excluded, may be nullptr)
3726 /// This function assumes that m1 and m2 belong to the same basic block
3727 /// and they are top level instructions.
3728 bool hexapi is_between(const minsn_t *m1, const minsn_t *m2) const;
3729
3730 /// Is the instruction after the specified one?
3731 /// \param m the instruction to compare against in the list
3732 bool is_after(const minsn_t *m) const { return m != nullptr && is_between(m->next, nullptr); }
3733
3734 /// Is it possible for the instruction to use aliased memory?
3735 bool hexapi may_use_aliased_memory(void) const;
3736};
3737
3738/// Skip assertions forward
3739const minsn_t *hexapi getf_reginsn(const minsn_t *ins);
3740/// Skip assertions backward
3741const minsn_t *hexapi getb_reginsn(const minsn_t *ins);
3742inline minsn_t *getf_reginsn(minsn_t *ins) { return CONST_CAST(minsn_t*)(getf_reginsn(CONST_CAST(const minsn_t *)(ins))); }
3743inline minsn_t *getb_reginsn(minsn_t *ins) { return CONST_CAST(minsn_t*)(getb_reginsn(CONST_CAST(const minsn_t *)(ins))); }
3744
3745//-------------------------------------------------------------------------
3746/// Basic block types
3748{
3749 BLT_NONE = 0, ///< unknown block type
3750 BLT_STOP = 1, ///< stops execution regularly (must be the last block)
3751 BLT_0WAY = 2, ///< does not have successors (tail is a noret function)
3752 BLT_1WAY = 3, ///< passes execution to one block (regular or goto block)
3753 BLT_2WAY = 4, ///< passes execution to two blocks (conditional jump)
3754 BLT_NWAY = 5, ///< passes execution to many blocks (switch idiom)
3755 BLT_XTRN = 6, ///< external block (out of function address)
3756};
3757
3758// Maximal bit range
3759#define MAXRANGE bitrange_t(0, USHRT_MAX)
3760
3761//-------------------------------------------------------------------------
3762/// Microcode of one basic block.
3763/// All blocks are part of a doubly linked list. They can also be addressed
3764/// by indexing the mba->natural array. A block contains a doubly linked list
3765/// of instructions, various location lists that are used for data flow
3766/// analysis, and other attributes.
3768{
3769 friend class codegen_t;
3770 DECLARE_UNCOPYABLE(mblock_t)
3771 void hexapi init(void);
3772public:
3773 mblock_t *nextb; ///< next block in the doubly linked list
3774 mblock_t *prevb; ///< previous block in the doubly linked list
3775 uint32 flags; ///< combination of \ref MBL_ bits
3776 /// \defgroup MBL_ Basic block properties
3777 //@{
3778#define MBL_PRIV 0x0001 ///< private block - no instructions except
3779 ///< the specified are accepted (used in patterns)
3780#define MBL_NONFAKE 0x0000 ///< regular block
3781#define MBL_FAKE 0x0002 ///< fake block
3782#define MBL_GOTO 0x0004 ///< this block is a goto target
3783#define MBL_TCAL 0x0008 ///< aritifical call block for tail calls
3784#define MBL_PUSH 0x0010 ///< needs "convert push/pop instructions"
3785#define MBL_DMT64 0x0020 ///< needs "demote 64bits"
3786#define MBL_COMB 0x0040 ///< needs "combine" pass
3787#define MBL_PROP 0x0080 ///< needs 'propagation' pass
3788#define MBL_DEAD 0x0100 ///< needs "eliminate deads" pass
3789#define MBL_LIST 0x0200 ///< use/def lists are ready (not dirty)
3790#define MBL_INCONST 0x0400 ///< inconsistent lists: we are building them
3791#define MBL_CALL 0x0800 ///< call information has been built
3792#define MBL_BACKPROP 0x1000 ///< performed backprop_cc
3793#define MBL_NORET 0x2000 ///< dead end block: doesn't return execution control
3794#define MBL_DSLOT 0x4000 ///< block for delay slot
3795#define MBL_VALRANGES 0x8000 ///< should optimize using value ranges
3796#define MBL_KEEP 0x10000 ///< do not remove even if unreachable
3797 //@}
3798 ea_t start; ///< start address
3799 ea_t end; ///< end address
3800 ///< note: we cannot rely on start/end addresses
3801 ///< very much because instructions are
3802 ///< propagated between blocks
3803 minsn_t *head; ///< pointer to the first instruction of the block
3804 minsn_t *tail; ///< pointer to the last instruction of the block
3805 mba_t *mba; ///< the parent micro block array
3806 int serial; ///< block number
3807 mblock_type_t type; ///< block type (BLT_NONE - not computed yet)
3808
3809 mlist_t dead_at_start; ///< data that is dead at the block entry
3810 mlist_t mustbuse; ///< data that must be used by the block
3811 mlist_t maybuse; ///< data that may be used by the block
3812 mlist_t mustbdef; ///< data that must be defined by the block
3813 mlist_t maybdef; ///< data that may be defined by the block
3814 mlist_t dnu; ///< data that is defined but not used in the block
3815
3816 sval_t maxbsp; ///< maximal sp value in the block (0...stacksize)
3817 sval_t minbstkref; ///< lowest stack location accessible with indirect
3818 ///< addressing (offset from the stack bottom)
3819 ///< initially it is 0 (not computed)
3820 sval_t minbargref; ///< the same for arguments
3821
3822 intvec_t predset; ///< control flow graph: list of our predecessors
3823 ///< use npred() and pred() to access it
3824 intvec_t succset; ///< control flow graph: list of our successors
3825 ///< use nsucc() and succ() to access it
3826
3827 // the exact size of this class is not documented, there may be more fields
3828 char reserved[];
3829
3830 void mark_lists_dirty(void) { flags &= ~MBL_LIST; request_propagation(); }
3831 void request_propagation(void) { flags |= MBL_PROP; }
3832 bool needs_propagation(void) const { return (flags & MBL_PROP) != 0; }
3833 void request_demote64(void) { flags |= MBL_DMT64; }
3834 bool lists_dirty(void) const { return (flags & MBL_LIST) == 0; }
3835 bool lists_ready(void) const { return (flags & (MBL_LIST|MBL_INCONST)) == MBL_LIST; }
3836 int make_lists_ready(void) // returns number of changes
3837 {
3838 if ( lists_ready() )
3839 return 0;
3840 return build_lists(false);
3841 }
3842
3843 /// Get number of block predecessors
3844 int npred(void) const { return predset.size(); } // number of xrefs to the block
3845 /// Get number of block successors
3846 int nsucc(void) const { return succset.size(); } // number of xrefs from the block
3847 // Get predecessor number N
3848 int pred(int n) const { return predset[n]; }
3849 // Get successor number N
3850 int succ(int n) const { return succset[n]; }
3851
3852 mblock_t(void) = delete;
3853 virtual ~mblock_t(void);
3854 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
3855 bool empty(void) const { return head == nullptr; }
3856
3857 /// Print block contents.
3858 /// \param vp print helpers class. it can be used to direct the printed
3859 /// info to any destination
3860 void hexapi print(vd_printer_t &vp) const;
3861
3862 /// Dump block info.
3863 /// This function is useful for debugging, see mba_t::dump for info
3864 void hexapi dump(void) const;
3865 AS_PRINTF(2, 0) void hexapi vdump_block(const char *title, va_list va) const;
3866 AS_PRINTF(2, 3) void dump_block(const char *title, ...) const
3867 {
3868 va_list va;
3869 va_start(va, title);
3870 vdump_block(title, va);
3871 va_end(va);
3872 }
3873
3874 //-----------------------------------------------------------------------
3875 // Functions to insert/remove insns during the microcode optimization phase.
3876 // See codegen_t, microcode_filter_t, udcall_t classes for the initial
3877 // microcode generation.
3878 //-----------------------------------------------------------------------
3879 /// Insert instruction into the doubly linked list
3880 /// \param nm new instruction
3881 /// \param om existing instruction, part of the doubly linked list
3882 /// if nullptr, then the instruction will be inserted at the beginning
3883 /// of the list
3884 /// NM will be inserted immediately after OM
3885 /// \return pointer to NM
3886 minsn_t *hexapi insert_into_block(minsn_t *nm, minsn_t *om);
3887
3888 /// Remove instruction from the doubly linked list
3889 /// \param m instruction to remove
3890 /// The removed instruction is not deleted, the caller gets its ownership
3891 /// \return pointer to the next instruction
3892 minsn_t *hexapi remove_from_block(minsn_t *m);
3893
3894 //-----------------------------------------------------------------------
3895 // Iterator over instructions and operands
3896 //-----------------------------------------------------------------------
3897 /// Visit all instructions.
3898 /// This function visits subinstructions too.
3899 /// \param mv instruction visitor
3900 /// \return zero or the value returned by mv.visit_insn()
3901 /// See also mba_t::for_all_topinsns()
3902 int hexapi for_all_insns(minsn_visitor_t &mv);
3903
3904 /// Visit all operands.
3905 /// This function visit subinstruction operands too.
3906 /// \param mv operand visitor
3907 /// \return zero or the value returned by mv.visit_mop()
3908 int hexapi for_all_ops(mop_visitor_t &mv);
3909
3910 /// Visit all operands that use LIST.
3911 /// \param list ptr to the list of locations. it may be modified:
3912 /// parts that get redefined by the instructions in [i1,i2)
3913 /// will be deleted.
3914 /// \param i1 starting instruction. must be a top level insn.
3915 /// \param i2 ending instruction (excluded). must be a top level insn.
3916 /// \param mmv operand visitor
3917 /// \return zero or the value returned by mmv.visit_mop()
3918 int hexapi for_all_uses(
3919 mlist_t *list,
3920 minsn_t *i1,
3921 minsn_t *i2,
3922 mlist_mop_visitor_t &mmv);
3923
3924 //-----------------------------------------------------------------------
3925 // Optimization functions
3926 //-----------------------------------------------------------------------
3927 /// Optimize one instruction in the context of the block.
3928 /// \param m pointer to a top level instruction
3929 /// \param optflags combination of \ref OPTI_ bits
3930 /// \return number of changes made to the block
3931 /// This function may change other instructions in the block too.
3932 /// However, it will not destroy top level instructions (it may convert them
3933 /// to nop's). This function performs only intrablock modifications.
3934 /// See also minsn_t::optimize_solo()
3935 int hexapi optimize_insn(minsn_t *m, int optflags=OPTI_MINSTKREF|OPTI_COMBINSNS);
3936
3937 /// Optimize a basic block.
3938 /// Usually there is no need to call this function explicitly because the
3939 /// decompiler will call it itself if optinsn_t::func or optblock_t::func
3940 /// return non-zero.
3941 /// \return number of changes made to the block
3942 int hexapi optimize_block(void);
3943
3944 /// Build def-use lists and eliminate deads.
3945 /// \param kill_deads do delete dead instructions?
3946 /// \return the number of eliminated instructions
3947 /// Better mblock_t::call make_lists_ready() rather than this function.
3948 int hexapi build_lists(bool kill_deads);
3949
3950 /// Remove a jump at the end of the block if it is useless.
3951 /// This function preserves any side effects when removing a useless jump.
3952 /// Both conditional and unconditional jumps are handled (and jtbl too).
3953 /// This function deletes useless jumps, not only replaces them with a nop.
3954 /// (please note that \optimize_insn does not handle useless jumps).
3955 /// \return number of changes made to the block
3956 int hexapi optimize_useless_jump(void);
3957
3958 //-----------------------------------------------------------------------
3959 // Functions that build with use/def lists. These lists are used to
3960 // reprsent list of registers and stack locations that are either modified
3961 // or accessed by microinstructions.
3962 //-----------------------------------------------------------------------
3963 /// Append use-list of an operand.
3964 /// This function calculates list of locations that may or must be used
3965 /// by the operand and appends it to LIST.
3966 /// \param list ptr to the output buffer. we will append to it.
3967 /// \param op operand to calculate the use list of
3968 /// \param maymust should we calculate 'may-use' or 'must-use' list?
3969 /// see \ref maymust_t for more details.
3970 /// \param mask if only part of the operand should be considered,
3971 /// a bitmask can be used to specify which part.
3972 /// example: op=AX,mask=0xFF means that we will consider only AL.
3973 void hexapi append_use_list(
3974 mlist_t *list,
3975 const mop_t &op,
3976 maymust_t maymust,
3977 bitrange_t mask=MAXRANGE) const;
3978
3979 /// Append def-list of an operand.
3980 /// This function calculates list of locations that may or must be modified
3981 /// by the operand and appends it to LIST.
3982 /// \param list ptr to the output buffer. we will append to it.
3983 /// \param op operand to calculate the def list of
3984 /// \param maymust should we calculate 'may-def' or 'must-def' list?
3985 /// see \ref maymust_t for more details.
3986 void hexapi append_def_list(
3987 mlist_t *list,
3988 const mop_t &op,
3989 maymust_t maymust) const;
3990
3991 /// Build use-list of an instruction.
3992 /// This function calculates list of locations that may or must be used
3993 /// by the instruction. Examples:
3994 /// "ldx ds.2, eax.4, ebx.4", may-list: all aliasable memory
3995 /// "ldx ds.2, eax.4, ebx.4", must-list: empty
3996 /// Since LDX uses EAX for indirect access, it may access any aliasable
3997 /// memory. On the other hand, we cannot tell for sure which memory cells
3998 /// will be accessed, this is why the must-list is empty.
3999 /// \param ins instruction to calculate the use list of
4000 /// \param maymust should we calculate 'may-use' or 'must-use' list?
4001 /// see \ref maymust_t for more details.
4002 /// \return the calculated use-list
4003 mlist_t hexapi build_use_list(const minsn_t &ins, maymust_t maymust) const;
4004
4005 /// Build def-list of an instruction.
4006 /// This function calculates list of locations that may or must be modified
4007 /// by the instruction. Examples:
4008 /// "stx ebx.4, ds.2, eax.4", may-list: all aliasable memory
4009 /// "stx ebx.4, ds.2, eax.4", must-list: empty
4010 /// Since STX uses EAX for indirect access, it may modify any aliasable
4011 /// memory. On the other hand, we cannot tell for sure which memory cells
4012 /// will be modified, this is why the must-list is empty.
4013 /// \param ins instruction to calculate the def list of
4014 /// \param maymust should we calculate 'may-def' or 'must-def' list?
4015 /// see \ref maymust_t for more details.
4016 /// \return the calculated def-list
4017 mlist_t hexapi build_def_list(const minsn_t &ins, maymust_t maymust) const;
4018
4019 //-----------------------------------------------------------------------
4020 // The use/def lists can be used to search for interesting instructions
4021 //-----------------------------------------------------------------------
4022 /// Is the list used by the specified instruction range?
4023 /// \param list list of locations. LIST may be modified by the function:
4024 /// redefined locations will be removed from it.
4025 /// \param i1 starting instruction of the range (must be a top level insn)
4026 /// \param i2 end instruction of the range (must be a top level insn)
4027 /// i2 is excluded from the range. it can be specified as nullptr.
4028 /// i1 and i2 must belong to the same block.
4029 /// \param maymust should we search in 'may-access' or 'must-access' mode?
4030 bool is_used(mlist_t *list, const minsn_t *i1, const minsn_t *i2, maymust_t maymust=MAY_ACCESS) const
4031 { return find_first_use(list, i1, i2, maymust) != nullptr; }
4032
4033 /// Find the first insn that uses the specified list in the insn range.
4034 /// \param list list of locations. LIST may be modified by the function:
4035 /// redefined locations will be removed from it.
4036 /// \param i1 starting instruction of the range (must be a top level insn)
4037 /// \param i2 end instruction of the range (must be a top level insn)
4038 /// i2 is excluded from the range. it can be specified as nullptr.
4039 /// i1 and i2 must belong to the same block.
4040 /// \param maymust should we search in 'may-access' or 'must-access' mode?
4041 /// \return pointer to such instruction or nullptr.
4042 /// Upon return LIST will contain only locations not redefined
4043 /// by insns [i1..result]
4044 const minsn_t *hexapi find_first_use(mlist_t *list, const minsn_t *i1, const minsn_t *i2, maymust_t maymust=MAY_ACCESS) const;
4045 minsn_t *find_first_use(mlist_t *list, minsn_t *i1, const minsn_t *i2, maymust_t maymust=MAY_ACCESS) const
4046 {
4047 return CONST_CAST(minsn_t*)(find_first_use(list,
4048 CONST_CAST(const minsn_t*)(i1),
4049 i2,
4050 maymust));
4051 }
4052
4053 /// Is the list redefined by the specified instructions?
4054 /// \param list list of locations to check.
4055 /// \param i1 starting instruction of the range (must be a top level insn)
4056 /// \param i2 end instruction of the range (must be a top level insn)
4057 /// i2 is excluded from the range. it can be specified as nullptr.
4058 /// i1 and i2 must belong to the same block.
4059 /// \param maymust should we search in 'may-access' or 'must-access' mode?
4061 const mlist_t &list,
4062 const minsn_t *i1,
4063 const minsn_t *i2,
4064 maymust_t maymust=MAY_ACCESS) const
4065 {
4066 return find_redefinition(list, i1, i2, maymust) != nullptr;
4067 }
4068
4069 /// Find the first insn that redefines any part of the list in the insn range.
4070 /// \param list list of locations to check.
4071 /// \param i1 starting instruction of the range (must be a top level insn)
4072 /// \param i2 end instruction of the range (must be a top level insn)
4073 /// i2 is excluded from the range. it can be specified as nullptr.
4074 /// i1 and i2 must belong to the same block.
4075 /// \param maymust should we search in 'may-access' or 'must-access' mode?
4076 /// \return pointer to such instruction or nullptr.
4077 const minsn_t *hexapi find_redefinition(
4078 const mlist_t &list,
4079 const minsn_t *i1,
4080 const minsn_t *i2,
4081 maymust_t maymust=MAY_ACCESS) const;
4082 minsn_t *find_redefinition(
4083 const mlist_t &list,
4084 minsn_t *i1,
4085 const minsn_t *i2,
4086 maymust_t maymust=MAY_ACCESS) const
4087 {
4088 return CONST_CAST(minsn_t*)(find_redefinition(list,
4089 CONST_CAST(const minsn_t*)(i1),
4090 i2,
4091 maymust));
4092 }
4093
4094 /// Is the right hand side of the instruction redefined the insn range?
4095 /// "right hand side" corresponds to the source operands of the instruction.
4096 /// \param ins instruction to consider
4097 /// \param i1 starting instruction of the range (must be a top level insn)
4098 /// \param i2 end instruction of the range (must be a top level insn)
4099 /// i2 is excluded from the range. it can be specified as nullptr.
4100 /// i1 and i2 must belong to the same block.
4101 bool hexapi is_rhs_redefined(const minsn_t *ins, const minsn_t *i1, const minsn_t *i2) const;
4102
4103 /// Find the instruction that accesses the specified operand.
4104 /// This function search inside one block.
4105 /// \param op operand to search for
4106 /// \param parent ptr to ptr to a top level instruction.
4107 /// denotes the beginning of the search range.
4108 /// \param mend end instruction of the range (must be a top level insn)
4109 /// mend is excluded from the range. it can be specified as nullptr.
4110 /// parent and mend must belong to the same block.
4111 /// \param fdflags combination of \ref FD_ bits
4112 /// \return the instruction that accesses the operand. this instruction
4113 /// may be a sub-instruction. to find out the top level
4114 /// instruction, check out *p_i1.
4115 /// nullptr means 'not found'.
4116 minsn_t *hexapi find_access(
4117 const mop_t &op,
4118 minsn_t **parent,
4119 const minsn_t *mend,
4120 int fdflags) const;
4121 /// \defgroup FD_ bits for mblock_t::find_access
4122 //@{
4123#define FD_BACKWARD 0x0000 ///< search direction
4124#define FD_FORWARD 0x0001 ///< search direction
4125#define FD_USE 0x0000 ///< look for use
4126#define FD_DEF 0x0002 ///< look for definition
4127#define FD_DIRTY 0x0004 ///< ignore possible implicit definitions
4128 ///< by function calls and indirect memory access
4129 //@}
4130
4131 // Convenience functions:
4132 minsn_t *find_def(
4133 const mop_t &op,
4134 minsn_t **p_i1,
4135 const minsn_t *i2,
4136 int fdflags)
4137 {
4138 return find_access(op, p_i1, i2, fdflags|FD_DEF);
4139 }
4140 minsn_t *find_use(
4141 const mop_t &op,
4142 minsn_t **p_i1,
4143 const minsn_t *i2,
4144 int fdflags)
4145 {
4146 return find_access(op, p_i1, i2, fdflags|FD_USE);
4147 }
4148
4149 /// Find possible values for a block.
4150 /// \param res set of value ranges
4151 /// \param vivl what to search for
4152 /// \param vrflags combination of \ref VR_ bits
4153 bool hexapi get_valranges(
4154 valrng_t *res,
4155 const vivl_t &vivl,
4156 int vrflags) const;
4157
4158 /// Find possible values for an instruction.
4159 /// \param res set of value ranges
4160 /// \param vivl what to search for
4161 /// \param m insn to search value ranges at. \sa VR_ bits
4162 /// \param vrflags combination of \ref VR_ bits
4163 bool hexapi get_valranges(
4164 valrng_t *res,
4165 const vivl_t &vivl,
4166 const minsn_t *m,
4167 int vrflags) const;
4168
4169 /// \defgroup VR_ bits for get_valranges
4170 //@{
4171#define VR_AT_START 0x0000 ///< get value ranges before the instruction or
4172 ///< at the block start (if M is nullptr)
4173#define VR_AT_END 0x0001 ///< get value ranges after the instruction or
4174 ///< at the block end, just after the last
4175 ///< instruction (if M is nullptr)
4176#define VR_EXACT 0x0002 ///< find exact match. if not set, the returned
4177 ///< valrng size will be >= vivl.size
4178 //@}
4179
4180 /// Erase the instruction (convert it to nop) and mark the lists dirty.
4181 /// This is the recommended function to use because it also marks the block
4182 /// use-def lists dirty.
4183 void make_nop(minsn_t *m) { m->_make_nop(); mark_lists_dirty(); }
4184
4185 /// Calculate number of regular instructions in the block.
4186 /// Assertions are skipped by this function.
4187 /// \return Number of non-assertion instructions in the block.
4188 size_t hexapi get_reginsn_qty(void) const;
4189
4190 bool is_call_block(void) const { return tail != nullptr && is_mcode_call(tail->opcode); }
4191 bool is_unknown_call(void) const { return tail != nullptr && tail->is_unknown_call(); }
4192 bool is_nway(void) const { return type == BLT_NWAY; }
4193 bool is_branch(void) const { return type == BLT_2WAY && tail->d.t == mop_b; }
4194 bool is_simple_goto_block(void) const
4195 {
4196 return get_reginsn_qty() == 1
4197 && tail->opcode == m_goto
4198 && tail->l.t == mop_b;
4199 }
4200 bool is_simple_jcnd_block() const
4201 {
4202 return is_branch()
4203 && npred() == 1
4204 && get_reginsn_qty() == 1
4205 && is_mcode_convertible_to_set(tail->opcode);
4206 }
4207};
4208//-------------------------------------------------------------------------
4209/// Warning ids
4211{
4212 WARN_VARARG_REGS, ///< 0 cannot handle register arguments in vararg function, discarded them
4213 WARN_ILL_PURGED, ///< 1 odd caller purged bytes %d, correcting
4214 WARN_ILL_FUNCTYPE, ///< 2 invalid function type has been ignored
4215 WARN_VARARG_TCAL, ///< 3 cannot handle tail call to vararg
4216 WARN_VARARG_NOSTK, ///< 4 call vararg without local stack
4217 WARN_VARARG_MANY, ///< 5 too many varargs, some ignored
4218 WARN_ADDR_OUTARGS, ///< 6 cannot handle address arithmetics in outgoing argument area of stack frame -- unused
4219 WARN_DEP_UNK_CALLS, ///< 7 found interdependent unknown calls
4220 WARN_ILL_ELLIPSIS, ///< 8 erroneously detected ellipsis type has been ignored
4221 WARN_GUESSED_TYPE, ///< 9 using guessed type %s;
4222 WARN_EXP_LINVAR, ///< 10 failed to expand a linear variable
4223 WARN_WIDEN_CHAINS, ///< 11 failed to widen chains
4224 WARN_BAD_PURGED, ///< 12 inconsistent function type and number of purged bytes
4225 WARN_CBUILD_LOOPS, ///< 13 too many cbuild loops
4226 WARN_NO_SAVE_REST, ///< 14 could not find valid save-restore pair for %s
4227 WARN_ODD_INPUT_REG, ///< 15 odd input register %s
4228 WARN_ODD_ADDR_USE, ///< 16 odd use of a variable address
4229 WARN_MUST_RET_FP, ///< 17 function return type is incorrect (must be floating point)
4230 WARN_ILL_FPU_STACK, ///< 18 inconsistent fpu stack
4231 WARN_SELFREF_PROP, ///< 19 self-referencing variable has been detected
4232 WARN_WOULD_OVERLAP, ///< 20 variables would overlap: %s
4233 WARN_ARRAY_INARG, ///< 21 array has been used for an input argument
4234 WARN_MAX_ARGS, ///< 22 too many input arguments, some ignored
4235 WARN_BAD_FIELD_TYPE,///< 23 incorrect structure member type for %s::%s, ignored
4236 WARN_WRITE_CONST, ///< 24 write access to const memory at %a has been detected
4237 WARN_BAD_RETVAR, ///< 25 wrong return variable
4238 WARN_FRAG_LVAR, ///< 26 fragmented variable at %s may be wrong
4239 WARN_HUGE_STKOFF, ///< 27 exceedingly huge offset into the stack frame
4240 WARN_UNINITED_REG, ///< 28 reference to an uninitialized register has been removed: %s
4241 WARN_FIXED_MACRO, ///< 29 fixed broken macro-insn
4242 WARN_WRONG_VA_OFF, ///< 30 wrong offset of va_list variable
4243 WARN_CR_NOFIELD, ///< 31 CONTAINING_RECORD: no field '%s' in struct '%s' at %d
4244 WARN_CR_BADOFF, ///< 32 CONTAINING_RECORD: too small offset %d for struct '%s'
4245 WARN_BAD_STROFF, ///< 33 user specified stroff has not been processed: %s
4246 WARN_BAD_VARSIZE, ///< 34 inconsistent variable size for '%s'
4247 WARN_UNSUPP_REG, ///< 35 unsupported processor register '%s'
4248 WARN_UNALIGNED_ARG, ///< 36 unaligned function argument '%s'
4249 WARN_BAD_STD_TYPE, ///< 37 corrupted or unexisting local type '%s'
4250 WARN_BAD_CALL_SP, ///< 38 bad sp value at call
4251 WARN_MISSED_SWITCH, ///< 39 wrong markup of switch jump, skipped it
4252 WARN_BAD_SP, ///< 40 positive sp value %a has been found
4253 WARN_BAD_STKPNT, ///< 41 wrong sp change point
4254 WARN_UNDEF_LVAR, ///< 42 variable '%s' is possibly undefined
4255 WARN_JUMPOUT, ///< 43 control flows out of bounds
4256 WARN_BAD_VALRNG, ///< 44 values range analysis failed
4257 WARN_BAD_SHADOW, ///< 45 ignored the value written to the shadow area of the succeeding call
4258 WARN_OPT_VALRNG, ///< 46 conditional instruction was optimized away because %s
4259 WARN_RET_LOCREF, ///< 47 returning address of temporary local variable '%s'
4260 WARN_BAD_MAPDST, ///< 48 too short map destination '%s' for variable '%s'
4261 WARN_BAD_INSN, ///< 49 bad instruction
4262 WARN_ODD_ABI, ///< 50 encountered odd instruction for the current ABI
4263 WARN_UNBALANCED_STACK, ///< 51 unbalanced stack, ignored a potential tail call
4264
4265 WARN_OPT_VALRNG2, ///< 52 mask 0x%X is shortened because %s <= 0x%X"
4266
4267 WARN_OPT_VALRNG3, ///< 53 masking with 0X%X was optimized away because %s <= 0x%X
4268 WARN_OPT_USELESS_JCND, ///< 54 simplified comparisons for '%s': %s became %s
4269 WARN_MAX, ///< may be used in notes as a placeholder when the
4270 ///< warning id is not available
4271};
4272
4273/// Warning instances
4275{
4276 ea_t ea; ///< Address where the warning occurred
4277 warnid_t id; ///< Warning id
4278 qstring text; ///< Fully formatted text of the warning
4279 DECLARE_COMPARISONS(hexwarn_t)
4280 {
4281 if ( ea < r.ea )
4282 return -1;
4283 if ( ea > r.ea )
4284 return 1;
4285 if ( id < r.id )
4286 return -1;
4287 if ( id > r.id )
4288 return 1;
4289 return strcmp(text.c_str(), r.text.c_str());
4290 }
4291};
4292DECLARE_TYPE_AS_MOVABLE(hexwarn_t);
4293typedef qvector<hexwarn_t> hexwarns_t;
4294
4295//-------------------------------------------------------------------------
4296/// Microcode maturity levels
4298{
4299 MMAT_ZERO, ///< microcode does not exist
4300 MMAT_GENERATED, ///< generated microcode
4301 MMAT_PREOPTIMIZED, ///< preoptimized pass is complete
4302 MMAT_LOCOPT, ///< local optimization of each basic block is complete.
4303 ///< control flow graph is ready too.
4304 MMAT_CALLS, ///< detected call arguments
4305 MMAT_GLBOPT1, ///< performed the first pass of global optimization
4306 MMAT_GLBOPT2, ///< most global optimization passes are done
4307 MMAT_GLBOPT3, ///< completed all global optimization. microcode is fixed now.
4308 MMAT_LVARS, ///< allocated local variables
4309};
4310
4311//-------------------------------------------------------------------------
4312enum memreg_index_t ///< memory region types
4313{
4314 MMIDX_GLBLOW, ///< global memory: low part
4315 MMIDX_LVARS, ///< stack: local variables
4316 MMIDX_RETADDR, ///< stack: return address
4317 MMIDX_SHADOW, ///< stack: shadow arguments
4318 MMIDX_ARGS, ///< stack: regular stack arguments
4319 MMIDX_GLBHIGH, ///< global memory: high part
4320};
4321
4322//-------------------------------------------------------------------------
4323/// Ranges to decompile. Either a function or an explicit vector of ranges.
4325{
4326 func_t *pfn = nullptr; ///< function to decompile. if not null, then function mode.
4327 rangevec_t ranges; ///< snippet mode: ranges to decompile.
4328 ///< function mode: list of outlined ranges
4329 mba_ranges_t(func_t *_pfn=nullptr) : pfn(_pfn) {}
4330 mba_ranges_t(const rangevec_t &r) : ranges(r) {}
4331 ea_t start(void) const { return (pfn != nullptr ? *pfn : ranges[0]).start_ea; }
4332 bool empty(void) const { return pfn == nullptr && ranges.empty(); }
4333 void clear(void) { pfn = nullptr; ranges.clear(); }
4334 bool is_snippet(void) const { return pfn == nullptr; }
4335 bool hexapi range_contains(ea_t ea) const;
4336 bool is_fragmented(void) const
4337 {
4338 int n_frags = ranges.size();
4339 if ( pfn != nullptr )
4340 n_frags += pfn->tailqty + 1;
4341 return n_frags > 1;
4342 }
4343};
4344
4345/// Item iterator of arbitrary rangevec items
4347{
4348 const rangevec_t *ranges = nullptr;
4349 const range_t *rptr = nullptr; // pointer into ranges
4350 ea_t cur = BADADDR; // current address
4351 bool set(const rangevec_t &r);
4352 bool next_code(void);
4353 ea_t current(void) const { return cur; }
4354};
4355
4356/// Item iterator for mba_ranges_t
4358{
4360 func_item_iterator_t fii;
4361 bool func_items_done = true;
4362 bool set(const mba_ranges_t &mbr)
4363 {
4364 bool ok = false;
4365 if ( mbr.pfn != nullptr )
4366 {
4367 ok = fii.set(mbr.pfn);
4368 if ( ok )
4369 func_items_done = false;
4370 }
4371 if ( rii.set(mbr.ranges) )
4372 ok = true;
4373 return ok;
4374 }
4375 bool next_code(void)
4376 {
4377 bool ok = false;
4378 if ( !func_items_done )
4379 {
4380 ok = fii.next_code();
4381 if ( !ok )
4382 func_items_done = true;
4383 }
4384 if ( !ok )
4385 ok = rii.next_code();
4386 return ok;
4387 }
4388 ea_t current(void) const
4389 {
4390 return func_items_done ? rii.current() : fii.current();
4391 }
4392};
4393
4394/// Chunk iterator of arbitrary rangevec items
4396{
4397 const range_t *rptr = nullptr; // pointer into ranges
4398 const range_t *rend = nullptr;
4399 bool set(const rangevec_t &r) { rptr = r.begin(); rend = r.end(); return rptr != rend; }
4400 bool next(void) { return ++rptr != rend; }
4401 const range_t &chunk(void) const { return *rptr; }
4402};
4403
4404/// Chunk iterator for mba_ranges_t
4406{
4408 func_tail_iterator_t fii; // this is used if rii.rptr==nullptr
4409 bool is_snippet(void) const { return rii.rptr != nullptr; }
4410 bool set(const mba_ranges_t &mbr)
4411 {
4412 if ( mbr.is_snippet() )
4413 return rii.set(mbr.ranges);
4414 else
4415 return fii.set(mbr.pfn);
4416 }
4417 bool next(void)
4418 {
4419 if ( is_snippet() )
4420 return rii.next();
4421 else
4422 return fii.next();
4423 }
4424 const range_t &chunk(void) const
4425 {
4426 return is_snippet() ? rii.chunk() : fii.chunk();
4427 }
4428};
4429
4430//-------------------------------------------------------------------------
4431/// Array of micro blocks representing microcode for a decompiled function.
4432/// The first micro block is the entry point, the last one is the exit point.
4433/// The entry and exit blocks are always empty. The exit block is generated
4434/// at MMAT_LOCOPT maturity level.
4435class mba_t
4436{
4437 DECLARE_UNCOPYABLE(mba_t)
4438 uint32 flags;
4439 uint32 flags2;
4440
4441public:
4442 // bits to describe the microcode, set by the decompiler
4443#define MBA_PRCDEFS 0x00000001 ///< use precise defeas for chain-allocated lvars
4444#define MBA_NOFUNC 0x00000002 ///< function is not present, addresses might be wrong
4445#define MBA_PATTERN 0x00000004 ///< microcode pattern, callinfo is present
4446#define MBA_LOADED 0x00000008 ///< loaded gdl, no instructions (debugging)
4447#define MBA_RETFP 0x00000010 ///< function returns floating point value
4448#define MBA_SPLINFO 0x00000020 ///< (final_type ? idb_spoiled : spoiled_regs) is valid
4449#define MBA_PASSREGS 0x00000040 ///< has mcallinfo_t::pass_regs
4450#define MBA_THUNK 0x00000080 ///< thunk function
4451#define MBA_CMNSTK 0x00000100 ///< stkvars+stkargs should be considered as one area
4452
4453 // bits to describe analysis stages and requests
4454#define MBA_PREOPT 0x00000200 ///< preoptimization stage complete
4455#define MBA_CMBBLK 0x00000400 ///< request to combine blocks
4456#define MBA_ASRTOK 0x00000800 ///< assertions have been generated
4457#define MBA_CALLS 0x00001000 ///< callinfo has been built
4458#define MBA_ASRPROP 0x00002000 ///< assertion have been propagated
4459#define MBA_SAVRST 0x00004000 ///< save-restore analysis has been performed
4460#define MBA_RETREF 0x00008000 ///< return type has been refined
4461#define MBA_GLBOPT 0x00010000 ///< microcode has been optimized globally
4462#define MBA_LVARS0 0x00040000 ///< lvar pre-allocation has been performed
4463#define MBA_LVARS1 0x00080000 ///< lvar real allocation has been performed
4464#define MBA_DELPAIRS 0x00100000 ///< pairs have been deleted once
4465#define MBA_CHVARS 0x00200000 ///< can verify chain varnums
4466
4467 // bits that can be set by the caller:
4468#define MBA_SHORT 0x00400000 ///< use short display
4469#define MBA_COLGDL 0x00800000 ///< display graph after each reduction
4470#define MBA_INSGDL 0x01000000 ///< display instruction in graphs
4471#define MBA_NICE 0x02000000 ///< apply transformations to c code
4472#define MBA_REFINE 0x04000000 ///< may refine return value size
4473#define MBA_WINGR32 0x10000000 ///< use wingraph32
4474#define MBA_NUMADDR 0x20000000 ///< display definition addresses for numbers
4475#define MBA_VALNUM 0x40000000 ///< display value numbers
4476
4477#define MBA_INITIAL_FLAGS (MBA_INSGDL|MBA_NICE|MBA_CMBBLK|MBA_REFINE\
4478 |MBA_PRCDEFS|MBA_WINGR32|MBA_VALNUM)
4479
4480#define MBA2_LVARNAMES_OK 0x00000001 ///< may verify lvar_names?
4481#define MBA2_LVARS_RENAMED 0x00000002 ///< accept empty names now?
4482#define MBA2_OVER_CHAINS 0x00000004 ///< has overlapped chains?
4483#define MBA2_VALRNG_DONE 0x00000008 ///< calculated valranges?
4484#define MBA2_IS_CTR 0x00000010 ///< is constructor?
4485#define MBA2_IS_DTR 0x00000020 ///< is destructor?
4486#define MBA2_ARGIDX_OK 0x00000040 ///< may verify input argument list?
4487#define MBA2_NO_DUP_CALLS 0x00000080 ///< forbid multiple calls with the same ea
4488#define MBA2_NO_DUP_LVARS 0x00000100 ///< forbid multiple lvars with the same ea
4489#define MBA2_UNDEF_RETVAR 0x00000200 ///< return value is undefined
4490#define MBA2_ARGIDX_SORTED 0x00000400 ///< args finally sorted according to ABI
4491 ///< (e.g. reverse stkarg order in Borland)
4492#define MBA2_CODE16_BIT 0x00000800 ///< the code16 bit removed
4493#define MBA2_STACK_RETVAL 0x00001000 ///< the return value is on the stack
4494#define MBA2_HAS_OUTLINES 0x00002000 ///< calls to outlined code have been inlined
4495#define MBA2_NO_FRAME 0x00004000 ///< do not use function frame info (only snippet mode)
4496
4497#define MBA2_DONT_VERIFY 0x80000000 ///< Do not verify microcode. This flag
4498 ///< is recomended to be set only when
4499 ///< debugging decompiler plugins
4500
4501#define MBA2_INITIAL_FLAGS (MBA2_LVARNAMES_OK|MBA2_LVARS_RENAMED)
4502
4503#define MBA2_ALL_FLAGS 0x00007FFF
4504
4505 bool precise_defeas(void) const { return (flags & MBA_PRCDEFS) != 0; }
4506 bool optimized(void) const { return (flags & MBA_GLBOPT) != 0; }
4507 bool short_display(void) const { return (flags & MBA_SHORT ) != 0; }
4508 bool show_reduction(void) const { return (flags & MBA_COLGDL) != 0; }
4509 bool graph_insns(void) const { return (flags & MBA_INSGDL) != 0; }
4510 bool loaded_gdl(void) const { return (flags & MBA_LOADED) != 0; }
4511 bool should_beautify(void)const { return (flags & MBA_NICE ) != 0; }
4512 bool rtype_refined(void) const { return (flags & MBA_RETREF) != 0; }
4513 bool may_refine_rettype(void) const { return (flags & MBA_REFINE) != 0; }
4514 bool use_wingraph32(void) const { return (flags & MBA_WINGR32) != 0; }
4515 bool display_numaddrs(void) const { return (flags & MBA_NUMADDR) != 0; }
4516 bool display_valnums(void) const { return (flags & MBA_VALNUM) != 0; }
4517 bool is_pattern(void) const { return (flags & MBA_PATTERN) != 0; }
4518 bool is_thunk(void) const { return (flags & MBA_THUNK) != 0; }
4519 bool saverest_done(void) const { return (flags & MBA_SAVRST) != 0; }
4520 bool callinfo_built(void) const { return (flags & MBA_CALLS) != 0; }
4521 bool really_alloc(void) const { return (flags & MBA_LVARS0) != 0; }
4522 bool lvars_allocated(void)const { return (flags & MBA_LVARS1) != 0; }
4523 bool chain_varnums_ok(void)const { return (flags & MBA_CHVARS) != 0; }
4524 bool returns_fpval(void) const { return (flags & MBA_RETFP) != 0; }
4525 bool has_passregs(void) const { return (flags & MBA_PASSREGS) != 0; }
4526 bool generated_asserts(void) const { return (flags & MBA_ASRTOK) != 0; }
4527 bool propagated_asserts(void) const { return (flags & MBA_ASRPROP) != 0; }
4528 bool deleted_pairs(void) const { return (flags & MBA_DELPAIRS) != 0; }
4529 bool common_stkvars_stkargs(void) const { return (flags & MBA_CMNSTK) != 0; }
4530 bool lvar_names_ok(void) const { return (flags2 & MBA2_LVARNAMES_OK) != 0; }
4531 bool lvars_renamed(void) const { return (flags2 & MBA2_LVARS_RENAMED) != 0; }
4532 bool has_over_chains(void) const { return (flags2 & MBA2_OVER_CHAINS) != 0; }
4533 bool valranges_done(void) const { return (flags2 & MBA2_VALRNG_DONE) != 0; }
4534 bool argidx_ok(void) const { return (flags2 & MBA2_ARGIDX_OK) != 0; }
4535 bool argidx_sorted(void) const { return (flags2 & MBA2_ARGIDX_SORTED) != 0; }
4536 bool code16_bit_removed(void) const { return (flags2 & MBA2_CODE16_BIT) != 0; }
4537 bool has_stack_retval(void) const { return (flags2 & MBA2_STACK_RETVAL) != 0; }
4538 bool has_outlines(void) const { return (flags2 & MBA2_HAS_OUTLINES) != 0; }
4539 bool is_ctr(void) const { return (flags2 & MBA2_IS_CTR) != 0; }
4540 bool is_dtr(void) const { return (flags2 & MBA2_IS_DTR) != 0; }
4541 bool is_cdtr(void) const { return (flags2 & (MBA2_IS_CTR|MBA2_IS_DTR)) != 0; }
4542 int get_mba_flags(void) const { return flags; }
4543 int get_mba_flags2(void) const { return flags2; }
4544 void set_mba_flags(int f) { flags |= f; }
4545 void clr_mba_flags(int f) { flags &= ~f; }
4546 void set_mba_flags2(int f) { flags2 |= f; }
4547 void clr_mba_flags2(int f) { flags2 &= ~f; }
4548 void clr_cdtr(void) { flags2 &= ~(MBA2_IS_CTR|MBA2_IS_DTR); }
4549 int calc_shins_flags(void) const
4550 {
4551 int shins_flags = 0;
4552 if ( short_display() )
4553 shins_flags |= SHINS_SHORT;
4554 if ( display_valnums() )
4555 shins_flags |= SHINS_VALNUM;
4556 if ( display_numaddrs() )
4557 shins_flags |= SHINS_NUMADDR;
4558 return shins_flags;
4559 }
4560
4561/*
4562 +-----------+ <- inargtop
4563 | prmN |
4564 | ... | <- minargref
4565 | prm0 |
4566 +-----------+ <- inargoff
4567 |shadow_args|
4568 +-----------+
4569 | retaddr |
4570 frsize+frregs +-----------+ <- initial esp |
4571 | frregs | |
4572 +frsize +-----------+ <- typical ebp |
4573 | | | |
4574 | | | fpd |
4575 | | | |
4576 | frsize | <- current ebp |
4577 | | |
4578 | | |
4579 | | | stacksize
4580 | | |
4581 | | |
4582 | | <- minstkref |
4583 stkvar base off 0 +---.. | | | current
4584 | | | | stack
4585 | | | | pointer
4586 | | | | range
4587 |tmpstk_size| | | (what getspd() returns)
4588 | | | |
4589 | | | |
4590 +-----------+ <- minimal sp | | offset 0 for the decompiler (vd)
4591
4592 There is a detail that may add confusion when working with stack variables.
4593 The decompiler does not use the same stack offsets as IDA.
4594 The picture above should explain the difference:
4595 - IDA stkoffs are displayed on the left, decompiler stkoffs - on the right
4596 - Decompiler stkoffs are always >= 0
4597 - IDA stkoff==0 corresponds to stkoff==tmpstk_size in the decompiler
4598 - See stkoff_vd2ida and stkoff_ida2vd below to convert IDA stkoffs to vd stkoff
4599
4600*/
4601
4602 // convert a stack offset used in vd to a stack offset used in ida stack frame
4603 sval_t stkoff_vd2ida(sval_t off) const
4604 {
4605 return off - tmpstk_size;
4606 }
4607 // convert a ida stack frame offset to a stack offset used in vd
4608 sval_t stkoff_ida2vd(sval_t off) const
4609 {
4610 return off + tmpstk_size;
4611 }
4612 sval_t argbase() const
4613 {
4614 return retsize + stacksize;
4615 }
4616 static vdloc_t hexapi idaloc2vd(const argloc_t &loc, int width, sval_t spd);
4617 vdloc_t hexapi idaloc2vd(const argloc_t &loc, int width) const;
4618
4619 static argloc_t hexapi vd2idaloc(const vdloc_t &loc, int width, sval_t spd);
4620 argloc_t hexapi vd2idaloc(const vdloc_t &loc, int width) const;
4621
4622 bool is_stkarg(const lvar_t &v) const
4623 {
4624 return v.is_stk_var() && v.get_stkoff() >= inargoff;
4625 }
4626 member_t *get_stkvar(sval_t vd_stkoff, uval_t *poff) const;
4627 // get lvar location
4628 argloc_t get_ida_argloc(const lvar_t &v) const
4629 {
4630 return vd2idaloc(v.location, v.width);
4631 }
4632 mba_ranges_t mbr;
4633 ea_t entry_ea;
4634 ea_t last_prolog_ea;
4635 ea_t first_epilog_ea;
4636 int qty; ///< number of basic blocks
4637 int npurged; ///< -1 - unknown
4638 cm_t cc; ///< calling convention
4639 sval_t tmpstk_size; ///< size of the temporary stack part
4640 ///< (which dynamically changes with push/pops)
4641 sval_t frsize; ///< size of local stkvars range in the stack frame
4642 sval_t frregs; ///< size of saved registers range in the stack frame
4643 sval_t fpd; ///< frame pointer delta
4644 int pfn_flags; ///< copy of func_t::flags
4645 int retsize; ///< size of return address in the stack frame
4646 int shadow_args; ///< size of shadow argument area
4647 sval_t fullsize; ///< Full stack size including incoming args
4648 sval_t stacksize; ///< The maximal size of the function stack including
4649 ///< bytes allocated for outgoing call arguments
4650 ///< (up to retaddr)
4651 sval_t inargoff; ///< offset of the first stack argument;
4652 ///< after fix_scattered_movs() INARGOFF may
4653 ///< be less than STACKSIZE
4654 sval_t minstkref; ///< The lowest stack location whose address was taken
4655 ea_t minstkref_ea; ///< address with lowest minstkref (for debugging)
4656 sval_t minargref; ///< The lowest stack argument location whose address was taken
4657 ///< This location and locations above it can be aliased
4658 ///< It controls locations >= inargoff-shadow_args
4659 sval_t spd_adjust; ///< If sp>0, the max positive sp value
4660 ivl_t aliased_vars; ///< Aliased stkvar locations
4661 ivl_t aliased_args; ///< Aliased stkarg locations
4662 ivlset_t gotoff_stkvars; ///< stkvars that hold .got offsets. considered to be unaliasable
4663 ivlset_t restricted_memory;
4664 ivlset_t aliased_memory; ///< aliased_memory+restricted_memory=ALLMEM
4665 mlist_t nodel_memory; ///< global dead elimination may not delete references to this area
4666 rlist_t consumed_argregs; ///< registers converted into stack arguments, should not be used as arguments
4667
4668 mba_maturity_t maturity; ///< current maturity level
4669 mba_maturity_t reqmat; ///< required maturity level
4670
4671 bool final_type; ///< is the function type final? (specified by the user)
4672 tinfo_t idb_type; ///< function type as retrieved from the database
4673 reginfovec_t idb_spoiled; ///< MBA_SPLINFO && final_type: info in ida format
4674 mlist_t spoiled_list; ///< MBA_SPLINFO && !final_type: info in vd format
4675 int fti_flags; ///< FTI_... constants for the current function
4676
4677 netnode deprecated_idb_node; ///< netnode with additional decompiler info.
4678 ///< deprecated, do not use it anymore. it may get
4679 ///< stale after undo.
4680#define NALT_VD 2 ///< this index is not used by ida
4681
4682 qstring label; ///< name of the function or pattern (colored)
4683 lvars_t vars; ///< local variables
4684 intvec_t argidx; ///< input arguments (indexes into 'vars')
4685 int retvaridx; ///< index of variable holding the return value
4686 ///< -1 means none
4687
4688 ea_t error_ea; ///< during microcode generation holds ins.ea
4689 qstring error_strarg;
4690
4691 mblock_t *blocks; ///< double linked list of blocks
4692 mblock_t **natural; ///< natural order of blocks
4693
4694 ivl_with_name_t std_ivls[6]; ///< we treat memory as consisting of 6 parts
4695 ///< see \ref memreg_index_t
4696
4697 mutable hexwarns_t notes;
4698 mutable uchar occurred_warns[32]; // occurred warning messages
4699 // (even disabled warnings are taken into account)
4700 bool write_to_const_detected(void) const
4701 {
4702 return test_bit(occurred_warns, WARN_WRITE_CONST);
4703 }
4704 bool bad_call_sp_detected(void) const
4705 {
4706 return test_bit(occurred_warns, WARN_BAD_CALL_SP);
4707 }
4708 bool regargs_is_not_aligned(void) const
4709 {
4710 return test_bit(occurred_warns, WARN_UNALIGNED_ARG);
4711 }
4712 bool has_bad_sp(void) const
4713 {
4714 return test_bit(occurred_warns, WARN_BAD_SP);
4715 }
4716
4717 // the exact size of this class is not documented, there may be more fields
4718 char reserved[];
4719 mba_t(void);
4720 ~mba_t(void) { term(); }
4721 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
4722 void hexapi term(void);
4723 func_t *hexapi get_curfunc() const;
4724 bool use_frame(void) const { return get_curfunc() != nullptr; }
4725 bool range_contains(ea_t ea) const { return mbr.range_contains(map_fict_ea(ea)); }
4726 bool is_snippet(void) const { return mbr.is_snippet(); }
4727
4728 /// Set maturity level.
4729 /// \param mat new maturity level
4730 /// \return true if it is time to stop analysis
4731 /// Plugins may use this function to skip some parts of the analysis.
4732 /// The maturity level cannot be decreased.
4733 bool hexapi set_maturity(mba_maturity_t mat);
4734
4735 /// Optimize each basic block locally
4736 /// \param locopt_bits combination of \ref LOCOPT_ bits
4737 /// \return number of changes. 0 means nothing changed
4738 /// This function is called by the decompiler, usually there is no need to
4739 /// call it explicitly.
4740 int hexapi optimize_local(int locopt_bits);
4741 /// \defgroup LOCOPT_ Bits for optimize_local()
4742 //@{
4743#define LOCOPT_ALL 0x0001 ///< redo optimization for all blocks. if this bit
4744 ///< is not set, only dirty blocks will be optimized
4745#define LOCOPT_REFINE 0x0002 ///< refine return type, ok to fail
4746#define LOCOPT_REFINE2 0x0004 ///< refine return type, try harder
4747 //@}
4748
4749 /// Build control flow graph.
4750 /// This function may be called only once. It calculates the type of each
4751 /// basic block and the adjacency list. optimize_local() calls this function
4752 /// if necessary. You need to call this function only before MMAT_LOCOPT.
4753 /// \return error code
4754 merror_t hexapi build_graph(void);
4755
4756 /// Get control graph.
4757 /// Call build_graph() if you need the graph before MMAT_LOCOPT.
4758 mbl_graph_t *hexapi get_graph(void);
4759
4760 /// Analyze calls and determine calling conventions.
4761 /// \param acflags permitted actions that are necessary for successful detection
4762 /// of calling conventions. See \ref ACFL_
4763 /// \return number of calls. -1 means error.
4764 int hexapi analyze_calls(int acflags);
4765 /// \defgroup ACFL_ Bits for analyze_calls()
4766 //@{
4767#define ACFL_LOCOPT 0x01 ///< perform local propagation (requires ACFL_BLKOPT)
4768#define ACFL_BLKOPT 0x02 ///< perform interblock transformations
4769#define ACFL_GLBPROP 0x04 ///< perform global propagation
4770#define ACFL_GLBDEL 0x08 ///< perform dead code eliminition
4771#define ACFL_GUESS 0x10 ///< may guess calling conventions
4772 //@}
4773
4774 /// Optimize microcode globally.
4775 /// This function applies various optimization methods until we reach the
4776 /// fixed point. After that it preallocates lvars unless reqmat forbids it.
4777 /// \return error code
4778 merror_t hexapi optimize_global(void);
4779
4780 /// Allocate local variables.
4781 /// Must be called only immediately after optimize_global(), with no
4782 /// modifications to the microcode. Converts registers,
4783 /// stack variables, and similar operands into mop_l. This call will not fail
4784 /// because all necessary checks were performed in optimize_global().
4785 /// After this call the microcode reaches its final state.
4786 void hexapi alloc_lvars(void);
4787
4788 /// Dump microcode to a file.
4789 /// The file will be created in the directory pointed by IDA_DUMPDIR envvar.
4790 /// Dump will be created only if IDA is run under debugger.
4791 void hexapi dump(void) const;
4792 AS_PRINTF(3, 0) void hexapi vdump_mba(bool _verify, const char *title, va_list va) const;
4793 AS_PRINTF(3, 4) void dump_mba(bool _verify, const char *title, ...) const
4794 {
4795 va_list va;
4796 va_start(va, title);
4797 vdump_mba(_verify, title, va);
4798 va_end(va);
4799 }
4800
4801 /// Print microcode to any destination.
4802 /// \param vp print sink
4803 void hexapi print(vd_printer_t &vp) const;
4804
4805 /// Verify microcode consistency.
4806 /// \param always if false, the check will be performed only if ida runs
4807 /// under debugger
4808 /// If any inconsistency is discovered, an internal error will be generated.
4809 /// We strongly recommend you to call this function before returing control
4810 /// to the decompiler from your callbacks, in the case if you modified
4811 /// the microcode.
4812 void hexapi verify(bool always) const;
4813
4814 /// Mark the microcode use-def chains dirty.
4815 /// Call this function is any inter-block data dependencies got changed
4816 /// because of your modifications to the microcode. Failing to do so may
4817 /// cause an internal error.
4818 void hexapi mark_chains_dirty(void);
4819
4820 /// Get basic block by its serial number.
4821 const mblock_t *get_mblock(int n) const { return natural[n]; }
4822 mblock_t *get_mblock(int n) { return CONST_CAST(mblock_t*)((CONST_CAST(const mba_t *)(this))->get_mblock(n)); }
4823
4824 /// Insert a block in the middle of the mbl array.
4825 /// The very first block of microcode must be empty, it is the entry block.
4826 /// The very last block of microcode must be BLT_STOP, it is the exit block.
4827 /// Therefore inserting a new block before the entry point or after the exit
4828 /// block is not a good idea.
4829 /// \param bblk the new block will be inserted before BBLK
4830 /// \return ptr to the new block
4831 mblock_t *hexapi insert_block(int bblk);
4832
4833 /// Delete a block.
4834 /// \param blk block to delete
4835 /// \return true if at least one of the other blocks became empty or unreachable
4836 bool hexapi remove_block(mblock_t *blk);
4837
4838 /// Make a copy of a block.
4839 /// This function makes a simple copy of the block. It does not fix the
4840 /// predecessor and successor lists, they must be fixed if necessary.
4841 /// \param blk block to copy
4842 /// \param new_serial position of the copied block
4843 /// \param cpblk_flags combination of \ref CPBLK_... bits
4844 /// \return pointer to the new copy
4845 mblock_t *hexapi copy_block(mblock_t *blk, int new_serial, int cpblk_flags=3);
4846/// \defgroup CPBLK_ Batch decompilation bits
4847//@{
4848#define CPBLK_FAST 0x0000 ///< do not update minbstkref and minbargref
4849#define CPBLK_MINREF 0x0001 ///< update minbstkref and minbargref
4850#define CPBLK_OPTJMP 0x0002 ///< del the jump insn at the end of the block
4851 ///< if it becomes useless
4852//@}
4853
4854 /// Delete all empty and unreachable blocks.
4855 /// Blocks marked with MBL_KEEP won't be deleted.
4856 bool hexapi remove_empty_and_unreachable_blocks(void);
4857
4858 /// Combine blocks.
4859 /// This function merges blocks constituting linear flow.
4860 /// It calls remove_empty_and_unreachable_blocks() as well.
4861 /// \return true if changed any blocks
4862 bool hexapi combine_blocks(void);
4863
4864 /// Visit all operands of all instructions.
4865 /// \param mv operand visitor
4866 /// \return non-zero value returned by mv.visit_mop() or zero
4867 int hexapi for_all_ops(mop_visitor_t &mv);
4868
4869 /// Visit all instructions.
4870 /// This function visits all instruction and subinstructions.
4871 /// \param mv instruction visitor
4872 /// \return non-zero value returned by mv.visit_mop() or zero
4873 int hexapi for_all_insns(minsn_visitor_t &mv);
4874
4875 /// Visit all top level instructions.
4876 /// \param mv instruction visitor
4877 /// \return non-zero value returned by mv.visit_mop() or zero
4878 int hexapi for_all_topinsns(minsn_visitor_t &mv);
4879
4880 /// Find an operand in the microcode.
4881 /// This function tries to find the operand that matches LIST.
4882 /// Any operand that overlaps with LIST is considered as a match.
4883 /// \param[out] ctx context information for the result
4884 /// \param ea desired address of the operand
4885 /// \param is_dest search for destination operand? this argument may be
4886 /// ignored if the exact match could not be found
4887 /// \param list list of locations the correspond to the operand
4888 /// \return pointer to the operand or nullptr.
4889 mop_t *hexapi find_mop(op_parent_info_t *ctx, ea_t ea, bool is_dest, const mlist_t &list);
4890
4891 /// Create a call of a helper function.
4892 /// \param ea The desired address of the instruction
4893 /// \param helper The helper name
4894 /// \param rettype The return type (nullptr or empty type means 'void')
4895 /// \param callargs The helper arguments (nullptr-no arguments)
4896 /// \param out The operand where the call result should be stored.
4897 /// If this argument is not nullptr, "mov helper_call(), out"
4898 /// will be generated. Otherwise "call helper()" will be
4899 /// generated. Note: the size of this operand must be equal
4900 /// to the RETTYPE size
4901 /// \return pointer to the created instruction or nullptr if error
4902 minsn_t *hexapi create_helper_call(
4903 ea_t ea,
4904 const char *helper,
4905 const tinfo_t *rettype=nullptr,
4906 const mcallargs_t *callargs=nullptr,
4907 const mop_t *out=nullptr);
4908
4909 /// Get input argument of the decompiled function.
4910 /// \param n argument number (0..nargs-1)
4911 lvar_t &hexapi arg(int n);
4912 const lvar_t &arg(int n) const { return CONST_CAST(mba_t*)(this)->arg(n); }
4913
4914 /// Allocate a fictional address.
4915 /// This function can be used to allocate a new unique address for a new
4916 /// instruction, if re-using any existing address leads to conflicts.
4917 /// For example, if the last instruction of the function modifies R0
4918 /// and falls through to the next function, it will be a tail call:
4919 /// LDM R0!, {R4,R7}
4920 /// end of the function
4921 /// start of another function
4922 /// In this case R0 generates two different lvars at the same address:
4923 /// - one modified by LDM
4924 /// - another that represents the return value from the tail call
4925 /// Another example: a third-party plugin makes a copy of an instruction.
4926 /// This may lead to the generation of two variables at the same address.
4927 /// Example 3: fictional addresses can be used for new instructions created
4928 /// while modifying the microcode.
4929 /// This function can be used to allocate a new unique address for a new
4930 /// instruction or a variable.
4931 /// The fictional address is selected from an unallocated address range.
4932 /// \param real_ea real instruction address (BADADDR is ok too)
4933 /// \return a unique fictional address
4934 ea_t hexapi alloc_fict_ea(ea_t real_ea);
4935
4936 /// Resolve a fictional address.
4937 /// This function provides a reverse of the mapping made by alloc_fict_ea().
4938 /// \param fict_ea fictional definition address
4939 /// \return the real instruction address
4940 ea_t hexapi map_fict_ea(ea_t fict_ea) const;
4941
4942 /// Get information about various memory regions.
4943 /// We map the stack frame to the global memory, to some unused range.
4944 const ivl_t &get_std_region(memreg_index_t idx) const;
4945 const ivl_t &get_lvars_region(void) const;
4946 const ivl_t &get_shadow_region(void) const;
4947 const ivl_t &get_args_region(void) const;
4948 ivl_t get_stack_region(void) const; // get entire stack region
4949
4950 /// Serialize mbl array into a sequence of bytes.
4951 void hexapi serialize(bytevec_t &vout) const;
4952
4953 /// Deserialize a byte sequence into mbl array.
4954 /// \param bytes pointer to the beginning of the byte sequence.
4955 /// \param nbytes number of bytes in the byte sequence.
4956 /// \return new mbl array
4957 WARN_UNUSED_RESULT static mba_t *hexapi deserialize(const uchar *bytes, size_t nbytes);
4958
4959 /// Create and save microcode snapshot
4960 void hexapi save_snapshot(const char *description);
4961
4962 /// Allocate a kernel register.
4963 /// \param size size of the register in bytes
4964 /// \param check_size if true, only the sizes that correspond to a size of
4965 /// a basic type will be accepted.
4966 /// \return allocated register. mr_none means failure.
4967 mreg_t hexapi alloc_kreg(size_t size, bool check_size=true);
4968
4969 /// Free a kernel register.
4970 /// If wrong arguments are passed, this function will generate an internal error.
4971 /// \param reg a previously allocated kernel register
4972 /// \param size size of the register in bytes
4973 void hexapi free_kreg(mreg_t reg, size_t size);
4974};
4975using mbl_array_t = mba_t;
4976//-------------------------------------------------------------------------
4977/// Convenience class to release graph chains automatically.
4978/// Use this class instead of using graph_chains_t directly.
4980{
4981 graph_chains_t *gc;
4982 chain_keeper_t &operator=(const chain_keeper_t &); // not defined
4983public:
4984 chain_keeper_t(graph_chains_t *_gc) : gc(_gc) { QASSERT(50446, gc != nullptr); gc->acquire(); }
4985 ~chain_keeper_t(void)
4986 {
4987 gc->release();
4988 }
4989 block_chains_t &operator[](size_t idx) { return (*gc)[idx]; }
4990 block_chains_t &front(void) { return gc->front(); }
4991 block_chains_t &back(void) { return gc->back(); }
4992 operator graph_chains_t &(void) { return *gc; }
4993 int for_all_chains(chain_visitor_t &cv, int gca) { return gc->for_all_chains(cv, gca); }
4994 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
4995};
4996
4997//-------------------------------------------------------------------------
4998/// Kind of use-def and def-use chains
5000{
5001 GC_REGS_AND_STKVARS, ///< registers and stkvars (restricted memory only)
5002 GC_ASR, ///< all the above and assertions
5003 GC_XDSU, ///< only registers calculated with FULL_XDSU
5004 GC_END, ///< number of chain types
5005 GC_DIRTY_ALL = (1 << (2*GC_END))-1, ///< bitmask to represent all chains
5006};
5007
5008//-------------------------------------------------------------------------
5009/// Control flow graph of microcode.
5011{
5012 mba_t *mba; ///< pointer to the mbl array
5013 int dirty; ///< what kinds of use-def chains are dirty?
5014 int chain_stamp; ///< we increment this counter each time chains are recalculated
5015 graph_chains_t gcs[2*GC_END]; ///< cached use-def chains
5016
5017 /// Is LIST accessed between two instructions?
5018 /// This function can analyze all path between the specified instructions
5019 /// and find if the specified list is used in any of them. The instructions
5020 /// may be located in different basic blocks. This function does not use
5021 /// use-def chains but use the graph for analysis. It may be slow in some
5022 /// cases but its advantage is that is does not require building the use-def
5023 /// chains.
5024 /// \param list list to verify
5025 /// \param b1 starting block
5026 /// \param b2 ending block. may be -1, it means all possible paths from b1
5027 /// \param m1 starting instruction (in b1)
5028 /// \param m2 ending instruction (in b2). excluded. may be nullptr.
5029 /// \param access_type read or write access?
5030 /// \param maymust may access or must access?
5031 /// \return true if found an access to the list
5032 bool hexapi is_accessed_globally(
5033 const mlist_t &list, // list to verify
5034 int b1, // starting block
5035 int b2, // ending block
5036 const minsn_t *m1, // starting instruction (in b1)
5037 const minsn_t *m2, // ending instruction (in b2)
5038 access_type_t access_type,
5039 maymust_t maymust) const;
5040 int get_ud_gc_idx(gctype_t gctype) const { return (gctype << 1); }
5041 int get_du_gc_idx(gctype_t gctype) const { return (gctype << 1)+1; }
5042 int get_ud_dirty_bit(gctype_t gctype) { return 1 << get_ud_gc_idx(gctype); }
5043 int get_du_dirty_bit(gctype_t gctype) { return 1 << get_du_gc_idx(gctype); }
5044
5045public:
5046 /// Is the use-def chain of the specified kind dirty?
5048 {
5049 int bit = get_ud_dirty_bit(gctype);
5050 return (dirty & bit) != 0;
5051 }
5052
5053 /// Is the def-use chain of the specified kind dirty?
5055 {
5056 int bit = get_du_dirty_bit(gctype);
5057 return (dirty & bit) != 0;
5058 }
5059 int get_chain_stamp(void) const { return chain_stamp; }
5060
5061 /// Get use-def chains.
5062 graph_chains_t *hexapi get_ud(gctype_t gctype);
5063
5064 /// Get def-use chains.
5065 graph_chains_t *hexapi get_du(gctype_t gctype);
5066
5067 /// Is LIST redefined in the graph?
5068 bool is_redefined_globally(const mlist_t &list, int b1, int b2, const minsn_t *m1, const minsn_t *m2, maymust_t maymust=MAY_ACCESS) const
5069 { return is_accessed_globally(list, b1, b2, m1, m2, WRITE_ACCESS, maymust); }
5070
5071 /// Is LIST used in the graph?
5072 bool is_used_globally(const mlist_t &list, int b1, int b2, const minsn_t *m1, const minsn_t *m2, maymust_t maymust=MAY_ACCESS) const
5073 { return is_accessed_globally(list, b1, b2, m1, m2, READ_ACCESS, maymust); }
5074
5075 mblock_t *get_mblock(int n) const { return mba->get_mblock(n); }
5076};
5077
5078//-------------------------------------------------------------------------
5079// Helper for codegen_t. It takes into account delay slots
5081{
5082 const mba_t *mba; // to check range
5083 ea_t ea = BADADDR; // next insn to decode
5084 ea_t end = BADADDR; // end of the block
5085 ea_t dslot = BADADDR; // address of the insn in the delay slot
5086 insn_t dslot_insn; // instruction in the delay slot
5087 ea_t severed_branch = BADADDR; // address of the severed branch insn
5088 // (when this branch insn ends the previous block)
5089 bool is_likely_dslot = false; // execute delay slot only when jumping
5090
5091 cdg_insn_iterator_t(const mba_t *mba_) : mba(mba_) {}
5092 cdg_insn_iterator_t(const cdg_insn_iterator_t &r) = default;
5093 cdg_insn_iterator_t &operator=(const cdg_insn_iterator_t &r) = default;
5094
5095 bool ok() const { return ea < end; }
5096 bool has_dslot() const { return dslot != BADADDR; }
5097 bool dslot_with_xrefs() const { return dslot >= end; }
5098 // the current insn is the severed delayed insn (when this starts a block)
5099 bool is_severed_dslot() const { return severed_branch != BADADDR; }
5100 void start(const range_t &rng)
5101 {
5102 ea = rng.start_ea;
5103 end = rng.end_ea;
5104 }
5105 merror_t hexapi next(insn_t *ins);
5106};
5107
5108//-------------------------------------------------------------------------
5109/// Helper class to generate the initial microcode
5111{
5112public:
5113 mba_t *mba; // ptr to mbl array
5114 mblock_t *mb = nullptr; // current basic block
5115 insn_t insn; // instruction to generate microcode for
5116 char ignore_micro = IM_NONE; // value of get_ignore_micro() for the insn
5117 cdg_insn_iterator_t ii; // instruction iterator
5118 size_t reserved;
5119
5120 codegen_t() = delete;
5121 virtual ~codegen_t(void)
5122 {
5123 }
5124
5125 /// Analyze prolog/epilog of the function to decompile.
5126 /// If prolog is found, allocate and fill 'mba->pi' structure.
5127 /// \param fc flow chart
5128 /// \param reachable bitmap of reachable blocks
5129 /// \return error code
5130 virtual merror_t idaapi analyze_prolog(
5131 const class qflow_chart_t &fc,
5132 const class bitset_t &reachable) = 0;
5133
5134 /// Generate microcode for one instruction.
5135 /// The instruction is in INSN
5136 /// \return MERR_OK - all ok
5137 /// MERR_BLOCK - all ok, need to switch to new block
5138 /// MERR_BADBLK - delete current block and continue
5139 /// other error codes are fatal
5140 virtual merror_t idaapi gen_micro() = 0;
5141
5142 /// Generate microcode to load one operand.
5143 /// \param opnum number of INSN operand
5144 /// \param flags reserved for future use
5145 /// \return register containing the operand.
5146 virtual mreg_t idaapi load_operand(int opnum, int flags=0) = 0;
5147
5148 /// This method is called when the microcode generation is done
5149 virtual void idaapi microgen_completed() {}
5150
5151 /// Setup internal data to handle new instruction.
5152 /// This method should be called before calling gen_micro().
5153 /// Usually gen_micro() is called by the decompiler. You have to call this
5154 /// function explicitly only if you yourself call gen_micro().
5155 /// The instruction is in INSN
5156 /// \return MERR_OK - all ok
5157 /// other error codes are fatal
5158 virtual merror_t idaapi prepare_gen_micro() { return MERR_OK; }
5159
5160 /// Generate microcode to calculate the address of a memory operand.
5161 /// \param n - number of INSN operand
5162 /// \param flags - reserved for future use
5163 /// \return register containing the operand address.
5164 /// mr_none - failed (not a memory operand)
5165 virtual mreg_t idaapi load_effective_address(int n, int flags=0) = 0;
5166
5167 /// Generate microcode to store an operand.
5168 /// In case of success an arbitrary number of instructions can be
5169 /// generated (and even no instruction if the source and target are the same)
5170 /// \param n - number of target INSN operand
5171 /// \param mop - operand to be stored
5172 /// \param flags - reserved for future use
5173 /// \param outins - (OUT) the last generated instruction
5174 // (nullptr if no instruction was generated)
5175 /// \return success
5176 virtual bool idaapi store_operand(int n, const mop_t &mop, int flags=0, minsn_t **outins=nullptr);
5177
5178 /// Emit one microinstruction.
5179 /// The L, R, D arguments usually mean the register number. However, they depend
5180 /// on CODE. For example:
5181 /// - for m_goto and m_jcnd L is the target address
5182 /// - for m_ldc L is the constant value to load
5183 /// \param code instruction opcode
5184 /// \param width operand size in bytes
5185 /// \param l left operand
5186 /// \param r right operand
5187 /// \param d destination operand
5188 /// \param offsize for ldx/stx, the size of the offset operand
5189 /// for ldc, operand number of the constant value
5190 /// -1, set the FP instruction (e.g. for m_mov)
5191 /// \return created microinstruction. can be nullptr if the instruction got
5192 /// immediately optimized away.
5193 minsn_t *hexapi emit(mcode_t code, int width, uval_t l, uval_t r, uval_t d, int offsize);
5194
5195 /// Emit one microinstruction.
5196 /// This variant takes a data type not a size.
5198 mcode_t code,
5199 op_dtype_t dtype,
5200 uval_t l,
5201 uval_t r,
5202 uval_t d,
5203 int offsize)
5204 {
5205 return emit(code, get_dtype_size(dtype), l, r, d, offsize);
5206 }
5207
5208 /// Emit one microinstruction.
5209 /// This variant accepts pointers to operands. It is more difficult to use
5210 /// but permits to create virtually any instruction. Operands may be nullptr
5211 /// when it makes sense.
5212 minsn_t *hexapi emit(mcode_t code, const mop_t *l, const mop_t *r, const mop_t *d);
5213
5214};
5215
5216//-------------------------------------------------------------------------
5218{
5219 t = mop_d;
5220 d = ins;
5221}
5222
5223inline bool mop_t::has_side_effects(bool include_ldx_and_divs) const
5224{
5225 return is_insn() && d->has_side_effects(include_ldx_and_divs);
5226}
5227
5228inline bool mop_t::is_kreg(void) const
5229{
5230 return t == mop_r && ::is_kreg(r);
5231}
5232
5233inline minsn_t *mop_t::get_insn(mcode_t code)
5234{
5235 return is_insn(code) ? d : nullptr;
5236}
5237inline const minsn_t *mop_t::get_insn(mcode_t code) const
5238{
5239 return is_insn(code) ? d : nullptr;
5240}
5241
5242inline bool mop_t::is_insn(mcode_t code) const
5243{
5244 return is_insn() && d->opcode == code;
5245}
5246
5247inline bool mop_t::is_glbaddr() const
5248{
5249 return t == mop_a && a->t == mop_v;
5250}
5251
5252inline bool mop_t::is_glbaddr(ea_t ea) const
5253{
5254 return is_glbaddr() && a->g == ea;
5255}
5256
5257inline bool mop_t::is_stkaddr() const
5258{
5259 return t == mop_a && a->t == mop_S;
5260}
5261
5262inline vivl_t::vivl_t(const chain_t &ch)
5263 : voff_t(ch.key().type, ch.is_reg() ? ch.get_reg() : ch.get_stkoff()),
5264 size(ch.width)
5265{
5266}
5267
5268// The following memory regions exist
5269// start length
5270// ------------------------ ---------
5271// lvars spbase stacksize
5272// retaddr spbase+stacksize retsize
5273// shadow spbase+stacksize+retsize shadow_args
5274// args inargoff MAX_FUNC_ARGS*sp_width-shadow_args
5275// globals data_segment sizeof_data_segment
5276// heap everything else?
5277
5279{
5280 return std_ivls[idx].ivl;
5281}
5282
5283inline const ivl_t &mba_t::get_lvars_region(void) const
5284{
5286}
5287
5288inline const ivl_t &mba_t::get_shadow_region(void) const
5289{
5291}
5292
5293inline const ivl_t &mba_t::get_args_region(void) const
5294{
5295 return get_std_region(MMIDX_ARGS);
5296}
5297
5298inline ivl_t mba_t::get_stack_region(void) const
5299{
5300 return ivl_t(std_ivls[MMIDX_LVARS].ivl.off, fullsize);
5301}
5302
5303//-------------------------------------------------------------------------
5304/// Get decompiler version.
5305/// The returned string is of the form <major>.<minor>.<revision>.<build-date>
5306/// \return pointer to version string. For example: "2.0.0.140605"
5307
5308const char *hexapi get_hexrays_version(void);
5309
5310
5311/// Check out a floating decompiler license.
5312/// This function will display a dialog box if the license is not available.
5313/// For non-floating licenses this function is effectively no-op.
5314/// It is not necessary to call this function before decompiling.
5315/// If the license was not checked out, the decompiler will automatically do it.
5316/// This function can be used to check out a license in advance and ensure
5317/// that a license is available.
5318/// \param silent silently fail if the license cannot be checked out.
5319/// \return false if failed
5320
5321bool hexapi checkout_hexrays_license(bool silent);
5322
5323/// \defgroup OPF_ open_pseudocode flags
5324/// Used in open_pseudocode
5325//@{
5326#define OPF_REUSE 0x00 ///< reuse existing window
5327#define OPF_NEW_WINDOW 0x01 ///< open new window
5328#define OPF_REUSE_ACTIVE 0x02 ///< reuse existing window, only if the
5329 ///< currently active widget is a pseudocode view
5330#define OPF_NO_WAIT 0x08 ///< do not display waitbox if decompilation happens
5331//@}
5332
5333#define OPF_WINDOW_MGMT_MASK 0x07
5334
5335
5336/// Open pseudocode window.
5337/// The specified function is decompiled and the pseudocode window is opened.
5338/// \param ea function to decompile
5339/// \param flags: a combination of OPF_ flags
5340/// \return false if failed
5341
5342vdui_t *hexapi open_pseudocode(ea_t ea, int flags);
5343
5344
5345/// Close pseudocode window.
5346/// \param f pointer to window
5347/// \return false if failed
5348
5350
5351
5352/// Get the vdui_t instance associated to the TWidget
5353/// \param f pointer to window
5354/// \return a vdui_t *, or nullptr
5355
5357
5358
5359/// \defgroup VDRUN_ Batch decompilation bits
5360//@{
5361#define VDRUN_NEWFILE 0x00000000 ///< Create a new file or overwrite existing file
5362#define VDRUN_APPEND 0x00000001 ///< Create a new file or append to existing file
5363#define VDRUN_ONLYNEW 0x00000002 ///< Fail if output file already exists
5364#define VDRUN_SILENT 0x00000004 ///< Silent decompilation
5365#define VDRUN_SENDIDB 0x00000008 ///< Send problematic databases to hex-rays.com
5366#define VDRUN_MAYSTOP 0x00000010 ///< The user can cancel decompilation
5367#define VDRUN_CMDLINE 0x00000020 ///< Called from ida's command line
5368#define VDRUN_STATS 0x00000040 ///< Print statistics into vd_stats.txt
5369#define VDRUN_LUMINA 0x00000080 ///< Use lumina server
5370//@}
5371
5372/// Batch decompilation.
5373/// Decompile all or the specified functions
5374/// \return true if no internal error occurred and the user has not cancelled decompilation
5375/// \param outfile name of the output file
5376/// \param funcaddrs list of functions to decompile.
5377/// If nullptr or empty, then decompile all nonlib functions
5378/// \param flags \ref VDRUN_
5379
5380bool hexapi decompile_many(const char *outfile, const eavec_t *funcaddrs, int flags);
5381
5382
5383/// Exception object: decompiler failure information
5385{
5386 merror_t code; ///< \ref MERR_
5387 ea_t errea; ///< associated address
5388 qstring str; ///< string information
5389 hexrays_failure_t(void) : code(MERR_OK), errea(BADADDR) {}
5390 hexrays_failure_t(merror_t c, ea_t ea, const char *buf=nullptr) : code(c), errea(ea), str(buf) {}
5391 hexrays_failure_t(merror_t c, ea_t ea, const qstring &buf) : code(c), errea(ea), str(buf) {}
5392 qstring hexapi desc(void) const;
5393 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
5394};
5395
5396/// Exception object: decompiler exception
5397struct vd_failure_t : public std::exception
5398{
5400 vd_failure_t(void) {}
5401 vd_failure_t(merror_t code, ea_t ea, const char *buf=nullptr) : hf(code, ea, buf) {}
5402 vd_failure_t(merror_t code, ea_t ea, const qstring &buf) : hf(code, ea, buf) {}
5403 vd_failure_t(const hexrays_failure_t &_hf) : hf(_hf) {}
5404 qstring desc(void) const { return hf.desc(); }
5405#ifdef __GNUC__
5406 ~vd_failure_t(void) throw() {}
5407#endif
5408 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
5409};
5410
5411/// Exception object: decompiler internal error
5413{
5414 vd_interr_t(ea_t ea, const qstring &buf) : vd_failure_t(MERR_INTERR, ea, buf) {}
5415 vd_interr_t(ea_t ea, const char *buf) : vd_failure_t(MERR_INTERR, ea, buf) {}
5416};
5417
5418/// Send the database to Hex-Rays.
5419/// This function sends the current database to the Hex-Rays server.
5420/// The database is sent in the compressed form over an encrypted (SSL) connection.
5421/// \param err failure description object. Empty hexrays_failure_t object can
5422/// be used if error information is not available.
5423/// \param silent if false, a dialog box will be displayed before sending the database.
5424
5425void hexapi send_database(const hexrays_failure_t &err, bool silent);
5426
5427/// Result of get_current_operand()
5429{
5430 qstring name; ///< register or stkvar name
5431 union
5432 {
5433 sval_t stkoff; ///< if stkvar, stack offset
5434 int regnum; ///< if register, the register id
5435 };
5436 int size; ///< operand size
5437 int flags;
5438#define GCO_STK 0x0000 ///< a stack variable
5439#define GCO_REG 0x0001 ///< is register? otherwise a stack variable
5440#define GCO_USE 0x0002 ///< is source operand?
5441#define GCO_DEF 0x0004 ///< is destination operand?
5442 bool is_reg(void) const { return (flags & GCO_REG) != 0; }
5443 bool is_use(void) const { return (flags & GCO_USE) != 0; }
5444 bool is_def(void) const { return (flags & GCO_DEF) != 0; }
5445
5446 /// Append operand info to LIST.
5447 /// This function converts IDA register number or stack offset to
5448 /// a decompiler list.
5449 /// \param list list to append to
5450 /// \param mba microcode object
5451 bool hexapi append_to_list(mlist_t *list, const mba_t *mba) const;
5452
5453 /// Convert operand info to VIVL.
5454 /// The returned VIVL can be used, for example, in a call of
5455 /// get_valranges().
5457 {
5458 vivl_t ret;
5459 if ( is_reg() )
5460 ret.set_reg(regnum, size);
5461 else
5462 ret.set_stkoff(stkoff, size);
5463 return ret;
5464 }
5465};
5466
5467/// Get the instruction operand under the cursor.
5468/// This function determines the operand that is under the cursor in the active
5469/// disassembly listing. If the operand refers to a register or stack variable,
5470/// it returns true.
5471/// \param out[out] output buffer
5473
5474void hexapi remitem(const citem_t *e);
5475//-------------------------------------------------------------------------
5476/// Ctree item code. At the beginning of this list there are expression
5477/// codes (cot_...), followed by statement codes (cit_...).
5479{
5480 cot_empty = 0,
5481 cot_comma = 1, ///< x, y
5482 cot_asg = 2, ///< x = y
5483 cot_asgbor = 3, ///< x |= y
5484 cot_asgxor = 4, ///< x ^= y
5485 cot_asgband = 5, ///< x &= y
5486 cot_asgadd = 6, ///< x += y
5487 cot_asgsub = 7, ///< x -= y
5488 cot_asgmul = 8, ///< x *= y
5489 cot_asgsshr = 9, ///< x >>= y signed
5490 cot_asgushr = 10, ///< x >>= y unsigned
5491 cot_asgshl = 11, ///< x <<= y
5492 cot_asgsdiv = 12, ///< x /= y signed
5493 cot_asgudiv = 13, ///< x /= y unsigned
5494 cot_asgsmod = 14, ///< x %= y signed
5495 cot_asgumod = 15, ///< x %= y unsigned
5496 cot_tern = 16, ///< x ? y : z
5497 cot_lor = 17, ///< x || y
5498 cot_land = 18, ///< x && y
5499 cot_bor = 19, ///< x | y
5500 cot_xor = 20, ///< x ^ y
5501 cot_band = 21, ///< x & y
5502 cot_eq = 22, ///< x == y int or fpu (see EXFL_FPOP)
5503 cot_ne = 23, ///< x != y int or fpu (see EXFL_FPOP)
5504 cot_sge = 24, ///< x >= y signed or fpu (see EXFL_FPOP)
5505 cot_uge = 25, ///< x >= y unsigned
5506 cot_sle = 26, ///< x <= y signed or fpu (see EXFL_FPOP)
5507 cot_ule = 27, ///< x <= y unsigned
5508 cot_sgt = 28, ///< x > y signed or fpu (see EXFL_FPOP)
5509 cot_ugt = 29, ///< x > y unsigned
5510 cot_slt = 30, ///< x < y signed or fpu (see EXFL_FPOP)
5511 cot_ult = 31, ///< x < y unsigned
5512 cot_sshr = 32, ///< x >> y signed
5513 cot_ushr = 33, ///< x >> y unsigned
5514 cot_shl = 34, ///< x << y
5515 cot_add = 35, ///< x + y
5516 cot_sub = 36, ///< x - y
5517 cot_mul = 37, ///< x * y
5518 cot_sdiv = 38, ///< x / y signed
5519 cot_udiv = 39, ///< x / y unsigned
5520 cot_smod = 40, ///< x % y signed
5521 cot_umod = 41, ///< x % y unsigned
5522 cot_fadd = 42, ///< x + y fp
5523 cot_fsub = 43, ///< x - y fp
5524 cot_fmul = 44, ///< x * y fp
5525 cot_fdiv = 45, ///< x / y fp
5526 cot_fneg = 46, ///< -x fp
5527 cot_neg = 47, ///< -x
5528 cot_cast = 48, ///< (type)x
5529 cot_lnot = 49, ///< !x
5530 cot_bnot = 50, ///< ~x
5531 cot_ptr = 51, ///< *x, access size in 'ptrsize'
5532 cot_ref = 52, ///< &x
5533 cot_postinc = 53, ///< x++
5534 cot_postdec = 54, ///< x--
5535 cot_preinc = 55, ///< ++x
5536 cot_predec = 56, ///< --x
5537 cot_call = 57, ///< x(...)
5538 cot_idx = 58, ///< x[y]
5539 cot_memref = 59, ///< x.m
5540 cot_memptr = 60, ///< x->m, access size in 'ptrsize'
5541 cot_num = 61, ///< n
5542 cot_fnum = 62, ///< fpc
5543 cot_str = 63, ///< string constant (user representation)
5544 cot_obj = 64, ///< obj_ea
5545 cot_var = 65, ///< v
5546 cot_insn = 66, ///< instruction in expression, internal representation only
5547 cot_sizeof = 67, ///< sizeof(x)
5548 cot_helper = 68, ///< arbitrary name
5549 cot_type = 69, ///< arbitrary type
5550 cot_last = cot_type,
5551 cit_empty = 70, ///< instruction types start here
5552 cit_block = 71, ///< block-statement: { ... }
5553 cit_expr = 72, ///< expression-statement: expr;
5554 cit_if = 73, ///< if-statement
5555 cit_for = 74, ///< for-statement
5556 cit_while = 75, ///< while-statement
5557 cit_do = 76, ///< do-statement
5558 cit_switch = 77, ///< switch-statement
5559 cit_break = 78, ///< break-statement
5560 cit_continue = 79, ///< continue-statement
5561 cit_return = 80, ///< return-statement
5562 cit_goto = 81, ///< goto-statement
5563 cit_asm = 82, ///< asm-statement
5564 cit_end
5565};
5566
5567/// Negate a comparison operator. For example, \ref cot_sge becomes \ref cot_slt
5569/// Swap a comparison operator. For example, \ref cot_sge becomes \ref cot_sle
5571/// Get operator sign. Meaningful for sign-dependent operators, like \ref cot_sdiv
5572type_sign_t hexapi get_op_signness(ctype_t op);
5573/// Convert plain operator into assignment operator. For example, \ref cot_add returns \ref cot_asgadd
5575/// Convert assignment operator into plain operator. For example, \ref cot_asgadd returns \ref cot_add
5576/// \return cot_empty is the input operator is not an assignment operator.
5578/// Does operator use the 'x' field of cexpr_t?
5579inline bool op_uses_x(ctype_t op) { return (op >= cot_comma && op <= cot_memptr) || op == cot_sizeof; }
5580/// Does operator use the 'y' field of cexpr_t?
5581inline bool op_uses_y(ctype_t op) { return (op >= cot_comma && op <= cot_fdiv) || op == cot_idx; }
5582/// Does operator use the 'z' field of cexpr_t?
5583inline bool op_uses_z(ctype_t op) { return op == cot_tern; }
5584/// Is binary operator?
5585inline bool is_binary(ctype_t op) { return op_uses_y(op) && op != cot_tern; } // x,y
5586/// Is unary operator?
5587inline bool is_unary(ctype_t op) { return op >= cot_fneg && op <= cot_predec; }
5588/// Is comparison operator?
5589inline bool is_relational(ctype_t op) { return op >= cot_eq && op <= cot_ult; }
5590/// Is assignment operator?
5591inline bool is_assignment(ctype_t op) { return op >= cot_asg && op <= cot_asgumod; }
5592// Can operate on UDTs?
5593inline bool accepts_udts(ctype_t op) { return op == cot_asg || op == cot_comma || op > cot_last; }
5594/// Is pre/post increment/decrement operator?
5595inline bool is_prepost(ctype_t op) { return op >= cot_postinc && op <= cot_predec; }
5596/// Is commutative operator?
5598{
5599 return op == cot_bor
5600 || op == cot_xor
5601 || op == cot_band
5602 || op == cot_add
5603 || op == cot_mul
5604 || op == cot_fadd
5605 || op == cot_fmul
5606 || op == cot_ne
5607 || op == cot_eq;
5608}
5609/// Is additive operator?
5610inline bool is_additive(ctype_t op)
5611{
5612 return op == cot_add
5613 || op == cot_sub
5614 || op == cot_fadd
5615 || op == cot_fsub;
5616}
5617/// Is multiplicative operator?
5619{
5620 return op == cot_mul
5621 || op == cot_sdiv
5622 || op == cot_udiv
5623 || op == cot_fmul
5624 || op == cot_fdiv;
5625}
5626
5627/// Is bit related operator?
5628inline bool is_bitop(ctype_t op)
5629{
5630 return op == cot_bor
5631 || op == cot_xor
5632 || op == cot_band
5633 || op == cot_bnot;
5634}
5635
5636/// Is logical operator?
5637inline bool is_logical(ctype_t op)
5638{
5639 return op == cot_lor
5640 || op == cot_land
5641 || op == cot_lnot;
5642}
5643
5644/// Is loop statement code?
5645inline bool is_loop(ctype_t op)
5646{
5647 return op == cit_for
5648 || op == cit_while
5649 || op == cit_do;
5650}
5651/// Does a break statement influence the specified statement code?
5653{
5654 return is_loop(op) || op == cit_switch;
5655}
5656
5657/// Is Lvalue operator?
5658inline bool is_lvalue(ctype_t op)
5659{
5660 return op == cot_ptr // *x
5661 || op == cot_idx // x[y]
5662 || op == cot_memref // x.m
5663 || op == cot_memptr // x->m
5664 || op == cot_obj // v
5665 || op == cot_var; // l
5666}
5667
5668/// Is the operator allowed on small structure or union?
5670{
5671 return op == cit_return
5672 || op == cot_asg
5673 || op == cot_eq
5674 || op == cot_ne
5675 || op == cot_comma
5676 || op == cot_tern
5677 || (op > cot_last && op < cit_end); // any insn
5678}
5679
5680/// An immediate number
5682{
5683 uint64 _value; ///< its value
5684 number_format_t nf; ///< how to represent it
5685 cnumber_t(int _opnum=0) : _value(0), nf(_opnum) {}
5686
5687 /// Get text representation
5688 /// \param vout output buffer
5689 /// \param type number type
5690 /// \param parent parent expression
5691 /// \param nice_stroff out: printed as stroff expression
5692 void hexapi print(
5693 qstring *vout,
5694 const tinfo_t &type,
5695 const citem_t *parent=nullptr,
5696 bool *nice_stroff=nullptr) const;
5697
5698 /// Get value.
5699 /// This function will properly extend the number sign to 64bits
5700 /// depending on the type sign.
5701 uint64 hexapi value(const tinfo_t &type) const;
5702
5703 /// Assign new value
5704 /// \param v new value
5705 /// \param nbytes size of the new value in bytes
5706 /// \param sign sign of the value
5707 void hexapi assign(uint64 v, int nbytes, type_sign_t sign);
5708
5709 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
5710 DECLARE_COMPARISONS(cnumber_t);
5711};
5712
5713/// Reference to a local variable
5715{
5716 mba_t *mba; ///< pointer to the underlying micro array
5717 int idx; ///< index into lvars_t
5718 lvar_t &getv(void) const { return mba->vars[idx]; }
5719 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
5720 DECLARE_COMPARISONS(var_ref_t);
5721};
5722
5723/// Vector of parents
5724typedef qvector<citem_t *> ctree_items_t;
5725typedef ctree_items_t parents_t;
5726
5727/// A generic helper class that is used for ctree traversal.
5728/// When traversing the ctree, the currently visited ctree item and its children
5729/// can be freely modified without interrupting the traversal. However, if a
5730/// parent of the visited item is modified, the traversal must be immediately
5731/// stopped by returning a non-zero value.
5733{
5734 int cv_flags; ///< \ref CV_
5735/// \defgroup CV_ Ctree visitor property bits
5736/// Used in ctree_visitor_t::cv_flags
5737//@{
5738#define CV_FAST 0x0000 ///< do not maintain parent information
5739#define CV_PRUNE 0x0001 ///< this bit is set by visit...() to prune the walk
5740#define CV_PARENTS 0x0002 ///< maintain parent information
5741#define CV_POST 0x0004 ///< call the leave...() functions
5742#define CV_RESTART 0x0008 ///< restart enumeration at the top expr (apply_to_exprs)
5743#define CV_INSNS 0x0010 ///< visit only statements, prune all expressions
5744 ///< do not use before the final ctree maturity because
5745 ///< expressions may contain statements at intermediate
5746 ///< stages (see cot_insn). Otherwise you risk missing
5747 ///< statements embedded into expressions.
5748//@}
5749 /// Should the parent information by maintained?
5750 bool maintain_parents(void) const { return (cv_flags & CV_PARENTS) != 0; }
5751 /// Should the traversal skip the children of the current item?
5752 bool must_prune(void) const { return (cv_flags & CV_PRUNE) != 0; }
5753 /// Should the traversal restart?
5754 bool must_restart(void) const { return (cv_flags & CV_RESTART) != 0; }
5755 /// Should the leave...() functions be called?
5756 bool is_postorder(void) const { return (cv_flags & CV_POST) != 0; }
5757 /// Should all expressions be automatically pruned?
5758 bool only_insns(void) const { return (cv_flags & CV_INSNS) != 0; }
5759 /// Prune children.
5760 /// This function may be called by a visitor() to skip all children of the current item.
5761 void prune_now(void) { cv_flags |= CV_PRUNE; }
5762 /// Do not prune children. This is an internal function, no need to call it.
5763 void clr_prune(void) { cv_flags &= ~CV_PRUNE; }
5764 /// Restart the travesal. Meaningful only in apply_to_exprs()
5765 void set_restart(void) { cv_flags |= CV_RESTART; }
5766 /// Do not restart. This is an internal function, no need to call it.
5767 void clr_restart(void) { cv_flags &= ~CV_RESTART; }
5768
5769 parents_t parents; ///< Vector of parents of the current item
5770
5771 /// Constructor.
5772 /// This constructor can be used with CV_FAST, CV_PARENTS
5773 /// combined with CV_POST, CV_ONLYINS
5774 ctree_visitor_t(int _flags) : cv_flags(_flags) {}
5775
5776 virtual ~ctree_visitor_t() {}
5777 /// Traverse ctree.
5778 /// The traversal will start at the specified item and continue until
5779 /// of one the visit_...() functions return a non-zero value.
5780 /// \param item root of the ctree to traverse
5781 /// \param parent parent of the specified item. can be specified as nullptr.
5782 /// \return 0 or a non-zero value returned by a visit_...() function
5783 int hexapi apply_to(citem_t *item, citem_t *parent);
5784
5785 /// Traverse only expressions.
5786 /// The traversal will start at the specified item and continue until
5787 /// of one the visit_...() functions return a non-zero value.
5788 /// \param item root of the ctree to traverse
5789 /// \param parent parent of the specified item. can be specified as nullptr.
5790 /// \return 0 or a non-zero value returned by a visit_...() function
5791 int hexapi apply_to_exprs(citem_t *item, citem_t *parent);
5792
5793 /// Get parent of the current item as an expression
5794 cexpr_t *parent_expr(void) { return (cexpr_t *)parents.back(); }
5795 /// Get parent of the current item as a statement
5796 cinsn_t *parent_insn(void) { return (cinsn_t *)parents.back(); }
5797
5798 // the following functions are redefined by the derived class
5799 // in order to perform the desired actions during the traversal
5800
5801 /// Visit a statement.
5802 /// This is a visitor function which should be overridden by a derived
5803 /// class to do some useful work.
5804 /// This visitor performs pre-order traserval, i.e. an item is visited before
5805 /// its children.
5806 /// \return 0 to continue the traversal, nonzero to stop.
5807 virtual int idaapi visit_insn(cinsn_t *) { return 0; }
5808
5809 /// Visit an expression.
5810 /// This is a visitor function which should be overridden by a derived
5811 /// class to do some useful work.
5812 /// This visitor performs pre-order traserval, i.e. an item is visited before
5813 /// its children.
5814 /// \return 0 to continue the traversal, nonzero to stop.
5815 virtual int idaapi visit_expr(cexpr_t *) { return 0; }
5816
5817 /// Visit a statement after having visited its children.
5818 /// This is a visitor function which should be overridden by a derived
5819 /// class to do some useful work.
5820 /// This visitor performs post-order traserval, i.e. an item is visited after
5821 /// its children.
5822 /// \return 0 to continue the traversal, nonzero to stop.
5823 virtual int idaapi leave_insn(cinsn_t *) { return 0; }
5824
5825 /// Visit an expression after having visited its children.
5826 /// This is a visitor function which should be overridden by a derived
5827 /// class to do some useful work.
5828 /// This visitor performs post-order traserval, i.e. an item is visited after
5829 /// its children.
5830 /// \return 0 to continue the traversal, nonzero to stop.
5831 virtual int idaapi leave_expr(cexpr_t *) { return 0; }
5832
5833 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
5834};
5835
5836/// A helper ctree traversal class that maintains parent information
5838{
5839 ctree_parentee_t(bool post=false)
5840 : ctree_visitor_t((post ? CV_POST : 0)|CV_PARENTS) {}
5841
5842 /// Recalculate type of parent nodes.
5843 /// If a node type has been changed, the visitor must recalculate
5844 /// all parent types, otherwise the ctree becomes inconsistent.
5845 /// If during this recalculation a parent node is added/deleted,
5846 /// this function returns true. In this case the traversal must be
5847 /// stopped because the information about parent nodes is stale.
5848 /// \return false-ok to continue the traversal, true-must stop.
5849 bool hexapi recalc_parent_types(void);
5850
5851 /// Get pointer to the parent block of the currently visited item.
5852 /// This function should be called only when the parent is a block.
5853 cblock_t *get_block();
5854};
5855
5856/// Class to traverse the whole function.
5858{
5859 cfunc_t *func; ///< Pointer to current function
5860 cfunc_parentee_t(cfunc_t *f, bool post=false)
5861 : ctree_parentee_t(post), func(f) {}
5862
5863 /// Calculate rvalue type.
5864 /// This function tries to determine the type of the specified item
5865 /// based on its context. For example, if the current expression is the
5866 /// right side of an assignment operator, the type
5867 /// of its left side will be returned. This function can be used to determine the 'best'
5868 /// type of the specified expression.
5869 /// \param[in] e expression to determine the desired type
5870 /// \param[out] target 'best' type of the expression will be returned here
5871 /// \return false if failed
5872 bool hexapi calc_rvalue_type(tinfo_t *target, const cexpr_t *e);
5873};
5874
5875/// Ctree maturity level. The level will increase
5876/// as we switch from one phase of ctree generation to the next one
5878{
5879 CMAT_ZERO, ///< does not exist
5880 CMAT_BUILT, ///< just generated
5881 CMAT_TRANS1, ///< applied first wave of transformations
5882 CMAT_NICE, ///< nicefied expressions
5883 CMAT_TRANS2, ///< applied second wave of transformations
5884 CMAT_CPA, ///< corrected pointer arithmetic
5885 CMAT_TRANS3, ///< applied third wave of transformations
5886 CMAT_CASTED, ///< added necessary casts
5887 CMAT_FINAL, ///< ready-to-use
5888};
5889
5890//--------------------------------------------------------------------------
5891/// Comment item preciser.
5892/// Item preciser is used to assign comments to ctree items
5893/// A ctree item may have several comments attached to it. For example,
5894/// an if-statement may have the following comments: <pre>
5895/// if ( ... ) // cmt1
5896/// { // cmt2
5897/// } // cmt3
5898/// else // cmt4
5899/// { -- usually the else block has a separate ea
5900/// } </pre>
5901/// The first 4 comments will have the same ea. In order to denote the exact
5902/// line for the comment, we store the item_preciser along with ea.
5904{
5905 // inner comments (comments within an expression)
5906 ITP_EMPTY, ///< nothing
5907 ITP_ARG1, ///< , (64 entries are reserved for 64 call arguments)
5908 ITP_ARG64 = ITP_ARG1+63, // ,
5909 ITP_BRACE1, // (
5910 ITP_INNER_LAST = ITP_BRACE1,
5911 // outer comments
5912 ITP_ASM, ///< __asm-line
5913 ITP_ELSE, ///< else-line
5914 ITP_DO, ///< do-line
5915 ITP_SEMI, ///< semicolon
5919 ITP_COLON, ///< : (label)
5920 ITP_BLOCK1, ///< opening block comment. this comment is printed before the item
5921 ///< (other comments are indented and printed after the item)
5922 ITP_BLOCK2, ///< closing block comment.
5923 ITP_CASE = 0x40000000, ///< bit for switch cases
5924 ITP_SIGN = 0x20000000, ///< if this bit is set too, then we have a negative case value
5925 // this is a hack, we better introduce special indexes for case values
5926 // case value >= ITP_CASE will be processed incorrectly
5927};
5928/// Ctree location. Used to denote comment locations.
5930{
5931 ea_t ea;
5932 item_preciser_t itp;
5933 bool operator < (const treeloc_t &r) const
5934 {
5935 return ea < r.ea
5936 || (ea == r.ea && itp < r.itp);
5937 }
5938 bool operator == (const treeloc_t &r) const
5939 {
5940 return ea == r.ea && itp == r.itp;
5941 }
5942 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
5943};
5944
5945/// Comment retrieval type.
5946/// Ctree remembers what comments have already been retrieved.
5947/// This is done because our mechanism of item_precisers is still
5948/// not perfect and in theory some listing lines cannot be told
5949/// apart. To avoid comment duplication, we remember if a comment
5950/// has already been used or not.
5952{
5953 RETRIEVE_ONCE, ///< Retrieve comment if it has not been used yet
5954 RETRIEVE_ALWAYS, ///< Retrieve comment even if it has been used
5955};
5956
5957/// Ctree item comment.
5958/// For each comment we remember its body and the fact of its retrieval
5959struct citem_cmt_t : public qstring
5960{
5961 mutable bool used; ///< the comment has been retrieved?
5962 citem_cmt_t(void) : used(false) {}
5963 citem_cmt_t(const char *s) : qstring(s), used(false) {}
5964};
5965
5966// Comments are attached to tree locations:
5967typedef std::map<treeloc_t, citem_cmt_t> user_cmts_t;
5968
5969/// Generic ctree item locator. It can be used for instructions and some expression
5970/// types. However, we need more precise locators for other items (e.g. for numbers)
5972{
5973 ea_t ea; ///< citem address
5974 ctype_t op; ///< citem operation
5975 citem_locator_t(void) = delete;
5976public:
5977 citem_locator_t(ea_t _ea, ctype_t _op) : ea(_ea), op(_op) {}
5978 citem_locator_t(const citem_t *i);
5979 DECLARE_COMPARISONS(citem_locator_t);
5980 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
5981};
5982
5983// citem_t::iflags are attached to (ea,op) pairs
5984typedef std::map<citem_locator_t, int32> user_iflags_t;
5985
5986// union field selections
5987// they are represented as a vector of integers. each integer represents the
5988// number of union field (0 means the first union field, etc)
5989// the size of this vector is equal to the number of nested unions in the selection.
5990typedef std::map<ea_t, intvec_t> user_unions_t;
5991
5992//--------------------------------------------------------------------------
5994{
5995 int16 nbits; // total number of non-zero bits. we cannot guarantee that
5996 // they are zero. example: a random "int var" has nbits==32
5997 int16 sbits; // number of sign bits (they can be either 0 or 1, all of them)
5998 // if bits are known to be zeroes, they are not taken into account here
5999 // (in this case nbits should be reduced)
6000 // if bits are unknown and can be anything, they cannot be included
6001 // in sbits.
6002 // sbits==1 is a special case and should not be used
6003 bit_bound_t(int n=0, int s=0) : nbits(n), sbits(s) {}
6004};
6005
6006//--------------------------------------------------------------------------
6007/// Basic ctree item. This is an abstract class (but we don't use virtual
6008/// functions in ctree, so the compiler will not disallow you to create citem_t
6009/// instances). However, items of pure citem_t type must never be created.
6010/// Two classes, cexpr_t and cinsn_t are derived from it.
6012{
6013 ea_t ea = BADADDR; ///< address that corresponds to the item. may be BADADDR
6014 ctype_t op = cot_empty; ///< item type
6015 int label_num = -1; ///< label number. -1 means no label. items of the expression
6016 ///< types (cot_...) should not have labels at the final maturity
6017 ///< level, but at the intermediate levels any ctree item
6018 ///< may have a label. Labels must be unique. Usually
6019 ///< they correspond to the basic block numbers.
6020 mutable int index = -1; ///< an index in cfunc_t::treeitems.
6021 ///< meaningful only after print_func()
6022 citem_t(ctype_t o=cot_empty) : op(o) {}
6023 /// Swap two citem_t
6024 void swap(citem_t &r)
6025 {
6026 std::swap(ea, r.ea);
6027 std::swap(op, r.op);
6028 std::swap(label_num, r.label_num);
6029 }
6030 /// Is an expression?
6031 bool is_expr(void) const { return op <= cot_last; }
6032 /// Does the item contain an expression?
6033 bool hexapi contains_expr(const cexpr_t *e) const;
6034 /// Does the item contain a label?
6035 bool hexapi contains_label(void) const;
6036 /// Find parent of the specified item.
6037 /// \param sitem Item to find the parent of. The search will be performed
6038 /// among the children of the item pointed by \c this.
6039 /// \return nullptr if not found
6040 const citem_t *hexapi find_parent_of(const citem_t *sitem) const;
6041 citem_t *find_parent_of(const citem_t *item)
6042 { return CONST_CAST(citem_t*)((CONST_CAST(const citem_t*)(this))->find_parent_of(item)); }
6043 citem_t *hexapi find_closest_addr(ea_t _ea);
6044 void print1(qstring *vout, const cfunc_t *func) const;
6045 ~citem_t(void)
6046 {
6047 remitem(this);
6048 }
6049 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
6050};
6051DECLARE_TYPE_AS_MOVABLE(citem_t);
6052
6053/// Ctree item: expression.
6054/// Depending on the exact expression item type, various fields of this structure are used.
6055struct cexpr_t : public citem_t
6056{
6057 union
6058 {
6059 cnumber_t *n; ///< used for \ref cot_num
6060 fnumber_t *fpc; ///< used for \ref cot_fnum
6061 struct
6062 {
6063 union
6064 {
6065 var_ref_t v; ///< used for \ref cot_var
6066 ea_t obj_ea; ///< used for \ref cot_obj
6067 };
6068 int refwidth; ///< how many bytes are accessed? (-1: none)
6069 };
6070 struct
6071 {
6072 cexpr_t *x; ///< the first operand of the expression
6073 union
6074 {
6075 cexpr_t *y; ///< the second operand of the expression
6076 carglist_t *a;///< argument list (used for \ref cot_call)
6077 uint32 m; ///< member offset (used for \ref cot_memptr, \ref cot_memref)
6078 ///< for unions, the member number
6079 };
6080 union
6081 {
6082 cexpr_t *z; ///< the third operand of the expression
6083 int ptrsize; ///< memory access size (used for \ref cot_ptr, \ref cot_memptr)
6084 };
6085 };
6086 cinsn_t *insn; ///< an embedded statement, they are prohibited
6087 ///< at the final maturity stage (\ref CMAT_FINAL)
6088 char *helper; ///< helper name (used for \ref cot_helper)
6089 char *string; ///< utf8 string constant, user representation (used for \ref cot_str)
6090 };
6091 tinfo_t type; ///< expression type. must be carefully maintained
6092 uint32 exflags; ///< \ref EXFL_
6093/// \defgroup EXFL_ Expression attributes
6094/// Used in cexpr_t::exflags
6095//@{
6096#define EXFL_CPADONE 0x0001 ///< pointer arithmetic correction done
6097#define EXFL_LVALUE 0x0002 ///< expression is lvalue even if it doesn't look like it
6098#define EXFL_FPOP 0x0004 ///< floating point operation
6099#define EXFL_ALONE 0x0008 ///< standalone helper
6100#define EXFL_CSTR 0x0010 ///< string literal
6101#define EXFL_PARTIAL 0x0020 ///< type of the expression is considered partial
6102#define EXFL_UNDEF 0x0040 ///< expression uses undefined value
6103#define EXFL_JUMPOUT 0x0080 ///< jump out-of-function
6104#define EXFL_VFTABLE 0x0100 ///< is ptr to vftable (used for \ref cot_memptr, \ref cot_memref)
6105#define EXFL_ALL 0x01FF ///< all currently defined bits
6106//@}
6107 /// Pointer arithmetic correction done for this expression?
6108 bool cpadone(void) const { return (exflags & EXFL_CPADONE) != 0; }
6109 bool is_odd_lvalue(void) const { return (exflags & EXFL_LVALUE) != 0; }
6110 bool is_fpop(void) const { return (exflags & EXFL_FPOP) != 0; }
6111 bool is_cstr(void) const { return (exflags & EXFL_CSTR) != 0; }
6112 bool is_type_partial(void) const { return (exflags & EXFL_PARTIAL) != 0; }
6113 bool is_undef_val(void) const { return (exflags & EXFL_UNDEF) != 0; }
6114 bool is_jumpout(void) const { return (exflags & EXFL_JUMPOUT) != 0; }
6115 bool is_vftable(void) const { return (exflags & EXFL_VFTABLE) != 0; }
6116
6117
6118 void set_cpadone(void) { exflags |= EXFL_CPADONE; }
6119 void set_vftable(void) { exflags |= EXFL_VFTABLE; }
6120 void set_type_partial(bool val = true)
6121 {
6122 if ( val )
6123 exflags |= EXFL_PARTIAL;
6124 else
6125 exflags &= ~EXFL_PARTIAL;
6126 }
6127
6128 cexpr_t(void) : x(nullptr), y(nullptr), z(nullptr), exflags(0) {}
6129 cexpr_t(ctype_t cexpr_op, cexpr_t *_x) : citem_t(cexpr_op), x(_x), y(nullptr), z(nullptr), exflags(0) {}
6130 cexpr_t(ctype_t cexpr_op, cexpr_t *_x, cexpr_t *_y) : citem_t(cexpr_op), x(_x), y(_y), z(nullptr), exflags(0) {}
6131 cexpr_t(ctype_t cexpr_op, cexpr_t *_x, cexpr_t *_y, cexpr_t *_z) : citem_t(cexpr_op), x(_x), y(_y), z(_z), exflags(0) {}
6132 cexpr_t(mba_t *mba, const lvar_t &v);
6133 cexpr_t(const cexpr_t &r) : citem_t() { *this = r; }
6134 void swap(cexpr_t &r) { qswap(*this, r); }
6135 cexpr_t &operator=(const cexpr_t &r) { return assign(r); }
6136 cexpr_t &hexapi assign(const cexpr_t &r);
6137 DECLARE_COMPARISONS(cexpr_t);
6138 ~cexpr_t(void) { cleanup(); }
6139
6140 /// Replace the expression.
6141 /// The children of the expression are abandoned (not freed).
6142 /// The expression pointed by 'r' is moved to 'this' expression
6143 /// \param r the source expression. It is deleted after being copied
6144 void hexapi replace_by(cexpr_t *r);
6145
6146 /// Cleanup the expression.
6147 /// This function properly deletes all children and sets the item type to cot_empty.
6148 void hexapi cleanup(void);
6149
6150 /// Assign a number to the expression.
6151 /// \param func current function
6152 /// \param value number value
6153 /// \param nbytes size of the number in bytes
6154 /// \param sign number sign
6155 void hexapi put_number(cfunc_t *func, uint64 value, int nbytes, type_sign_t sign=no_sign);
6156
6157 /// Print expression into one line.
6158 /// \param vout output buffer
6159 /// \param func parent function. This argument is used to find out the referenced variable names.
6160 void hexapi print1(qstring *vout, const cfunc_t *func) const;
6161
6162 /// Calculate the type of the expression.
6163 /// Use this function to calculate the expression type when a new expression is built
6164 /// \param recursive if true, types of all children expression will be calculated
6165 /// before calculating our type
6166 void hexapi calc_type(bool recursive);
6167
6168 /// Compare two expressions.
6169 /// This function tries to compare two expressions in an 'intelligent' manner.
6170 /// For example, it knows about commutitive operators and can ignore useless casts.
6171 /// \param r the expression to compare against the current expression
6172 /// \return true expressions can be considered equal
6173 bool hexapi equal_effect(const cexpr_t &r) const;
6174
6175 /// Verify if the specified item is our parent.
6176 /// \param parent possible parent item
6177 /// \return true if the specified item is our parent
6178 bool hexapi is_child_of(const citem_t *parent) const;
6179
6180 /// Check if the expression contains the specified operator.
6181 /// \param needed_op operator code to search for
6182 /// \param times how many times the operator code should be present
6183 /// \return true if the expression has at least TIMES children with NEEDED_OP
6184 bool hexapi contains_operator(ctype_t needed_op, int times=1) const;
6185
6186 /// Does the expression contain a comma operator?
6187 bool contains_comma(int times=1) const { return contains_operator(cot_comma, times); }
6188 /// Does the expression contain an embedded statement operator?
6189 bool contains_insn(int times=1) const { return contains_operator(cot_insn, times); }
6190 /// Does the expression contain an embedded statement operator or a label?
6191 bool contains_insn_or_label(void) const { return contains_insn() || contains_label(); }
6192 /// Does the expression contain a comma operator or an embedded statement operator or a label?
6193 bool contains_comma_or_insn_or_label(int maxcommas=1) const { return contains_comma(maxcommas) || contains_insn_or_label(); }
6194 /// Is nice expression?
6195 /// Nice expressions do not contain comma operators, embedded statements, or labels.
6196 bool is_nice_expr(void) const { return !contains_comma_or_insn_or_label(); }
6197 /// Is nice condition?.
6198 /// Nice condition is a nice expression of the boolean type.
6199 bool is_nice_cond(void) const { return is_nice_expr() && type.is_bool(); }
6200 /// Is call object?
6201 /// \return true if our expression is the call object of the specified parent expression.
6202 bool is_call_object_of(const citem_t *parent) const { return parent != nullptr && parent->op == cot_call && ((cexpr_t*)parent)->x == this; }
6203 /// Is call argument?
6204 /// \return true if our expression is a call argument of the specified parent expression.
6205 bool is_call_arg_of(const citem_t *parent) const { return parent != nullptr && parent->op == cot_call && ((cexpr_t*)parent)->x != this; }
6206 /// Get expression sign
6207 type_sign_t get_type_sign(void) const { return type.get_sign(); }
6208 /// Is expression unsigned?
6209 bool is_type_unsigned(void) const { return type.is_unsigned(); }
6210 /// Is expression signed?
6211 bool is_type_signed(void) const { return type.is_signed(); }
6212 /// Get max number of bits that can really be used by the expression.
6213 /// For example, x % 16 can yield only 4 non-zero bits, higher bits are zero
6214 bit_bound_t hexapi get_high_nbit_bound(void) const;
6215 /// Get min number of bits that are certainly required to represent the expression.
6216 /// For example, constant 16 always uses 5 bits: 10000.
6217 int hexapi get_low_nbit_bound() const;
6218 /// Check if the expression requires an lvalue.
6219 /// \param child The function will check if this child of our expression must be an lvalue.
6220 /// \return true if child must be an lvalue.
6221 bool hexapi requires_lvalue(const cexpr_t *child) const;
6222 /// Check if the expression has side effects.
6223 /// Calls, pre/post inc/dec, and assignments have side effects.
6224 bool hexapi has_side_effects(void) const;
6225 /// Does the expression look like a boolean expression?
6226 /// In other words, its possible values are only 0 and 1.
6227 bool like_boolean(void) const;
6228 /// Check if the expression if aliasable.
6229 /// Simple registers and non-aliasble stack slots return false.
6230 bool is_aliasable(void) const;
6231 /// Get numeric value of the expression.
6232 /// This function can be called only on cot_num expressions!
6233 uint64 numval(void) const
6234 {
6235 QASSERT(50071, op == cot_num);
6236 return n->value(type);
6237 }
6238 /// Check if the expression is a number with the specified value.
6239 bool is_const_value(uint64 _v) const
6240 {
6241 return op == cot_num && numval() == _v;
6242 }
6243 /// Check if the expression is a negative number.
6244 bool is_negative_const(void) const
6245 {
6246 return op == cot_num && int64(numval()) < 0;
6247 }
6248 /// Check if the expression is a non-negative number.
6249 bool is_non_negative_const(void) const
6250 {
6251 return op == cot_num && int64(numval()) >= 0;
6252 }
6253 /// Check if the expression is a non-zero number.
6254 bool is_non_zero_const(void) const
6255 {
6256 return op == cot_num && numval() != 0;
6257 }
6258 /// Check if the expression is a zero.
6259 bool is_zero_const(void) const { return is_const_value(0); }
6260 /// Does the PARENT need the expression value
6261 bool is_value_used(const citem_t *parent) const;
6262 /// Get expression value.
6263 /// \param out Pointer to the variable where the expression value is returned.
6264 /// \return true if the expression is a number.
6265 bool get_const_value(uint64 *out) const
6266 {
6267 if ( op == cot_num )
6268 {
6269 if ( out != nullptr )
6270 *out = numval();
6271 return true;
6272 }
6273 return false;
6274 }
6275 /// May the expression be a pointer?
6276 bool hexapi maybe_ptr(void) const;
6277
6278 /// Find pointer or array child.
6280 {
6281 if ( x->type.is_ptr_or_array() )
6282 return x;
6283 if ( y->type.is_ptr_or_array() )
6284 return y;
6285 return nullptr;
6286 }
6287 /// Find the child with the specified operator.
6288 const cexpr_t *find_op(ctype_t _op) const
6289 {
6290 if ( x->op == _op )
6291 return x;
6292 if ( y->op == _op )
6293 return y;
6294 return nullptr;
6295 }
6296 cexpr_t *find_op(ctype_t _op)
6297 {
6298 return (cexpr_t *)((const cexpr_t *)this)->find_op(_op);
6299 }
6300
6301 /// Find the operand with a numeric value
6302 const cexpr_t *find_num_op(void) const { return find_op(cot_num); }
6303 cexpr_t *find_num_op(void) { return find_op(cot_num); }
6304 /// Find the pointer operand.
6305 /// This function returns the pointer operand for binary expressions.
6306 const cexpr_t *find_ptr_or_array(bool remove_eqsize_casts) const;
6307 /// Get the other operand.
6308 /// This function returns the other operand (not the specified one)
6309 /// for binary expressions.
6310 const cexpr_t *theother(const cexpr_t *what) const { return what == x ? y : x; }
6311 cexpr_t *theother(const cexpr_t *what) { return what == x ? y : x; }
6312
6313 // these are inline functions, see below
6314 bool get_1num_op(cexpr_t **o1, cexpr_t **o2);
6315 bool get_1num_op(const cexpr_t **o1, const cexpr_t **o2) const;
6316
6317};
6318DECLARE_TYPE_AS_MOVABLE(cexpr_t);
6319
6320/// Statement with an expression.
6321/// This is a base class for various statements with expressions.
6323{
6324 cexpr_t expr; ///< Expression of the statement
6325 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
6326};
6327DECLARE_TYPE_AS_MOVABLE(ceinsn_t);
6328
6329/// Should curly braces be printed?
6331{
6332 CALC_CURLY_BRACES, ///< print curly braces if necessary
6333 NO_CURLY_BRACES, ///< don't print curly braces
6334 USE_CURLY_BRACES, ///< print curly braces without any checks
6335};
6336
6337/// If statement
6338struct cif_t : public ceinsn_t
6339{
6340 cinsn_t *ithen; ///< Then-branch of the if-statement
6341 cinsn_t *ielse; ///< Else-branch of the if-statement. May be nullptr.
6342 cif_t(void) : ithen(nullptr), ielse(nullptr) {}
6343 cif_t(const cif_t &r) : ceinsn_t(), ithen(nullptr), ielse(nullptr) { *this = r; }
6344 cif_t &operator=(const cif_t &r) { return assign(r); }
6345 cif_t &hexapi assign(const cif_t &r);
6346 DECLARE_COMPARISONS(cif_t);
6347 ~cif_t(void) { cleanup(); }
6348 void cleanup(void);
6349};
6350
6351/// Base class for loop statements
6352struct cloop_t : public ceinsn_t
6353{
6354 cinsn_t *body;
6355 cloop_t(void) : body(nullptr) {}
6356 cloop_t(cinsn_t *b) : body(b) {}
6357 cloop_t(const cloop_t &r) : ceinsn_t(), body(nullptr) { *this = r; }
6358 cloop_t &operator=(const cloop_t &r) { return assign(r); }
6359 cloop_t &hexapi assign(const cloop_t &r);
6360 ~cloop_t(void) { cleanup(); }
6361 void cleanup(void);
6362};
6363
6364/// For-loop
6365struct cfor_t : public cloop_t
6366{
6367 cexpr_t init; ///< Initialization expression
6368 cexpr_t step; ///< Step expression
6369 DECLARE_COMPARISONS(cfor_t);
6370};
6371
6372/// While-loop
6373struct cwhile_t : public cloop_t
6374{
6375 DECLARE_COMPARISONS(cwhile_t);
6376};
6377
6378/// Do-loop
6379struct cdo_t : public cloop_t
6380{
6381 DECLARE_COMPARISONS(cdo_t);
6382};
6383
6384/// Return statement
6385struct creturn_t : public ceinsn_t
6386{
6387 DECLARE_COMPARISONS(creturn_t);
6388};
6389
6390/// Goto statement
6392{
6393 int label_num; ///< Target label number
6394 void print(const citem_t *parent, int indent, vc_printer_t &vp) const;
6395 DECLARE_COMPARISONS(cgoto_t);
6396 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
6397};
6398
6399/// asm statement
6400struct casm_t : public eavec_t
6401{
6402 casm_t(ea_t ea) { push_back(ea); }
6403 casm_t(const casm_t &r) : eavec_t(eavec_t(r)) {}
6404 DECLARE_COMPARISONS(casm_t);
6405 void print(const citem_t *parent, int indent, vc_printer_t &vp) const;
6406 bool one_insn(void) const { return size() == 1; }
6407 void genasm(qstring *buf, ea_t ea) const;
6408};
6409
6410/// Vector of pointers to statements.
6411typedef qvector<cinsn_t *> cinsnptrvec_t;
6412
6413/// Ctree item: statement.
6414/// Depending on the exact statement type, various fields of the union are used.
6415struct cinsn_t : public citem_t
6416{
6417 union
6418 {
6419 cblock_t *cblock; ///< details of block-statement
6420 cexpr_t *cexpr; ///< details of expression-statement
6421 cif_t *cif; ///< details of if-statement
6422 cfor_t *cfor; ///< details of for-statement
6423 cwhile_t *cwhile; ///< details of while-statement
6424 cdo_t *cdo; ///< details of do-statement
6425 cswitch_t *cswitch; ///< details of switch-statement
6426 creturn_t *creturn; ///< details of return-statement
6427 cgoto_t *cgoto; ///< details of goto-statement
6428 casm_t *casm; ///< details of asm-statement
6429 };
6430
6431 cinsn_t(void) { zero(); }
6432 cinsn_t(const cinsn_t &r) : citem_t(cit_empty) { *this = r; }
6433 void swap(cinsn_t &r) { citem_t::swap(r); std::swap(cblock, r.cblock); }
6434 cinsn_t &operator=(const cinsn_t &r) { return assign(r); }
6435 cinsn_t &hexapi assign(const cinsn_t &r);
6436 DECLARE_COMPARISONS(cinsn_t);
6437 ~cinsn_t(void) { cleanup(); }
6438
6439 /// Replace the statement.
6440 /// The children of the statement are abandoned (not freed).
6441 /// The statement pointed by 'r' is moved to 'this' statement
6442 /// \param r the source statement. It is deleted after being copied
6443 void hexapi replace_by(cinsn_t *r);
6444
6445 /// Cleanup the statement.
6446 /// This function properly deletes all children and sets the item type to cit_empty.
6447 void hexapi cleanup(void);
6448
6449 /// Overwrite with zeroes without cleaning memory or deleting children
6450 void zero(void) { op = cit_empty; cblock = nullptr; }
6451
6452 /// Create a new statement.
6453 /// The current statement must be a block. The new statement will be appended to it.
6454 /// \param insn_ea statement address
6455 cinsn_t &hexapi new_insn(ea_t insn_ea);
6456
6457 /// Create a new if-statement.
6458 /// The current statement must be a block. The new statement will be appended to it.
6459 /// \param cnd if condition. It will be deleted after being copied.
6460 cif_t &hexapi create_if(cexpr_t *cnd);
6461
6462 /// Print the statement into many lines.
6463 /// \param indent indention (number of spaces) for the statement
6464 /// \param vp printer helper class which will receive the generated text.
6465 /// \param use_curly if the statement is a block, how should curly braces be printed.
6466 void hexapi print(int indent, vc_printer_t &vp, use_curly_t use_curly=CALC_CURLY_BRACES) const;
6467
6468 /// Print the statement into one line.
6469 /// Currently this function is not available.
6470 /// \param vout output buffer
6471 /// \param func parent function. This argument is used to find out the referenced variable names.
6472 void hexapi print1(qstring *vout, const cfunc_t *func) const;
6473
6474 /// Check if the statement passes execution to the next statement.
6475 /// \return false if the statement breaks the control flow (like goto, return, etc)
6476 bool hexapi is_ordinary_flow(void) const;
6477
6478 /// Check if the statement contains a statement of the specified type.
6479 /// \param type statement opcode to look for
6480 /// \param times how many times TYPE should be present
6481 /// \return true if the statement has at least TIMES children with opcode == TYPE
6482 bool hexapi contains_insn(ctype_t type, int times=1) const;
6483
6484 /// Collect free \c break statements.
6485 /// This function finds all free \c break statements within the current statement.
6486 /// A \c break statement is free if it does not have a loop or switch parent that
6487 /// that is also within the current statement.
6488 /// \param breaks pointer to the variable where the vector of all found free
6489 /// \c break statements is returned. This argument can be nullptr.
6490 /// \return true if some free \c break statements have been found
6491 bool hexapi collect_free_breaks(cinsnptrvec_t *breaks);
6492
6493 /// Collect free \c continue statements.
6494 /// This function finds all free \c continue statements within the current statement.
6495 /// A \c continue statement is free if it does not have a loop parent that
6496 /// that is also within the current statement.
6497 /// \param continues pointer to the variable where the vector of all found free
6498 /// \c continue statements is returned. This argument can be nullptr.
6499 /// \return true if some free \c continue statements have been found
6500 bool hexapi collect_free_continues(cinsnptrvec_t *continues);
6501
6502 /// Check if the statement has free \c break statements.
6503 bool contains_free_break(void) const { return CONST_CAST(cinsn_t*)(this)->collect_free_breaks(nullptr); }
6504 /// Check if the statement has free \c continue statements.
6505 bool contains_free_continue(void) const { return CONST_CAST(cinsn_t*)(this)->collect_free_continues(nullptr); }
6506
6507};
6508DECLARE_TYPE_AS_MOVABLE(cinsn_t);
6509
6510typedef qlist<cinsn_t> cinsn_list_t;
6511
6512/// Compound statement (curly braces)
6513struct cblock_t : public cinsn_list_t // we need list to be able to manipulate
6514{ // its elements freely
6515 DECLARE_COMPARISONS(cblock_t);
6516};
6517
6518/// Function argument
6519struct carg_t : public cexpr_t
6520{
6521 bool is_vararg; ///< is a vararg (matches ...)
6522 tinfo_t formal_type; ///< formal parameter type (if known)
6523 void consume_cexpr(cexpr_t *e)
6524 {
6525 qswap(*(cexpr_t*)this, *e);
6526 delete e;
6527 }
6528 carg_t(void) : is_vararg(false) {}
6529 DECLARE_COMPARISONS(carg_t)
6530 {
6531 return cexpr_t::compare(r);
6532 }
6533};
6534DECLARE_TYPE_AS_MOVABLE(carg_t);
6535
6536/// Function argument list
6537struct carglist_t : public qvector<carg_t>
6538{
6539 tinfo_t functype; ///< function object type
6540 int flags; ///< call flags
6541#define CFL_FINAL 0x0001 ///< call type is final, should not be changed
6542#define CFL_HELPER 0x0002 ///< created from a decompiler helper function
6543#define CFL_NORET 0x0004 ///< call does not return
6544 carglist_t(void) : flags(0) {}
6545 carglist_t(const tinfo_t &ftype, int fl = 0) : functype(ftype), flags(fl) {}
6546 DECLARE_COMPARISONS(carglist_t);
6547 void print(qstring *vout, const cfunc_t *func) const;
6548 int print(int curpos, vc_printer_t &vp) const;
6549};
6550
6551/// Switch case. Usually cinsn_t is a block
6552struct ccase_t : public cinsn_t
6553{
6554 uint64vec_t values; ///< List of case values.
6555 ///< if empty, then 'default' case
6556 DECLARE_COMPARISONS(ccase_t);
6557 void set_insn(cinsn_t *i); // deletes 'i'
6558 size_t size(void) const { return values.size(); }
6559 const uint64 &value(int i) const { return values[i]; }
6560};
6561DECLARE_TYPE_AS_MOVABLE(ccase_t);
6562
6563/// Vector of switch cases
6564struct ccases_t : public qvector<ccase_t>
6565{
6566 DECLARE_COMPARISONS(ccases_t);
6567 int find_value(uint64 v) const;
6568};
6569
6570/// Switch statement
6571struct cswitch_t : public ceinsn_t
6572{
6573 cnumber_t mvnf; ///< Maximal switch value and number format
6574 ccases_t cases; ///< Switch cases: values and instructions
6575 DECLARE_COMPARISONS(cswitch_t);
6576};
6577
6578//---------------------------------------------------------------------------
6579/// Invisible COLOR_ADDR tags in the output text are used to refer to ctree items and variables
6581{
6582 uval_t value = BADADDR;
6583#define ANCHOR_INDEX 0x1FFFFFFF
6584#define ANCHOR_MASK 0xC0000000
6585#define ANCHOR_CITEM 0x00000000 ///< c-tree item
6586#define ANCHOR_LVAR 0x40000000 ///< declaration of local variable
6587#define ANCHOR_ITP 0x80000000 ///< item type preciser
6588#define ANCHOR_BLKCMT 0x20000000 ///< block comment (for ctree items)
6589 int get_index(void) const { return value & ANCHOR_INDEX; }
6590 item_preciser_t get_itp(void) const { return item_preciser_t(value & ~ANCHOR_ITP); }
6591 bool is_valid_anchor(void) const { return value != BADADDR; }
6592 bool is_citem_anchor(void) const { return (value & ANCHOR_MASK) == ANCHOR_CITEM; }
6593 bool is_lvar_anchor(void) const { return (value & ANCHOR_MASK) == ANCHOR_LVAR; }
6594 bool is_itp_anchor(void) const { return (value & ANCHOR_ITP) != 0; }
6595 bool is_blkcmt_anchor(void) const { return (value & ANCHOR_BLKCMT) != 0; }
6596};
6597
6598/// Type of the cursor item.
6600{
6601 VDI_NONE, ///< undefined
6602 VDI_EXPR, ///< c-tree item
6603 VDI_LVAR, ///< declaration of local variable
6604 VDI_FUNC, ///< the function itself (the very first line with the function prototype)
6605 VDI_TAIL, ///< cursor is at (beyond) the line end (commentable line)
6606};
6607
6608/// Cursor item.
6609/// Information about the item under the cursor
6611{
6613 union
6614 {
6615 citem_t *it;
6616 cexpr_t *e; ///< VDI_EXPR: Expression
6617 cinsn_t *i; ///< VDI_EXPR: Statement
6618 lvar_t *l; ///< VDI_LVAR: Local variable
6619 cfunc_t *f; ///< VDI_FUNC: Function
6620 treeloc_t loc; ///< VDI_TAIL: Line tail
6621 };
6622
6623 ctree_item_t(): citype(VDI_NONE) {}
6624
6625 void verify(const mba_t *mba) const;
6626
6627 /// Get pointer to structure member.
6628 /// If the current item is a structure field,
6629 /// this function will return pointer to its definition.
6630 /// \return nullptr if failed
6631 /// \param[out] p_sptr pointer to the variable where the pointer to the
6632 /// parent structure is returned. This parameter can be nullptr.
6633
6634 member_t *hexapi get_memptr(struc_t **p_sptr=nullptr) const;
6635
6636 /// Get pointer to local variable.
6637 /// If the current item is a local variable,
6638 /// this function will return pointer to its definition.
6639 /// \return nullptr if failed
6640
6641 lvar_t *hexapi get_lvar(void) const;
6642
6643
6644 /// Get address of the current item.
6645 /// Each ctree item has an address.
6646 /// \return BADADDR if failed
6647
6648 ea_t hexapi get_ea(void) const;
6649
6650
6651 /// Get label number of the current item.
6652 /// \param[in] gln_flags Combination of \ref GLN_ bits
6653 /// \return -1 if failed or no label
6654
6655 int hexapi get_label_num(int gln_flags) const;
6656/// \defgroup GLN_ get_label_num control
6657//@{
6658#define GLN_CURRENT 0x01 ///< get label of the current item
6659#define GLN_GOTO_TARGET 0x02 ///< get goto target
6660#define GLN_ALL 0x03 ///< get both
6661//@}
6662
6663 /// Is the current item is a ctree item?
6664 bool is_citem(void) const { return citype == VDI_EXPR; }
6665
6666 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
6667};
6668
6669/// Unused label disposition.
6671{
6672 FORBID_UNUSED_LABELS = 0, ///< Unused labels cause interr
6673 ALLOW_UNUSED_LABELS = 1, ///< Unused labels are permitted
6674};
6675
6676typedef std::map<int, qstring> user_labels_t;
6677
6678/// Logically negate the specified expression.
6679/// The specified expression will be logically negated.
6680/// For example, "x == y" is converted into "x != y" by this function.
6681/// \param e expression to negate. After the call, e must not be used anymore
6682/// because it can be changed by the function. The function return value
6683/// must be used to refer to the expression.
6684/// \return logically negated expression.
6685
6687
6688
6689/// Create a new block-statement.
6690
6691cinsn_t *hexapi new_block(void);
6692
6693
6694/// Create a helper object.
6695/// This function creates a helper object.
6696/// The named function is not required to exist, the decompiler will only print
6697/// its name in the output. Helper functions are usually used to represent arbitrary
6698/// function or macro calls in the output.
6699/// \param standalone false:helper must be called; true:helper can be used in any expression
6700/// \param type type of the create function object
6701/// \param format printf-style format string that will be used to create the function name.
6702/// \param va additional arguments for printf
6703/// \return the created expression.
6704
6705AS_PRINTF(3, 0) cexpr_t *hexapi vcreate_helper(bool standalone, const tinfo_t &type, const char *format, va_list va);
6706
6707/// Create a helper object..
6708AS_PRINTF(3, 4) inline cexpr_t *create_helper(bool standalone, const tinfo_t &type, const char *format, ...)
6709{
6710 va_list va;
6711 va_start(va, format);
6712 cexpr_t *e = vcreate_helper(standalone, type, format, va);
6713 va_end(va);
6714 return e;
6715}
6716
6717
6718/// Create a helper call expression.
6719/// This function creates a new expression: a call of a helper function.
6720/// \param rettype type of the whole expression.
6721/// \param args helper arguments. this object will be consumed by the function.
6722/// if there are no args, this parameter may be specified as nullptr.
6723/// \param format printf-style format string that will be used to create the function name.
6724/// \param va additional arguments for printf
6725/// \return the created expression.
6726
6727AS_PRINTF(3, 0) cexpr_t *hexapi vcall_helper(const tinfo_t &rettype, carglist_t *args, const char *format, va_list va);
6728
6729/// Create a helper call.
6730AS_PRINTF(3, 4) inline cexpr_t *call_helper(
6731 const tinfo_t &rettype,
6732 carglist_t *args,
6733 const char *format, ...)
6734{
6735 va_list va;
6736 va_start(va, format);
6737 cexpr_t *e = vcall_helper(rettype, args, format, va);
6738 va_end(va);
6739 return e;
6740}
6741
6742
6743/// Create a number expression
6744/// \param n value
6745/// \param func current function
6746/// \param ea definition address of the number
6747/// \param opnum operand number of the number (in the disassembly listing)
6748/// \param sign number sign
6749/// \param size size of number in bytes
6750/// Please note that the type of the resulting expression can be anything because
6751/// it can be inherited from the disassembly listing or taken from the user
6752/// specified number representation in the pseudocode view.
6753
6754cexpr_t *hexapi make_num(uint64 n, cfunc_t *func=nullptr, ea_t ea=BADADDR, int opnum=0, type_sign_t sign=no_sign, int size=0);
6755
6756
6757/// Create a reference.
6758/// This function performs the following conversion: "obj" => "&obj".
6759/// It can handle casts, annihilate "&*", and process other special cases.
6760
6762
6763
6764/// Dereference a pointer.
6765/// This function dereferences a pointer expression.
6766/// It performs the following conversion: "ptr" => "*ptr"
6767/// It can handle discrepancies in the pointer type and the access size.
6768/// \param e expression to deference
6769/// \param ptrsize access size
6770/// \param is_flt dereferencing for floating point access?
6771/// \return dereferenced expression
6772
6773cexpr_t *hexapi dereference(cexpr_t *e, int ptrsize, bool is_flt=false);
6774
6775
6776/// Save user defined labels into the database.
6777/// \param func_ea the entry address of the function,
6778/// ignored if FUNC != nullptr
6779/// \param user_labels collection of user defined labels
6780/// \param func pointer to current function,
6781/// if FUNC != nullptr, then save labels using a more stable
6782/// method that preserves them even when the decompiler
6783/// output drastically changes
6784
6785void hexapi save_user_labels(ea_t func_ea, const user_labels_t *user_labels); // DEPRECATED
6786void hexapi save_user_labels2(ea_t func_ea, const user_labels_t *user_labels, const cfunc_t *func=nullptr);
6787
6788
6789/// Save user defined comments into the database.
6790/// \param func_ea the entry address of the function
6791/// \param user_cmts collection of user defined comments
6792
6793void hexapi save_user_cmts(ea_t func_ea, const user_cmts_t *user_cmts);
6794
6795/// Save user defined number formats into the database.
6796/// \param func_ea the entry address of the function
6797/// \param numforms collection of user defined comments
6798
6799void hexapi save_user_numforms(ea_t func_ea, const user_numforms_t *numforms);
6800
6801
6802/// Save user defined citem iflags into the database.
6803/// \param func_ea the entry address of the function
6804/// \param iflags collection of user defined citem iflags
6805
6806void hexapi save_user_iflags(ea_t func_ea, const user_iflags_t *iflags);
6807
6808
6809/// Save user defined union field selections into the database.
6810/// \param func_ea the entry address of the function
6811/// \param unions collection of union field selections
6812
6813void hexapi save_user_unions(ea_t func_ea, const user_unions_t *unions);
6814
6815
6816/// Restore user defined labels from the database.
6817/// \param func_ea the entry address of the function,
6818/// ignored if FUNC != nullptr
6819/// \param func pointer to current function
6820/// \return collection of user defined labels.
6821/// The returned object must be deleted by the caller using delete_user_labels()
6822
6823user_labels_t *hexapi restore_user_labels(ea_t func_ea); // DEPRECATED
6824user_labels_t *hexapi restore_user_labels2(ea_t func_ea, const cfunc_t *func=nullptr);
6825
6826
6827/// Restore user defined comments from the database.
6828/// \param func_ea the entry address of the function
6829/// \return collection of user defined comments.
6830/// The returned object must be deleted by the caller using delete_user_cmts()
6831
6832user_cmts_t *hexapi restore_user_cmts(ea_t func_ea);
6833
6834
6835/// Restore user defined number formats from the database.
6836/// \param func_ea the entry address of the function
6837/// \return collection of user defined number formats.
6838/// The returned object must be deleted by the caller using delete_user_numforms()
6839
6841
6842
6843/// Restore user defined citem iflags from the database.
6844/// \param func_ea the entry address of the function
6845/// \return collection of user defined iflags.
6846/// The returned object must be deleted by the caller using delete_user_iflags()
6847
6848user_iflags_t *hexapi restore_user_iflags(ea_t func_ea);
6849
6850
6851/// Restore user defined union field selections from the database.
6852/// \param func_ea the entry address of the function
6853/// \return collection of union field selections
6854/// The returned object must be deleted by the caller using delete_user_unions()
6855
6856user_unions_t *hexapi restore_user_unions(ea_t func_ea);
6857
6858
6859typedef std::map<ea_t, cinsnptrvec_t> eamap_t;
6860// map of instruction boundaries. may contain INS_EPILOG for the epilog instructions
6861typedef std::map<cinsn_t *, rangeset_t> boundaries_t;
6862#define INS_EPILOG ((cinsn_t *)1)
6863
6864// Tags to find this location quickly: #cfunc_t #func_t
6865//-------------------------------------------------------------------------
6866/// Decompiled function. Decompilation result is kept here.
6868{
6869 ea_t entry_ea; ///< function entry address
6870 mba_t *mba; ///< underlying microcode
6871 cinsn_t body; ///< function body, must be a block
6872 intvec_t &argidx; ///< list of arguments (indexes into vars)
6873 ctree_maturity_t maturity; ///< maturity level
6874 // The following maps must be accessed using helper functions.
6875 // Example: for user_labels_t, see functions starting with "user_labels_".
6876 user_labels_t *user_labels;///< user-defined labels.
6877 user_cmts_t *user_cmts; ///< user-defined comments.
6878 user_numforms_t *numforms; ///< user-defined number formats.
6879 user_iflags_t *user_iflags;///< user-defined item flags \ref CIT_
6880 user_unions_t *user_unions;///< user-defined union field selections.
6881/// \defgroup CIT_ ctree item iflags bits
6882//@{
6883#define CIT_COLLAPSED 0x0001 ///< display ctree item in collapsed form
6884//@}
6885 int refcnt; ///< reference count to this object. use cfuncptr_t
6886 int statebits; ///< current cfunc_t state. see \ref CFS_
6887/// \defgroup CFS_ cfunc state bits
6888#define CFS_BOUNDS 0x0001 ///< 'eamap' and 'boundaries' are ready
6889#define CFS_TEXT 0x0002 ///< 'sv' is ready (and hdrlines)
6890#define CFS_LVARS_HIDDEN 0x0004 ///< local variable definitions are collapsed
6891#define CFS_LOCKED 0x0008 ///< cfunc is temporarily locked
6892 eamap_t *eamap; ///< ea->insn map. use \ref get_eamap
6893 boundaries_t *boundaries; ///< map of instruction boundaries. use \ref get_boundaries
6894 strvec_t sv; ///< decompilation output: function text. use \ref get_pseudocode
6895 int hdrlines; ///< number of lines in the declaration area
6896 mutable ctree_items_t treeitems; ///< vector of ctree items
6897
6898 // the exact size of this class is not documented, there may be more fields
6899 char reserved[];
6900
6901public:
6902 cfunc_t(mba_t *mba); // use create_cfunc()
6903 ~cfunc_t(void) { cleanup(); }
6904 void release(void) { delete this; }
6905 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
6906
6907 /// Generate the function body.
6908 /// This function (re)generates the function body from the underlying microcode.
6909 void hexapi build_c_tree(void);
6910
6911 /// Verify the ctree.
6912 /// This function verifies the ctree. If the ctree is malformed, an internal error
6913 /// is generated. Use it to verify the ctree after your modifications.
6914 /// \param aul Are unused labels acceptable?
6915 /// \param even_without_debugger if false and there is no debugger, the verification will be skipped
6916 void hexapi verify(allow_unused_labels_t aul, bool even_without_debugger) const;
6917
6918 /// Print function prototype.
6919 /// \param vout output buffer
6920 void hexapi print_dcl(qstring *vout) const;
6921
6922 /// Print function text.
6923 /// \param vp printer helper class to receive the generated text.
6924 void hexapi print_func(vc_printer_t &vp) const;
6925
6926 /// Get the function type.
6927 /// \param type variable where the function type is returned
6928 /// \return false if failure
6929 bool hexapi get_func_type(tinfo_t *type) const;
6930
6931 /// Get vector of local variables.
6932 /// \return pointer to the vector of local variables. If you modify this vector,
6933 /// the ctree must be regenerated in order to have correct cast operators.
6934 /// Use build_c_tree() for that.
6935 /// Removing lvars should be done carefully: all references in ctree
6936 /// and microcode must be corrected after that.
6937 lvars_t *hexapi get_lvars(void);
6938
6939 /// Get stack offset delta.
6940 /// The local variable stack offsets retrieved by v.location.stkoff()
6941 /// should be adjusted before being used as stack frame offsets in IDA.
6942 /// \return the delta to apply.
6943 /// example: ida_stkoff = v.location.stkoff() - f->get_stkoff_delta()
6944 sval_t hexapi get_stkoff_delta(void);
6945
6946 /// Find the label.
6947 /// \return pointer to the ctree item with the specified label number.
6948 citem_t *hexapi find_label(int label);
6949
6950 /// Remove unused labels.
6951 /// This function checks what labels are really used by the function and
6952 /// removes the unused ones. You must call it after deleting a goto statement.
6953 void hexapi remove_unused_labels(void);
6954
6955 /// Retrieve a user defined comment.
6956 /// \param loc ctree location
6957 /// \param rt should already retrieved comments retrieved again?
6958 /// \return pointer to the comment string or nullptr
6959 const char *hexapi get_user_cmt(const treeloc_t &loc, cmt_retrieval_type_t rt) const;
6960
6961 /// Set a user defined comment.
6962 /// This function stores the specified comment in the cfunc_t structure.
6963 /// The save_user_cmts() function must be called after it.
6964 /// \param loc ctree location
6965 /// \param cmt new comment. if empty or nullptr, then an existing comment is deleted.
6966 void hexapi set_user_cmt(const treeloc_t &loc, const char *cmt);
6967
6968 /// Retrieve citem iflags.
6969 /// \param loc citem locator
6970 /// \return \ref CIT_ or 0
6971 int32 hexapi get_user_iflags(const citem_locator_t &loc) const;
6972
6973 /// Set citem iflags.
6974 /// \param loc citem locator
6975 /// \param iflags new iflags
6976 void hexapi set_user_iflags(const citem_locator_t &loc, int32 iflags);
6977
6978 /// Check if there are orphan comments.
6979 bool hexapi has_orphan_cmts(void) const;
6980
6981 /// Delete all orphan comments.
6982 /// The save_user_cmts() function must be called after this call.
6983 int hexapi del_orphan_cmts(void);
6984
6985 /// Retrieve a user defined union field selection.
6986 /// \param ea address
6987 /// \param path out: path describing the union selection.
6988 /// \return pointer to the path or nullptr
6989 bool hexapi get_user_union_selection(ea_t ea, intvec_t *path);
6990
6991 /// Set a union field selection.
6992 /// The save_user_unions() function must be called after calling this function.
6993 /// \param ea address
6994 /// \param path in: path describing the union selection.
6995 void hexapi set_user_union_selection(ea_t ea, const intvec_t &path);
6996
6997 /// Save user-defined labels into the database
6998 void hexapi save_user_labels(void) const;
6999 /// Save user-defined comments into the database
7000 void hexapi save_user_cmts(void) const;
7001 /// Save user-defined number formats into the database
7002 void hexapi save_user_numforms(void) const;
7003 /// Save user-defined iflags into the database
7004 void hexapi save_user_iflags(void) const;
7005 /// Save user-defined union field selections into the database
7006 void hexapi save_user_unions(void) const;
7007
7008 /// Get ctree item for the specified cursor position.
7009 /// \return false if failed to get the current item
7010 /// \param line line of decompilation text (element of \ref sv)
7011 /// \param x x cursor coordinate in the line
7012 /// \param is_ctree_line does the line belong to statement area? (if not, it is assumed to belong to the declaration area)
7013 /// \param phead ptr to the first item on the line (used to attach block comments). May be nullptr
7014 /// \param pitem ptr to the current item. May be nullptr
7015 /// \param ptail ptr to the last item on the line (used to attach indented comments). May be nullptr
7016 /// \sa vdui_t::get_current_item()
7017 bool hexapi get_line_item(
7018 const char *line,
7019 int x,
7020 bool is_ctree_line,
7021 ctree_item_t *phead,
7022 ctree_item_t *pitem,
7023 ctree_item_t *ptail);
7024
7025 /// Get information about decompilation warnings.
7026 /// \return reference to the vector of warnings
7027 hexwarns_t &hexapi get_warnings(void);
7028
7029 /// Get pointer to ea->insn map.
7030 /// This function initializes eamap if not done yet.
7031 eamap_t &hexapi get_eamap(void);
7032
7033 /// Get pointer to map of instruction boundaries.
7034 /// This function initializes the boundary map if not done yet.
7035 boundaries_t &hexapi get_boundaries(void);
7036
7037 /// Get pointer to decompilation output: the pseudocode.
7038 /// This function generates pseudocode if not done yet.
7039 const strvec_t &hexapi get_pseudocode(void);
7040
7041 /// Refresh ctext after a ctree modification.
7042 /// This function informs the decompiler that ctree (\ref body) have been
7043 /// modified and ctext (\ref sv) does not correspond to it anymore.
7044 /// It also refreshes the pseudocode windows if there is any.
7045 void hexapi refresh_func_ctext(void);
7046
7047 bool hexapi gather_derefs(const ctree_item_t &ci, udt_type_data_t *udm=nullptr) const;
7048 bool hexapi find_item_coords(const citem_t *item, int *px, int *py);
7049 bool locked(void) const { return (statebits & CFS_LOCKED) != 0; }
7050private:
7051 /// Cleanup.
7052 /// Properly delete all children and free memory.
7053 void hexapi cleanup(void);
7054 DECLARE_UNCOPYABLE(cfunc_t)
7055};
7056typedef qvector<cfuncptr_t> cfuncptrs_t;
7057
7058/// \defgroup DECOMP_ decompile() flags
7059//@{
7060#define DECOMP_NO_WAIT 0x0001 ///< do not display waitbox
7061#define DECOMP_NO_CACHE 0x0002 ///< do not use decompilation cache
7062#define DECOMP_NO_FRAME 0x0004 ///< do not use function frame info (only snippet mode)
7063#define DECOMP_WARNINGS 0x0008 ///< display warnings in the output window
7064#define DECOMP_ALL_BLKS 0x0010 ///< generate microcode for unreachable blocks
7065#define DECOMP_NO_HIDE 0x0020 ///< do not close display waitbox. see close_hexrays_waitboxes()
7066#define DECOMP_NO_XREFS 0x0040 ///< do not update global xrefs cache
7067//@}
7068
7069/// Close the waitbox displayed by the decompiler.
7070/// Useful if DECOMP_NO_HIDE was used during decompilation.
7071
7072void hexapi close_hexrays_waitbox(void);
7073
7074
7075/// Decompile a snippet or a function.
7076/// \param mbr what to decompile
7077/// \param hf extended error information (if failed)
7078/// \param decomp_flags bitwise combination of \ref DECOMP_... bits
7079/// \return pointer to the decompilation result (a reference counted pointer).
7080/// nullptr if failed.
7081
7082cfuncptr_t hexapi decompile(
7083 const mba_ranges_t &mbr,
7085 int decomp_flags=0);
7086
7087
7088/// Decompile a function.
7089/// Multiple decompilations of the same function return the same object.
7090/// \param pfn pointer to function to decompile
7091/// \param hf extended error information (if failed)
7092/// \param decomp_flags bitwise combination of \ref DECOMP_... bits
7093/// \return pointer to the decompilation result (a reference counted pointer).
7094/// nullptr if failed.
7095
7096inline cfuncptr_t decompile_func(
7097 func_t *pfn,
7099 int decomp_flags=0)
7100{
7101 mba_ranges_t mbr(pfn);
7102 return decompile(mbr, hf, decomp_flags);
7103}
7104
7105
7106/// Decompile a snippet.
7107/// \param ranges snippet ranges. ranges[0].start_ea is the entry point
7108/// \param hf extended error information (if failed)
7109/// \param decomp_flags bitwise combination of \ref DECOMP_... bits
7110/// \return pointer to the decompilation result (a reference counted pointer).
7111/// nullptr if failed.
7112
7113inline cfuncptr_t decompile_snippet(
7114 const rangevec_t &ranges,
7116 int decomp_flags=0)
7117{
7118 mba_ranges_t mbr(ranges);
7119 return decompile(mbr, hf, decomp_flags);
7120}
7121
7122
7123/// Generate microcode of an arbitrary code snippet
7124/// \param mbr snippet ranges
7125/// \param hf extended error information (if failed)
7126/// \param retlist list of registers the snippet returns
7127/// \param decomp_flags bitwise combination of \ref DECOMP_... bits
7128/// \param reqmat required microcode maturity
7129/// \return pointer to the microcode, nullptr if failed.
7130
7132 const mba_ranges_t &mbr,
7134 const mlist_t *retlist=nullptr,
7135 int decomp_flags=0,
7137
7138
7139/// Create a new cfunc_t object.
7140/// \param mba microcode object.
7141/// After creating the cfunc object it takes the ownership of MBA.
7142
7143cfuncptr_t hexapi create_cfunc(mba_t *mba);
7144
7145
7146/// Flush the cached decompilation results.
7147/// Erases a cache entry for the specified function.
7148/// \param ea function to erase from the cache
7149/// \param close_views close pseudocode windows that show the function
7150/// \return if a cache entry existed.
7151
7152bool hexapi mark_cfunc_dirty(ea_t ea, bool close_views=false);
7153
7154
7155/// Flush all cached decompilation results.
7156
7157void hexapi clear_cached_cfuncs(void);
7158
7159
7160/// Do we have a cached decompilation result for 'ea'?
7161
7162bool hexapi has_cached_cfunc(ea_t ea);
7163
7164//--------------------------------------------------------------------------
7165// Now cinsn_t class is defined, define the cleanup functions:
7166inline void cif_t::cleanup(void) { delete ithen; delete ielse; }
7167inline void cloop_t::cleanup(void) { delete body; }
7168
7169/// Print item into one line.
7170/// \param vout output buffer
7171/// \param func parent function. This argument is used to find out the referenced variable names.
7172/// \return length of the generated text.
7173
7174inline void citem_t::print1(qstring *vout, const cfunc_t *func) const
7175{
7176 if ( is_expr() )
7177 ((cexpr_t*)this)->print1(vout, func);
7178 else
7179 ((cinsn_t*)this)->print1(vout, func);
7180}
7181
7182/// Get pointers to operands. at last one operand should be a number
7183/// o1 will be pointer to the number
7184
7185inline bool cexpr_t::get_1num_op(cexpr_t **o1, cexpr_t **o2)
7186{
7187 if ( x->op == cot_num )
7188 {
7189 *o1 = x;
7190 *o2 = y;
7191 }
7192 else
7193 {
7194 if ( y->op != cot_num )
7195 return false;
7196 *o1 = y;
7197 *o2 = x;
7198 }
7199 return true;
7200}
7201
7202inline bool cexpr_t::get_1num_op(const cexpr_t **o1, const cexpr_t **o2) const
7203{
7204 return CONST_CAST(cexpr_t*)(this)->get_1num_op(
7205 CONST_CAST(cexpr_t**)(o1),
7206 CONST_CAST(cexpr_t**)(o2));
7207}
7208
7209inline citem_locator_t::citem_locator_t(const citem_t *i)
7210 : ea(i != nullptr ? i->ea : BADADDR),
7211 op(i != nullptr ? i->op : cot_empty)
7212{
7213}
7214
7216{
7217 cinsn_t *block = (cinsn_t *)parents.back();
7218 QASSERT(50600, block->op == cit_block);
7219 return block->cblock;
7220}
7221
7222const char *hexapi get_ctype_name(ctype_t op);
7223qstring hexapi create_field_name(const tinfo_t &type, uval_t offset=BADADDR);
7224typedef void *hexdsp_t(int code, ...);
7225const int64 HEXRAYS_API_MAGIC = 0x00DEC0DE00000003LL;
7226
7227/// Decompiler events.
7228/// Use install_hexrays_callback() to install a handler for decompiler events.
7229/// When the possible return value is not specified, your callback
7230/// must return zero.
7231enum hexrays_event_t ENUM_SIZE(int)
7232{
7233 // When a function is decompiled, the following events occur:
7234
7235 hxe_flowchart, ///< Flowchart has been generated.
7236 ///< \param fc (qflow_chart_t *)
7237
7238 hxe_stkpnts, ///< SP change points have been calculated.
7239 ///< \param mba (mba_t *)
7240 ///< \param stkpnts (stkpnts_t *)
7241 ///< return \ref MERR_ code
7242
7243 hxe_prolog, ///< Prolog analysis has been finished.
7244 ///< \param mba (mba_t *)
7245 ///< \param fc (qflow_chart_t *)
7246 ///< \param reachable_blocks (bitset_t *)
7247 ///< \param decomp_flags (int)
7248 ///< return \ref MERR_ code
7249
7250 hxe_microcode, ///< Microcode has been generated.
7251 ///< \param mba (mba_t *)
7252 ///< return \ref MERR_ code
7253
7254 hxe_preoptimized, ///< Microcode has been preoptimized.
7255 ///< \param mba (mba_t *)
7256 ///< return \ref MERR_ code
7257
7258 hxe_locopt, ///< Basic block level optimization has been finished.
7259 ///< \param mba (mba_t *)
7260 ///< return \ref MERR_ code
7261
7262 hxe_prealloc, ///< Local variables: preallocation step begins.
7263 ///< \param mba (mba_t *)
7264 ///< This event may occur several times.
7265 ///< Should return: 1 if modified microcode
7266 ///< Negative values are \ref MERR_ error codes
7267
7268 hxe_glbopt, ///< Global optimization has been finished.
7269 ///< If microcode is modified, MERR_LOOP must be returned.
7270 ///< It will cause a complete restart of the optimization.
7271 ///< \param mba (mba_t *)
7272 ///< return \ref MERR_ code
7273
7274 hxe_structural, ///< Structural analysis has been finished.
7275 ///< \param ct (control_graph_t *)
7276
7277 hxe_maturity, ///< Ctree maturity level is being changed.
7278 ///< \param cfunc (cfunc_t *)
7279 ///< \param new_maturity (ctree_maturity_t)
7280
7281 hxe_interr, ///< Internal error has occurred.
7282 ///< \param errcode (int )
7283
7284 hxe_combine, ///< Trying to combine instructions of basic block.
7285 ///< \param blk (mblock_t *)
7286 ///< \param insn (minsn_t *)
7287 ///< Should return: 1 if combined the current instruction
7288 ///< with a preceding one
7289
7290 hxe_print_func, ///< Printing ctree and generating text.
7291 ///< \param cfunc (cfunc_t *)
7292 ///< \param vp (vc_printer_t *)
7293 ///< Returns: 1 if text has been generated by the plugin
7294 ///< It is forbidden to modify ctree at this event.
7295
7296 hxe_func_printed, ///< Function text has been generated. Plugins may
7297 ///< modify the text in \ref cfunc_t::sv.
7298 ///< The text uses regular color codes (see lines.hpp)
7299 ///< COLOR_ADDR is used to store pointers to ctree items.
7300 ///< \param cfunc (cfunc_t *)
7301
7302 hxe_resolve_stkaddrs, ///< The optimizer is about to resolve stack addresses.
7303 ///< \param mba (mba_t *)
7304
7305 hxe_build_callinfo, ///< Analyzing a call instruction.
7306 ///< \param blk (mblock_t *) blk->tail is the call.
7307 ///< \param type (tinfo_t *) buffer for the output type.
7308 ///< \param callinfo (mcallinfo_t **) prepared callinfo.
7309 ///< The plugin should either specify the function type,
7310 ///< either allocate and return a new mcallinfo_t object.
7311
7312 // User interface related events:
7313
7314 hxe_open_pseudocode=100,
7315 ///< New pseudocode view has been opened.
7316 ///< \param vu (vdui_t *)
7317
7318 hxe_switch_pseudocode,///< Existing pseudocode view has been reloaded
7319 ///< with a new function. Its text has not been
7320 ///< refreshed yet, only cfunc and mba pointers are ready.
7321 ///< \param vu (vdui_t *)
7322
7323 hxe_refresh_pseudocode,///< Existing pseudocode text has been refreshed.
7324 ///< Adding/removing pseudocode lines is forbidden in this event.
7325 ///< \param vu (vdui_t *)
7326 ///< See also hxe_text_ready, which happens earlier
7327
7328 hxe_close_pseudocode, ///< Pseudocode view is being closed.
7329 ///< \param vu (vdui_t *)
7330
7331 hxe_keyboard, ///< Keyboard has been hit.
7332 ///< \param vu (vdui_t *)
7333 ///< \param key_code (int) VK_...
7334 ///< \param shift_state (int)
7335 ///< Should return: 1 if the event has been handled
7336
7337 hxe_right_click, ///< Mouse right click.
7338 ///< Use hxe_populating_popup instead, in case you
7339 ///< want to add items in the popup menu.
7340 ///< \param vu (vdui_t *)
7341
7342 hxe_double_click, ///< Mouse double click.
7343 ///< \param vu (vdui_t *)
7344 ///< \param shift_state (int)
7345 ///< Should return: 1 if the event has been handled
7346
7347 hxe_curpos, ///< Current cursor position has been changed.
7348 ///< (for example, by left-clicking or using keyboard)\n
7349 ///< \param vu (vdui_t *)
7350
7351 hxe_create_hint, ///< Create a hint for the current item.
7352 ///< \see ui_get_custom_viewer_hint
7353 ///< \param vu (vdui_t *)
7354 ///< \param hint (qstring *)
7355 ///< \param important_lines (int *)
7356 ///< Possible return values:
7357 ///< \retval 0 continue collecting hints with other subscribers
7358 ///< \retval 1 stop collecting hints
7359
7360 hxe_text_ready, ///< Decompiled text is ready.
7361 ///< \param vu (vdui_t *)
7362 ///< This event can be used to modify the output text (sv).
7363 ///< Obsolete. Please use hxe_func_printed instead.
7364
7365 hxe_populating_popup, ///< Populating popup menu. We can add menu items now.
7366 ///< \param widget (TWidget *)
7367 ///< \param popup_handle (TPopupMenu *)
7368 ///< \param vu (vdui_t *)
7369
7370 lxe_lvar_name_changed,///< Local variable got renamed.
7371 ///< \param vu (vdui_t *)
7372 ///< \param v (lvar_t *)
7373 ///< \param name (const char *)
7374 ///< \param is_user_name (bool)
7375 ///< Please note that it is possible to read/write
7376 ///< user settings for lvars directly from the idb.
7377
7378 lxe_lvar_type_changed,///< Local variable type got changed.
7379 ///< \param vu (vdui_t *)
7380 ///< \param v (lvar_t *)
7381 ///< \param tinfo (const tinfo_t *)
7382 ///< Please note that it is possible to read/write
7383 ///< user settings for lvars directly from the idb.
7384
7385 lxe_lvar_cmt_changed, ///< Local variable comment got changed.
7386 ///< \param vu (vdui_t *)
7387 ///< \param v (lvar_t *)
7388 ///< \param cmt (const char *)
7389 ///< Please note that it is possible to read/write
7390 ///< user settings for lvars directly from the idb.
7391
7392 lxe_lvar_mapping_changed, ///< Local variable mapping got changed.
7393 ///< \param vu (vdui_t *)
7394 ///< \param from (lvar_t *)
7395 ///< \param to (lvar_t *)
7396 ///< Please note that it is possible to read/write
7397 ///< user settings for lvars directly from the idb.
7398
7399 hxe_cmt_changed, ///< Comment got changed.
7400 ///< \param cfunc (cfunc_t *)
7401 ///< \param loc (const treeloc_t *)
7402 ///< \param cmt (const char *)
7403};
7404
7405/// Handler of decompiler events.
7406/// \param ud user data. the value specified at the handler installation time
7407/// is passed here.
7408/// \param event decompiler event code
7409/// \param va additional arguments
7410/// \return as a rule the callback must return 0 unless specified otherwise
7411/// in the event description.
7412
7413typedef ssize_t idaapi hexrays_cb_t(void *ud, hexrays_event_t event, va_list va);
7414
7415
7416/// Install handler for decompiler events.
7417/// \param callback handler to install
7418/// \param ud user data. this pointer will be passed to your handler by the decompiler.
7419/// \return false if failed
7420
7421bool hexapi install_hexrays_callback(hexrays_cb_t *callback, void *ud);
7422
7423/// Uninstall handler for decompiler events.
7424/// \param callback handler to uninstall
7425/// \param ud user data. if nullptr, all handler corresponding to \c callback is uninstalled.
7426/// if not nullptr, only the callback instance with the specified \c ud value is uninstalled.
7427/// \return number of uninstalled handlers.
7428
7429int hexapi remove_hexrays_callback(hexrays_cb_t *callback, void *ud);
7430
7431
7432//---------------------------------------------------------------------------
7433/// \defgroup vdui User interface definitions
7434//@{
7435
7436/// Type of the input device.
7437/// How the user command has been invoked
7439{
7440 USE_KEYBOARD = 0, ///< Keyboard
7441 USE_MOUSE = 1, ///< Mouse
7442};
7443//@}
7444
7445//---------------------------------------------------------------------------
7446/// Cursor position in the output text (pseudocode).
7448{
7449 int lnnum; ///< Line number
7450 int x; ///< x coordinate of the cursor within the window
7451 int y; ///< y coordinate of the cursor within the window
7452 /// Is the cursor in the variable/type declaration area?
7453 /// \param hdrlines Number of lines of the declaration area
7454 bool in_ctree(int hdrlines) const { return lnnum >= hdrlines; }
7455 /// Comparison operators
7457 {
7458 if ( lnnum < r.lnnum ) return -1;
7459 if ( lnnum > r.lnnum ) return 1;
7460 if ( x < r.x ) return -1;
7461 if ( x > r.x ) return 1;
7462 return 0;
7463 }
7464 ctext_position_t(int _lnnum=-1, int _x=0, int _y=0)
7465 : lnnum(_lnnum), x(_x), y(_y) {}
7466};
7467
7468/// Navigation history item.
7469/// Holds information about interactive decompilation history.
7470/// Currently this is not saved in the database.
7472{
7473 ea_t ea; ///< The entry address of the decompiled function
7474 ea_t end; ///< BADADDR-decompile function; otherwise end of the range
7475 history_item_t(ea_t _ea=BADADDR, int _lnnum=-1, int _x=0, int _y=0)
7476 : ctext_position_t(_lnnum, _x, _y), ea(_ea), end(BADADDR) {}
7477 history_item_t(ea_t _ea, const ctext_position_t &p)
7478 : ctext_position_t(p), ea(_ea), end(BADADDR) {}
7479};
7480
7481/// Navigation history.
7482typedef qstack<history_item_t> history_t;
7483
7484/// Comment types
7485typedef int cmt_type_t;
7486const cmt_type_t
7487 CMT_NONE = 0x0000, ///< No comment is possible
7488 CMT_TAIL = 0x0001, ///< Indented comment
7489 CMT_BLOCK1 = 0x0002, ///< Anterioir block comment
7490 CMT_BLOCK2 = 0x0004, ///< Posterior block comment
7491 CMT_LVAR = 0x0008, ///< Local variable comment
7492 CMT_FUNC = 0x0010, ///< Function comment
7493 CMT_ALL = 0x001F; ///< All comments
7494
7495//---------------------------------------------------------------------------
7496/// Information about the pseudocode window
7498{
7499 int flags; ///< \ref VDUI_
7500/// \defgroup VDUI_ Properties of pseudocode window
7501/// Used in vdui_t::flags
7502//@{
7503#define VDUI_VISIBLE 0x0001 ///< is visible?
7504#define VDUI_VALID 0x0002 ///< is valid?
7505//@}
7506
7507 /// Is the pseudocode window visible?
7508 /// if not, it might be invisible or destroyed
7509 bool visible(void) const { return (flags & VDUI_VISIBLE) != 0; }
7510 /// Does the pseudocode window contain valid code?
7511 /// It can become invalid if the function type gets changed in IDA.
7512 bool valid(void) const { return (flags & VDUI_VALID) != 0; }
7513 /// Does the pseudocode window contain valid code?
7514 /// We lock windows before modifying them, to avoid recursion due to
7515 /// the events generated by the IDA kernel.
7516 /// \retval true The window is locked and may have stale info
7517 bool locked(void) const { return cfunc != nullptr && cfunc->locked(); }
7518 void set_visible(bool v) { setflag(flags, VDUI_VISIBLE, v); }
7519 void set_valid(bool v) { setflag(flags, VDUI_VALID, v); }
7520 bool hexapi set_locked(bool v); // returns true-redecompiled
7521
7522 int view_idx; ///< pseudocode window index (0..)
7523 TWidget *ct; ///< pseudocode view
7524 TWidget *toplevel;
7525
7526 mba_t *mba; ///< pointer to underlying microcode
7527 cfuncptr_t cfunc; ///< pointer to function object
7528 merror_t last_code; ///< result of the last user action. See \ref MERR_
7529
7530 // The following fields are valid after get_current_item():
7531 ctext_position_t cpos; ///< Current ctext position
7532 ctree_item_t head; ///< First ctree item on the current line (for block comments)
7533 ctree_item_t item; ///< Current ctree item
7534 ctree_item_t tail; ///< Tail ctree item on the current line (for indented comments)
7535
7536 vdui_t(void); // do not create your own vdui_t objects
7537
7538 /// Refresh pseudocode window.
7539 /// This is the highest level refresh function.
7540 /// It causes the most profound refresh possible and can lead to redecompilation
7541 /// of the current function. Please consider using refresh_ctext()
7542 /// if you need a more superficial refresh.
7543 /// \param redo_mba true means to redecompile the current function\n
7544 /// false means to rebuild ctree without regenerating microcode
7545 /// \sa refresh_ctext()
7546 void hexapi refresh_view(bool redo_mba);
7547
7548 /// Refresh pseudocode window.
7549 /// This function refreshes the pseudocode window by regenerating its text
7550 /// from cfunc_t. Instead of this function use refresh_func_ctext(), which
7551 /// refreshes all pseudocode windows for the function.
7552 /// \sa refresh_view(), refresh_func_ctext()
7553 void hexapi refresh_ctext(bool activate=true); // deprecated
7554
7555 /// Display the specified pseudocode.
7556 /// This function replaces the pseudocode window contents with the
7557 /// specified cfunc_t.
7558 /// \param f pointer to the function to display.
7559 /// \param activate should the pseudocode window get focus?
7560 void hexapi switch_to(cfuncptr_t f, bool activate);
7561
7562 /// Is the current item a statement?
7563 //// \return false if the cursor is in the local variable/type declaration area\n
7564 /// true if the cursor is in the statement area
7565 bool in_ctree(void) const { return cpos.in_ctree(cfunc->hdrlines); }
7566
7567 /// Get current number.
7568 /// If the current item is a number, return pointer to it.
7569 /// \return nullptr if the current item is not a number
7570 /// This function returns non-null for the cases of a 'switch' statement
7571 /// Also, if the current item is a casted number, then this function will succeed.
7573
7574 /// Get current label.
7575 /// If there is a label under the cursor, return its number.
7576 /// \return -1 if there is no label under the cursor.
7577 /// prereq: get_current_item() has been called
7578 int hexapi get_current_label(void);
7579
7580 /// Clear the pseudocode window.
7581 /// It deletes the current function and microcode.
7582 void hexapi clear(void);
7583
7584 /// Refresh the current position.
7585 /// This function refreshes the \ref cpos field.
7586 /// \return false if failed
7587 /// \param idv keyboard or mouse
7589
7590 /// Get current item.
7591 /// This function refreshes the \ref cpos, \ref item, \ref tail fields.
7592 /// \return false if failed
7593 /// \param idv keyboard or mouse
7594 /// \sa cfunc_t::get_line_item()
7596
7597 /// Rename local variable.
7598 /// This function displays a dialog box and allows the user to rename a local variable.
7599 /// \return false if failed or cancelled
7600 /// \param v pointer to local variable
7601 bool hexapi ui_rename_lvar(lvar_t *v);
7602
7603 /// Rename local variable.
7604 /// This function permanently renames a local variable.
7605 /// \return false if failed
7606 /// \param v pointer to local variable
7607 /// \param name new variable name
7608 /// \param is_user_name use true to save the new name into the database.
7609 /// use false to delete the saved name.
7610 /// \sa ::rename_lvar()
7611 bool hexapi rename_lvar(lvar_t *v, const char *name, bool is_user_name);
7612
7613 /// Set type of a function call
7614 /// This function displays a dialog box and allows the user to change
7615 /// the type of a function call
7616 /// \return false if failed or cancelled
7617 /// \param e pointer to call expression
7618 bool hexapi ui_set_call_type(const cexpr_t *e);
7619
7620 /// Set local variable type.
7621 /// This function displays a dialog box and allows the user to change
7622 /// the type of a local variable.
7623 /// \return false if failed or cancelled
7624 /// \param v pointer to local variable
7626
7627 /// Set local variable type.
7628 /// This function permanently sets a local variable type and clears
7629 /// NOPTR flag if it was set before by function 'set_noptr_lvar'
7630 /// \return false if failed
7631 /// \param v pointer to local variable
7632 /// \param type new variable type
7633 bool hexapi set_lvar_type(lvar_t *v, const tinfo_t &type);
7634
7635 /// Inform that local variable should have a non-pointer type
7636 /// This function permanently sets a corresponding variable flag (NOPTR)
7637 /// and removes type if it was set before by function 'set_lvar_type'
7638 /// \return false if failed
7639 /// \param v pointer to local variable
7640 bool hexapi set_noptr_lvar(lvar_t *v);
7641
7642 /// Set local variable comment.
7643 /// This function displays a dialog box and allows the user to edit
7644 /// the comment of a local variable.
7645 /// \return false if failed or cancelled
7646 /// \param v pointer to local variable
7648
7649 /// Set local variable comment.
7650 /// This function permanently sets a variable comment.
7651 /// \return false if failed
7652 /// \param v pointer to local variable
7653 /// \param cmt new comment
7654 bool hexapi set_lvar_cmt(lvar_t *v, const char *cmt);
7655
7656 /// Map a local variable to another.
7657 /// This function displays a variable list and allows the user to select mapping.
7658 /// \return false if failed or cancelled
7659 /// \param v pointer to local variable
7660 bool hexapi ui_map_lvar(lvar_t *v);
7661
7662 /// Unmap a local variable.
7663 /// This function displays list of variables mapped to the specified variable
7664 /// and allows the user to select a variable to unmap.
7665 /// \return false if failed or cancelled
7666 /// \param v pointer to local variable
7667 bool hexapi ui_unmap_lvar(lvar_t *v);
7668
7669 /// Map a local variable to another.
7670 /// This function permanently maps one lvar to another.
7671 /// All occurrences of the mapped variable are replaced by the new variable
7672 /// \return false if failed
7673 /// \param from the variable being mapped
7674 /// \param to the variable to map to. if nullptr, unmaps the variable
7675 bool hexapi map_lvar(lvar_t *from, lvar_t *to);
7676
7677 /// Set structure field type.
7678 /// This function displays a dialog box and allows the user to change
7679 /// the type of a structure field.
7680 /// \return false if failed or cancelled
7681 /// \param sptr pointer to structure
7682 /// \param mptr pointer to structure member
7683 bool hexapi set_strmem_type(struc_t *sptr, member_t *mptr);
7684
7685 /// Rename structure field.
7686 /// This function displays a dialog box and allows the user to rename
7687 /// a structure field.
7688 /// \return false if failed or cancelled
7689 /// \param sptr pointer to structure
7690 /// \param mptr pointer to structure member
7691 bool hexapi rename_strmem(struc_t *sptr, member_t *mptr);
7692
7693 /// Set global item type.
7694 /// This function displays a dialog box and allows the user to change
7695 /// the type of a global item (data or function).
7696 /// \return false if failed or cancelled
7697 /// \param ea address of the global item
7698 bool hexapi set_global_type(ea_t ea);
7699
7700 /// Rename global item.
7701 /// This function displays a dialog box and allows the user to rename
7702 /// a global item (data or function).
7703 /// \return false if failed or cancelled
7704 /// \param ea address of the global item
7705 bool hexapi rename_global(ea_t ea);
7706
7707 /// Rename a label.
7708 /// This function displays a dialog box and allows the user to rename
7709 /// a statement label.
7710 /// \return false if failed or cancelled
7711 /// \param label label number
7712 bool hexapi rename_label(int label);
7713
7714 /// Process the Enter key.
7715 /// This function jumps to the definition of the item under the cursor.
7716 /// If the current item is a function, it will be decompiled.
7717 /// If the current item is a global data, its disassemly text will be displayed.
7718 /// \return false if failed
7719 /// \param idv what cursor must be used, the keyboard or the mouse
7720 /// \param omflags OM_NEWWIN: new pseudocode window will open, 0: reuse the existing window
7721 bool hexapi jump_enter(input_device_t idv, int omflags);
7722
7723 /// Jump to disassembly.
7724 /// This function jumps to the address in the disassembly window
7725 /// which corresponds to the current item. The current item is determined
7726 /// based on the current keyboard cursor position.
7727 /// \return false if failed
7728 bool hexapi ctree_to_disasm(void);
7729
7730 /// Check if the specified line can have a comment.
7731 /// Due to the coordinate system for comments:
7732 /// (https://www.hex-rays.com/blog/coordinate-system-for-hex-rays)
7733 /// some function lines cannot have comments. This function checks if a
7734 /// comment can be attached to the specified line.
7735 /// \return possible comment types
7736 /// \param lnnum line number (0 based)
7737 /// \param cmttype comment types to check
7738 cmt_type_t hexapi calc_cmt_type(size_t lnnum, cmt_type_t cmttype) const;
7739
7740 /// Edit an indented comment.
7741 /// This function displays a dialog box and allows the user to edit
7742 /// the comment for the specified ctree location.
7743 /// \return false if failed or cancelled
7744 /// \param loc comment location
7745 bool hexapi edit_cmt(const treeloc_t &loc);
7746
7747 /// Edit a function comment.
7748 /// This function displays a dialog box and allows the user to edit
7749 /// the function comment.
7750 /// \return false if failed or cancelled
7751 bool hexapi edit_func_cmt(void);
7752
7753 /// Delete all orphan comments.
7754 /// Delete all orphan comments and refresh the screen.
7755 /// \return true
7756 bool hexapi del_orphan_cmts(void);
7757
7758 /// Change number base.
7759 /// This function changes the current number representation.
7760 /// \return false if failed
7761 /// \param base number radix (10 or 16)\n
7762 /// 0 means a character constant
7763 bool hexapi set_num_radix(int base);
7764
7765 /// Convert number to symbolic constant.
7766 /// This function displays a dialog box and allows the user to select
7767 /// a symbolic constant to represent the number.
7768 /// \return false if failed or cancelled
7769 bool hexapi set_num_enum(void);
7770
7771 /// Convert number to structure field offset.
7772 /// Currently not implemented.
7773 /// \return false if failed or cancelled
7774 bool hexapi set_num_stroff(void);
7775
7776 /// Negate a number.
7777 /// This function negates the current number.
7778 /// \return false if failed.
7779 bool hexapi invert_sign(void);
7780
7781 /// Bitwise negate a number.
7782 /// This function inverts all bits of the current number.
7783 /// \return false if failed.
7784 bool hexapi invert_bits(void);
7785
7786 /// Collapse/uncollapse item.
7787 /// This function collapses the current item.
7788 /// \return false if failed.
7789 bool hexapi collapse_item(bool hide);
7790
7791 /// Collapse/uncollapse local variable declarations.
7792 /// \return false if failed.
7793 bool hexapi collapse_lvars(bool hide);
7794
7795 /// Split/unsplit item.
7796 /// This function splits the current assignment expression.
7797 /// \return false if failed.
7798 bool hexapi split_item(bool split);
7799
7800};
7801
7802//---------------------------------------------------------------------------
7803/// Select UDT for the operands using "Select offsets" widget
7804
7805/// Operand represention
7807{
7808 qstring text; ///< any text for the column "Operand" of widget
7809 uval_t offset; ///< operand offset, will be used when calculating the UDT path
7810 bool operator==(const ui_stroff_op_t &r) const
7811 {
7812 return text == r.text && offset == r.offset;
7813 }
7814 bool operator!=(const ui_stroff_op_t &r) const { return !(*this == r); }
7815};
7816DECLARE_TYPE_AS_MOVABLE(ui_stroff_op_t);
7817typedef qvector<ui_stroff_op_t> ui_stroff_ops_t;
7818
7819/// Callback to apply the selection
7820/// \return success
7822{
7823 /// \param opnum operand ordinal number, see below
7824 /// \param path path describing the union selection, maybe empty
7825 /// \param top_tif tinfo_t of the selected toplevel UDT
7826 /// \param spath selected path
7827 virtual bool idaapi apply(size_t opnum, const intvec_t &path, const tinfo_t &top_tif, const char *spath) = 0;
7828};
7829
7830/// Select UDT
7831/// \param udts list of UDT tinfo_t for the selection,
7832/// if nullptr or empty then UDTs from the "Local types" will be used
7833/// \param ops operands
7834/// \param applicator callback will be called to apply the selection for every operand
7836 const qvector<tinfo_t> *udts,
7837 const ui_stroff_ops_t &ops,
7838 ui_stroff_applicator_t &applicator);
7839
7840
7841
7842
7843//--------------------------------------------------------------------------
7844// PUBLIC HEX-RAYS API
7845//--------------------------------------------------------------------------
7846
7847/// Hex-Rays decompiler dispatcher.
7848/// All interaction with the decompiler is carried out by the intermediary of this dispatcher.
7849typedef void *hexdsp_t(int code, ...);
7850
7851#ifndef SWIG
7852//==========================================================================
7853// PLEASE REMOVE 'hexdsp' VARIABLE, IT IS OUT OF USE NOW
7854//==========================================================================
7855extern int hexdsp;
7856#endif
7857
7858/// API call numbers
7860{
7861 hx_user_numforms_begin,
7862 hx_user_numforms_end,
7863 hx_user_numforms_next,
7864 hx_user_numforms_prev,
7865 hx_user_numforms_first,
7866 hx_user_numforms_second,
7867 hx_user_numforms_find,
7868 hx_user_numforms_insert,
7869 hx_user_numforms_erase,
7870 hx_user_numforms_clear,
7871 hx_user_numforms_size,
7872 hx_user_numforms_free,
7873 hx_user_numforms_new,
7874 hx_lvar_mapping_begin,
7875 hx_lvar_mapping_end,
7876 hx_lvar_mapping_next,
7877 hx_lvar_mapping_prev,
7878 hx_lvar_mapping_first,
7879 hx_lvar_mapping_second,
7880 hx_lvar_mapping_find,
7881 hx_lvar_mapping_insert,
7882 hx_lvar_mapping_erase,
7883 hx_lvar_mapping_clear,
7884 hx_lvar_mapping_size,
7885 hx_lvar_mapping_free,
7886 hx_lvar_mapping_new,
7887 hx_udcall_map_begin,
7888 hx_udcall_map_end,
7889 hx_udcall_map_next,
7890 hx_udcall_map_prev,
7891 hx_udcall_map_first,
7892 hx_udcall_map_second,
7893 hx_udcall_map_find,
7894 hx_udcall_map_insert,
7895 hx_udcall_map_erase,
7896 hx_udcall_map_clear,
7897 hx_udcall_map_size,
7898 hx_udcall_map_free,
7899 hx_udcall_map_new,
7900 hx_user_cmts_begin,
7901 hx_user_cmts_end,
7902 hx_user_cmts_next,
7903 hx_user_cmts_prev,
7904 hx_user_cmts_first,
7905 hx_user_cmts_second,
7906 hx_user_cmts_find,
7907 hx_user_cmts_insert,
7908 hx_user_cmts_erase,
7909 hx_user_cmts_clear,
7910 hx_user_cmts_size,
7911 hx_user_cmts_free,
7912 hx_user_cmts_new,
7913 hx_user_iflags_begin,
7914 hx_user_iflags_end,
7915 hx_user_iflags_next,
7916 hx_user_iflags_prev,
7917 hx_user_iflags_first,
7918 hx_user_iflags_second,
7919 hx_user_iflags_find,
7920 hx_user_iflags_insert,
7921 hx_user_iflags_erase,
7922 hx_user_iflags_clear,
7923 hx_user_iflags_size,
7924 hx_user_iflags_free,
7925 hx_user_iflags_new,
7926 hx_user_unions_begin,
7927 hx_user_unions_end,
7928 hx_user_unions_next,
7929 hx_user_unions_prev,
7930 hx_user_unions_first,
7931 hx_user_unions_second,
7932 hx_user_unions_find,
7933 hx_user_unions_insert,
7934 hx_user_unions_erase,
7935 hx_user_unions_clear,
7936 hx_user_unions_size,
7937 hx_user_unions_free,
7938 hx_user_unions_new,
7939 hx_user_labels_begin,
7940 hx_user_labels_end,
7941 hx_user_labels_next,
7942 hx_user_labels_prev,
7943 hx_user_labels_first,
7944 hx_user_labels_second,
7945 hx_user_labels_find,
7946 hx_user_labels_insert,
7947 hx_user_labels_erase,
7948 hx_user_labels_clear,
7949 hx_user_labels_size,
7950 hx_user_labels_free,
7951 hx_user_labels_new,
7952 hx_eamap_begin,
7953 hx_eamap_end,
7954 hx_eamap_next,
7955 hx_eamap_prev,
7956 hx_eamap_first,
7957 hx_eamap_second,
7958 hx_eamap_find,
7959 hx_eamap_insert,
7960 hx_eamap_erase,
7961 hx_eamap_clear,
7962 hx_eamap_size,
7963 hx_eamap_free,
7964 hx_eamap_new,
7965 hx_boundaries_begin,
7966 hx_boundaries_end,
7967 hx_boundaries_next,
7968 hx_boundaries_prev,
7969 hx_boundaries_first,
7970 hx_boundaries_second,
7971 hx_boundaries_find,
7972 hx_boundaries_insert,
7973 hx_boundaries_erase,
7974 hx_boundaries_clear,
7975 hx_boundaries_size,
7976 hx_boundaries_free,
7977 hx_boundaries_new,
7978 hx_block_chains_begin,
7979 hx_block_chains_end,
7980 hx_block_chains_next,
7981 hx_block_chains_prev,
7982 hx_block_chains_get,
7983 hx_block_chains_find,
7984 hx_block_chains_insert,
7985 hx_block_chains_erase,
7986 hx_block_chains_clear,
7987 hx_block_chains_size,
7988 hx_block_chains_free,
7989 hx_block_chains_new,
7990 hx_valrng_t_clear,
7991 hx_valrng_t_copy,
7992 hx_valrng_t_assign,
7993 hx_valrng_t_compare,
7994 hx_valrng_t_set_eq,
7995 hx_valrng_t_set_cmp,
7996 hx_valrng_t_reduce_size,
7997 hx_valrng_t_intersect_with,
7998 hx_valrng_t_unite_with,
7999 hx_valrng_t_inverse,
8000 hx_valrng_t_has,
8001 hx_valrng_t_print,
8002 hx_valrng_t_dstr,
8003 hx_valrng_t_cvt_to_single_value,
8004 hx_valrng_t_cvt_to_cmp,
8005 hx_get_merror_desc,
8006 hx_reg2mreg,
8007 hx_mreg2reg,
8008 hx_install_optinsn_handler,
8009 hx_remove_optinsn_handler,
8010 hx_install_optblock_handler,
8011 hx_remove_optblock_handler,
8012 hx_must_mcode_close_block,
8013 hx_is_mcode_propagatable,
8014 hx_negate_mcode_relation,
8015 hx_swap_mcode_relation,
8016 hx_get_signed_mcode,
8017 hx_get_unsigned_mcode,
8018 hx_mcode_modifies_d,
8019 hx_operand_locator_t_compare,
8020 hx_vd_printer_t_print,
8021 hx_file_printer_t_print,
8022 hx_qstring_printer_t_print,
8023 hx_dstr,
8024 hx_is_type_correct,
8025 hx_is_small_udt,
8026 hx_is_nonbool_type,
8027 hx_is_bool_type,
8028 hx_partial_type_num,
8029 hx_get_float_type,
8030 hx_get_int_type_by_width_and_sign,
8031 hx_get_unk_type,
8032 hx_dummy_ptrtype,
8033 hx_get_member_type,
8034 hx_make_pointer,
8035 hx_create_typedef,
8036 hx_get_type,
8037 hx_set_type,
8038 hx_vdloc_t_dstr,
8039 hx_vdloc_t_compare,
8040 hx_vdloc_t_is_aliasable,
8041 hx_print_vdloc,
8042 hx_arglocs_overlap,
8043 hx_lvar_locator_t_compare,
8044 hx_lvar_locator_t_dstr,
8045 hx_lvar_t_dstr,
8046 hx_lvar_t_is_promoted_arg,
8047 hx_lvar_t_accepts_type,
8048 hx_lvar_t_set_lvar_type,
8049 hx_lvar_t_set_width,
8050 hx_lvar_t_append_list_,
8051 hx_lvars_t_find_stkvar,
8052 hx_lvars_t_find,
8053 hx_lvars_t_find_lvar,
8054 hx_restore_user_lvar_settings,
8055 hx_save_user_lvar_settings,
8056 hx_modify_user_lvars,
8057 hx_restore_user_defined_calls,
8058 hx_save_user_defined_calls,
8059 hx_parse_user_call,
8060 hx_convert_to_user_call,
8061 hx_install_microcode_filter,
8062 hx_udc_filter_t_init,
8063 hx_udc_filter_t_apply,
8064 hx_bitset_t_bitset_t,
8065 hx_bitset_t_copy,
8066 hx_bitset_t_add,
8067 hx_bitset_t_add_,
8068 hx_bitset_t_add__,
8069 hx_bitset_t_sub,
8070 hx_bitset_t_sub_,
8071 hx_bitset_t_sub__,
8072 hx_bitset_t_cut_at,
8073 hx_bitset_t_shift_down,
8074 hx_bitset_t_has,
8075 hx_bitset_t_has_all,
8076 hx_bitset_t_has_any,
8077 hx_bitset_t_dstr,
8078 hx_bitset_t_empty,
8079 hx_bitset_t_count,
8080 hx_bitset_t_count_,
8081 hx_bitset_t_last,
8082 hx_bitset_t_fill_with_ones,
8083 hx_bitset_t_has_common,
8084 hx_bitset_t_intersect,
8085 hx_bitset_t_is_subset_of,
8086 hx_bitset_t_compare,
8087 hx_bitset_t_goup,
8088 hx_ivl_t_dstr,
8089 hx_ivl_t_compare,
8090 hx_ivlset_t_add,
8091 hx_ivlset_t_add_,
8092 hx_ivlset_t_addmasked,
8093 hx_ivlset_t_sub,
8094 hx_ivlset_t_sub_,
8095 hx_ivlset_t_has_common,
8096 hx_ivlset_t_print,
8097 hx_ivlset_t_dstr,
8098 hx_ivlset_t_count,
8099 hx_ivlset_t_has_common_,
8100 hx_ivlset_t_contains,
8101 hx_ivlset_t_includes,
8102 hx_ivlset_t_intersect,
8103 hx_ivlset_t_compare,
8104 hx_get_mreg_name,
8105 hx_rlist_t_print,
8106 hx_rlist_t_dstr,
8107 hx_mlist_t_addmem,
8108 hx_mlist_t_print,
8109 hx_mlist_t_dstr,
8110 hx_mlist_t_compare,
8111 hx_lvar_ref_t_compare,
8112 hx_lvar_ref_t_var,
8113 hx_stkvar_ref_t_compare,
8114 hx_stkvar_ref_t_get_stkvar,
8115 hx_fnumber_t_print,
8116 hx_fnumber_t_dstr,
8117 hx_mop_t_copy,
8118 hx_mop_t_assign,
8119 hx_mop_t_swap,
8120 hx_mop_t_erase,
8121 hx_mop_t_print,
8122 hx_mop_t_dstr,
8123 hx_mop_t_create_from_mlist,
8124 hx_mop_t_create_from_ivlset,
8125 hx_mop_t_create_from_vdloc,
8126 hx_mop_t_create_from_scattered_vdloc,
8127 hx_mop_t_create_from_insn,
8128 hx_mop_t_make_number,
8129 hx_mop_t_make_fpnum,
8130 hx_mop_t_make_reg_pair,
8131 hx_mop_t_make_helper,
8132 hx_mop_t_is_bit_reg,
8133 hx_mop_t_may_use_aliased_memory,
8134 hx_mop_t_is01,
8135 hx_mop_t_is_sign_extended_from,
8136 hx_mop_t_is_zero_extended_from,
8137 hx_mop_t_equal_mops,
8138 hx_mop_t_lexcompare,
8139 hx_mop_t_for_all_ops,
8140 hx_mop_t_for_all_scattered_submops,
8141 hx_mop_t_is_constant,
8142 hx_mop_t_get_stkoff,
8143 hx_mop_t_make_low_half,
8144 hx_mop_t_make_high_half,
8145 hx_mop_t_make_first_half,
8146 hx_mop_t_make_second_half,
8147 hx_mop_t_shift_mop,
8148 hx_mop_t_change_size,
8149 hx_mop_t_preserve_side_effects,
8150 hx_mop_t_apply_ld_mcode,
8151 hx_mcallarg_t_print,
8152 hx_mcallarg_t_dstr,
8153 hx_mcallarg_t_set_regarg,
8154 hx_mcallinfo_t_lexcompare,
8155 hx_mcallinfo_t_set_type,
8156 hx_mcallinfo_t_get_type,
8157 hx_mcallinfo_t_print,
8158 hx_mcallinfo_t_dstr,
8159 hx_mcases_t_compare,
8160 hx_mcases_t_print,
8161 hx_mcases_t_dstr,
8162 hx_vivl_t_extend_to_cover,
8163 hx_vivl_t_intersect,
8164 hx_vivl_t_print,
8165 hx_vivl_t_dstr,
8166 hx_chain_t_print,
8167 hx_chain_t_dstr,
8168 hx_chain_t_append_list_,
8169 hx_block_chains_t_get_chain,
8170 hx_block_chains_t_print,
8171 hx_block_chains_t_dstr,
8172 hx_graph_chains_t_for_all_chains,
8173 hx_graph_chains_t_release,
8174 hx_minsn_t_init,
8175 hx_minsn_t_copy,
8176 hx_minsn_t_swap,
8177 hx_minsn_t_print,
8178 hx_minsn_t_dstr,
8179 hx_minsn_t_setaddr,
8180 hx_minsn_t_optimize_subtree,
8181 hx_minsn_t_for_all_ops,
8182 hx_minsn_t_for_all_insns,
8183 hx_minsn_t__make_nop,
8184 hx_minsn_t_equal_insns,
8185 hx_minsn_t_lexcompare,
8186 hx_minsn_t_is_noret_call,
8187 hx_minsn_t_is_helper,
8188 hx_minsn_t_find_call,
8189 hx_minsn_t_has_side_effects,
8190 hx_minsn_t_find_opcode,
8191 hx_minsn_t_find_ins_op,
8192 hx_minsn_t_find_num_op,
8193 hx_minsn_t_modifies_d,
8194 hx_minsn_t_is_between,
8195 hx_minsn_t_may_use_aliased_memory,
8196 hx_getf_reginsn,
8197 hx_getb_reginsn,
8198 hx_mblock_t_init,
8199 hx_mblock_t_print,
8200 hx_mblock_t_dump,
8201 hx_mblock_t_vdump_block,
8202 hx_mblock_t_insert_into_block,
8203 hx_mblock_t_remove_from_block,
8204 hx_mblock_t_for_all_insns,
8205 hx_mblock_t_for_all_ops,
8206 hx_mblock_t_for_all_uses,
8207 hx_mblock_t_optimize_insn,
8208 hx_mblock_t_optimize_block,
8209 hx_mblock_t_build_lists,
8210 hx_mblock_t_append_use_list,
8211 hx_mblock_t_append_def_list,
8212 hx_mblock_t_build_use_list,
8213 hx_mblock_t_build_def_list,
8214 hx_mblock_t_find_first_use,
8215 hx_mblock_t_find_redefinition,
8216 hx_mblock_t_is_rhs_redefined,
8217 hx_mblock_t_find_access,
8218 hx_mblock_t_get_valranges,
8219 hx_mba_t_idaloc2vd,
8220 hx_mba_t_vd2idaloc,
8221 hx_mba_t_term,
8222 hx_mba_t_optimize_local,
8223 hx_mba_t_build_graph,
8224 hx_mba_t_get_graph,
8225 hx_mba_t_analyze_calls,
8226 hx_mba_t_optimize_global,
8227 hx_mba_t_alloc_lvars,
8228 hx_mba_t_dump,
8229 hx_mba_t_vdump_mba,
8230 hx_mba_t_print,
8231 hx_mba_t_verify,
8232 hx_mba_t_mark_chains_dirty,
8233 hx_mba_t_insert_block,
8234 hx_mba_t_remove_block,
8235 hx_mba_t_remove_empty_and_unreachable_blocks,
8236 hx_mba_t_combine_blocks,
8237 hx_mba_t_for_all_ops,
8238 hx_mba_t_for_all_insns,
8239 hx_mba_t_for_all_topinsns,
8240 hx_mba_t_find_mop,
8241 hx_mba_t_arg,
8242 hx_mba_t_serialize,
8243 hx_mba_t_deserialize,
8244 hx_mbl_graph_t_is_accessed_globally,
8245 hx_mbl_graph_t_get_ud,
8246 hx_mbl_graph_t_get_du,
8247 hx_codegen_t_emit,
8248 hx_codegen_t_emit_,
8249 hx_is_kreg,
8250 hx_get_temp_regs,
8251 hx_get_hexrays_version,
8252 hx_open_pseudocode,
8253 hx_close_pseudocode,
8254 hx_get_widget_vdui,
8255 hx_decompile_many,
8256 hx_hexrays_failure_t_desc,
8257 hx_send_database,
8258 hx_gco_info_t_append_to_list,
8259 hx_get_current_operand,
8260 hx_remitem,
8261 hx_negated_relation,
8262 hx_swapped_relation,
8263 hx_get_op_signness,
8264 hx_asgop,
8265 hx_asgop_revert,
8266 hx_cnumber_t_print,
8267 hx_cnumber_t_value,
8268 hx_cnumber_t_assign,
8269 hx_cnumber_t_compare,
8270 hx_var_ref_t_compare,
8271 hx_ctree_visitor_t_apply_to,
8272 hx_ctree_visitor_t_apply_to_exprs,
8273 hx_ctree_parentee_t_recalc_parent_types,
8274 hx_cfunc_parentee_t_calc_rvalue_type,
8275 hx_citem_locator_t_compare,
8276 hx_citem_t_contains_expr,
8277 hx_citem_t_contains_label,
8278 hx_citem_t_find_parent_of,
8279 hx_citem_t_find_closest_addr,
8280 hx_cexpr_t_assign,
8281 hx_cexpr_t_compare,
8282 hx_cexpr_t_replace_by,
8283 hx_cexpr_t_cleanup,
8284 hx_cexpr_t_put_number,
8285 hx_cexpr_t_print1,
8286 hx_cexpr_t_calc_type,
8287 hx_cexpr_t_equal_effect,
8288 hx_cexpr_t_is_child_of,
8289 hx_cexpr_t_contains_operator,
8290 hx_cexpr_t_get_high_nbit_bound,
8291 hx_cexpr_t_get_low_nbit_bound,
8292 hx_cexpr_t_requires_lvalue,
8293 hx_cexpr_t_has_side_effects,
8294 hx_cif_t_assign,
8295 hx_cif_t_compare,
8296 hx_cloop_t_assign,
8297 hx_cfor_t_compare,
8298 hx_cwhile_t_compare,
8299 hx_cdo_t_compare,
8300 hx_creturn_t_compare,
8301 hx_cgoto_t_compare,
8302 hx_casm_t_compare,
8303 hx_cinsn_t_assign,
8304 hx_cinsn_t_compare,
8305 hx_cinsn_t_replace_by,
8306 hx_cinsn_t_cleanup,
8307 hx_cinsn_t_new_insn,
8308 hx_cinsn_t_create_if,
8309 hx_cinsn_t_print,
8310 hx_cinsn_t_print1,
8311 hx_cinsn_t_is_ordinary_flow,
8312 hx_cinsn_t_contains_insn,
8313 hx_cinsn_t_collect_free_breaks,
8314 hx_cinsn_t_collect_free_continues,
8315 hx_cblock_t_compare,
8316 hx_carglist_t_compare,
8317 hx_ccase_t_compare,
8318 hx_ccases_t_compare,
8319 hx_cswitch_t_compare,
8320 hx_ctree_item_t_get_memptr,
8321 hx_ctree_item_t_get_lvar,
8322 hx_ctree_item_t_get_ea,
8323 hx_ctree_item_t_get_label_num,
8324 hx_lnot,
8325 hx_new_block,
8326 hx_vcreate_helper,
8327 hx_vcall_helper,
8328 hx_make_num,
8329 hx_make_ref,
8330 hx_dereference,
8331 hx_save_user_labels,
8332 hx_save_user_cmts,
8333 hx_save_user_numforms,
8334 hx_save_user_iflags,
8335 hx_save_user_unions,
8336 hx_restore_user_labels,
8337 hx_restore_user_cmts,
8338 hx_restore_user_numforms,
8339 hx_restore_user_iflags,
8340 hx_restore_user_unions,
8341 hx_cfunc_t_build_c_tree,
8342 hx_cfunc_t_verify,
8343 hx_cfunc_t_print_dcl,
8344 hx_cfunc_t_print_func,
8345 hx_cfunc_t_get_func_type,
8346 hx_cfunc_t_get_lvars,
8347 hx_cfunc_t_get_stkoff_delta,
8348 hx_cfunc_t_find_label,
8349 hx_cfunc_t_remove_unused_labels,
8350 hx_cfunc_t_get_user_cmt,
8351 hx_cfunc_t_set_user_cmt,
8352 hx_cfunc_t_get_user_iflags,
8353 hx_cfunc_t_set_user_iflags,
8354 hx_cfunc_t_has_orphan_cmts,
8355 hx_cfunc_t_del_orphan_cmts,
8356 hx_cfunc_t_get_user_union_selection,
8357 hx_cfunc_t_set_user_union_selection,
8358 hx_cfunc_t_get_line_item,
8359 hx_cfunc_t_get_warnings,
8360 hx_cfunc_t_get_eamap,
8361 hx_cfunc_t_get_boundaries,
8362 hx_cfunc_t_get_pseudocode,
8363 hx_cfunc_t_gather_derefs,
8364 hx_cfunc_t_find_item_coords,
8365 hx_cfunc_t_cleanup,
8366 hx_decompile,
8367 hx_gen_microcode,
8368 hx_mark_cfunc_dirty,
8369 hx_clear_cached_cfuncs,
8370 hx_has_cached_cfunc,
8371 hx_get_ctype_name,
8372 hx_create_field_name,
8373 hx_install_hexrays_callback,
8374 hx_remove_hexrays_callback,
8375 hx_vdui_t_set_locked,
8376 hx_vdui_t_refresh_view,
8377 hx_vdui_t_refresh_ctext,
8378 hx_vdui_t_switch_to,
8379 hx_vdui_t_get_number,
8380 hx_vdui_t_get_current_label,
8381 hx_vdui_t_clear,
8382 hx_vdui_t_refresh_cpos,
8383 hx_vdui_t_get_current_item,
8384 hx_vdui_t_ui_rename_lvar,
8385 hx_vdui_t_rename_lvar,
8386 hx_vdui_t_ui_set_call_type,
8387 hx_vdui_t_ui_set_lvar_type,
8388 hx_vdui_t_set_lvar_type,
8389 hx_vdui_t_ui_edit_lvar_cmt,
8390 hx_vdui_t_set_lvar_cmt,
8391 hx_vdui_t_ui_map_lvar,
8392 hx_vdui_t_ui_unmap_lvar,
8393 hx_vdui_t_map_lvar,
8394 hx_vdui_t_set_strmem_type,
8395 hx_vdui_t_rename_strmem,
8396 hx_vdui_t_set_global_type,
8397 hx_vdui_t_rename_global,
8398 hx_vdui_t_rename_label,
8399 hx_vdui_t_jump_enter,
8400 hx_vdui_t_ctree_to_disasm,
8401 hx_vdui_t_calc_cmt_type,
8402 hx_vdui_t_edit_cmt,
8403 hx_vdui_t_edit_func_cmt,
8404 hx_vdui_t_del_orphan_cmts,
8405 hx_vdui_t_set_num_radix,
8406 hx_vdui_t_set_num_enum,
8407 hx_vdui_t_set_num_stroff,
8408 hx_vdui_t_invert_sign,
8409 hx_vdui_t_invert_bits,
8410 hx_vdui_t_collapse_item,
8411 hx_vdui_t_collapse_lvars,
8412 hx_vdui_t_split_item,
8413 hx_hexrays_alloc,
8414 hx_hexrays_free,
8415 hx_vdui_t_set_noptr_lvar,
8416 hx_select_udt_by_offset,
8417 hx_mblock_t_get_valranges_,
8418 hx_cfunc_t_refresh_func_ctext,
8419 hx_checkout_hexrays_license,
8420 hx_mba_t_copy_block,
8421 hx_mblock_t_optimize_useless_jump,
8422 hx_mblock_t_get_reginsn_qty,
8423 hx_modify_user_lvar_info,
8424 hx_cdg_insn_iterator_t_next,
8425 hx_restore_user_labels2,
8426 hx_save_user_labels2,
8427 hx_mba_ranges_t_range_contains,
8428 hx_close_hexrays_waitbox,
8429 hx_mba_t_map_fict_ea,
8430 hx_mba_t_alloc_fict_ea,
8431 hx_mba_t_alloc_kreg,
8432 hx_mba_t_free_kreg,
8433 hx_mba_t_idaloc2vd_,
8434 hx_mba_t_vd2idaloc_,
8435 hx_bitset_t_fill_gaps,
8436 hx_cfunc_t_save_user_labels,
8437 hx_cfunc_t_save_user_cmts,
8438 hx_cfunc_t_save_user_numforms,
8439 hx_cfunc_t_save_user_iflags,
8440 hx_cfunc_t_save_user_unions,
8441 hx_minsn_t_set_combined,
8442 hx_mba_t_save_snapshot,
8443 hx_create_cfunc,
8444 hx_mba_t_set_maturity,
8445 hx_rename_lvar,
8446 hx_locate_lvar,
8447 hx_mba_t_create_helper_call,
8448 hx_lvar_t_append_list,
8449 hx_chain_t_append_list,
8450 hx_udc_filter_t_cleanup,
8451 hx_mba_t_get_curfunc,
8452 hx_mop_t__make_gvar,
8453 hx_mop_t_make_gvar,
8454 hx_cexpr_t_maybe_ptr,
8455};
8456
8457typedef size_t iterator_word;
8458
8459//--------------------------------------------------------------------------
8460/// Check that your plugin is compatible with hex-rays decompiler.
8461/// This function must be called before calling any other decompiler function.
8462/// \param flags reserved, must be 0
8463/// \return true if the decompiler exists and is compatible with your plugin
8464inline bool init_hexrays_plugin(int flags=0)
8465{
8466 hexdsp_t *dummy;
8467 return callui(ui_broadcast, HEXRAYS_API_MAGIC, &dummy, flags).i == (HEXRAYS_API_MAGIC >> 32);
8468}
8469
8470//--------------------------------------------------------------------------
8471/// Stop working with hex-rays decompiler.
8473{
8474}
8475
8476
8477//-------------------------------------------------------------------------
8479{
8480 iterator_word x;
8481 bool operator==(const user_numforms_iterator_t &p) const { return x == p.x; }
8482 bool operator!=(const user_numforms_iterator_t &p) const { return x != p.x; }
8483};
8484
8485//-------------------------------------------------------------------------
8486/// Get reference to the current map key
8488{
8489 return *(operand_locator_t *)HEXDSP(hx_user_numforms_first, &p);
8490}
8491
8492//-------------------------------------------------------------------------
8493/// Get reference to the current map value
8495{
8496 return *(number_format_t *)HEXDSP(hx_user_numforms_second, &p);
8497}
8498
8499//-------------------------------------------------------------------------
8500/// Find the specified key in user_numforms_t
8502{
8504 HEXDSP(hx_user_numforms_find, &p, map, &key);
8505 return p;
8506}
8507
8508//-------------------------------------------------------------------------
8509/// Insert new (operand_locator_t, number_format_t) pair into user_numforms_t
8511{
8513 HEXDSP(hx_user_numforms_insert, &p, map, &key, &val);
8514 return p;
8515}
8516
8517//-------------------------------------------------------------------------
8518/// Get iterator pointing to the beginning of user_numforms_t
8520{
8522 HEXDSP(hx_user_numforms_begin, &p, map);
8523 return p;
8524}
8525
8526//-------------------------------------------------------------------------
8527/// Get iterator pointing to the end of user_numforms_t
8529{
8531 HEXDSP(hx_user_numforms_end, &p, map);
8532 return p;
8533}
8534
8535//-------------------------------------------------------------------------
8536/// Move to the next element
8538{
8539 HEXDSP(hx_user_numforms_next, &p);
8540 return p;
8541}
8542
8543//-------------------------------------------------------------------------
8544/// Move to the previous element
8546{
8547 HEXDSP(hx_user_numforms_prev, &p);
8548 return p;
8549}
8550
8551//-------------------------------------------------------------------------
8552/// Erase current element from user_numforms_t
8554{
8555 HEXDSP(hx_user_numforms_erase, map, &p);
8556}
8557
8558//-------------------------------------------------------------------------
8559/// Clear user_numforms_t
8561{
8562 HEXDSP(hx_user_numforms_clear, map);
8563}
8564
8565//-------------------------------------------------------------------------
8566/// Get size of user_numforms_t
8568{
8569 return (size_t)HEXDSP(hx_user_numforms_size, map);
8570}
8571
8572//-------------------------------------------------------------------------
8573/// Delete user_numforms_t instance
8575{
8576 HEXDSP(hx_user_numforms_free, map);
8577}
8578
8579//-------------------------------------------------------------------------
8580/// Create a new user_numforms_t instance
8582{
8583 return (user_numforms_t *)HEXDSP(hx_user_numforms_new);
8584}
8585
8586//-------------------------------------------------------------------------
8588{
8589 iterator_word x;
8590 bool operator==(const lvar_mapping_iterator_t &p) const { return x == p.x; }
8591 bool operator!=(const lvar_mapping_iterator_t &p) const { return x != p.x; }
8592};
8593
8594//-------------------------------------------------------------------------
8595/// Get reference to the current map key
8597{
8598 return *(lvar_locator_t *)HEXDSP(hx_lvar_mapping_first, &p);
8599}
8600
8601//-------------------------------------------------------------------------
8602/// Get reference to the current map value
8604{
8605 return *(lvar_locator_t *)HEXDSP(hx_lvar_mapping_second, &p);
8606}
8607
8608//-------------------------------------------------------------------------
8609/// Find the specified key in lvar_mapping_t
8611{
8613 HEXDSP(hx_lvar_mapping_find, &p, map, &key);
8614 return p;
8615}
8616
8617//-------------------------------------------------------------------------
8618/// Insert new (lvar_locator_t, lvar_locator_t) pair into lvar_mapping_t
8620{
8622 HEXDSP(hx_lvar_mapping_insert, &p, map, &key, &val);
8623 return p;
8624}
8625
8626//-------------------------------------------------------------------------
8627/// Get iterator pointing to the beginning of lvar_mapping_t
8629{
8631 HEXDSP(hx_lvar_mapping_begin, &p, map);
8632 return p;
8633}
8634
8635//-------------------------------------------------------------------------
8636/// Get iterator pointing to the end of lvar_mapping_t
8638{
8640 HEXDSP(hx_lvar_mapping_end, &p, map);
8641 return p;
8642}
8643
8644//-------------------------------------------------------------------------
8645/// Move to the next element
8647{
8648 HEXDSP(hx_lvar_mapping_next, &p);
8649 return p;
8650}
8651
8652//-------------------------------------------------------------------------
8653/// Move to the previous element
8655{
8656 HEXDSP(hx_lvar_mapping_prev, &p);
8657 return p;
8658}
8659
8660//-------------------------------------------------------------------------
8661/// Erase current element from lvar_mapping_t
8663{
8664 HEXDSP(hx_lvar_mapping_erase, map, &p);
8665}
8666
8667//-------------------------------------------------------------------------
8668/// Clear lvar_mapping_t
8670{
8671 HEXDSP(hx_lvar_mapping_clear, map);
8672}
8673
8674//-------------------------------------------------------------------------
8675/// Get size of lvar_mapping_t
8677{
8678 return (size_t)HEXDSP(hx_lvar_mapping_size, map);
8679}
8680
8681//-------------------------------------------------------------------------
8682/// Delete lvar_mapping_t instance
8684{
8685 HEXDSP(hx_lvar_mapping_free, map);
8686}
8687
8688//-------------------------------------------------------------------------
8689/// Create a new lvar_mapping_t instance
8691{
8692 return (lvar_mapping_t *)HEXDSP(hx_lvar_mapping_new);
8693}
8694
8695//-------------------------------------------------------------------------
8697{
8698 iterator_word x;
8699 bool operator==(const udcall_map_iterator_t &p) const { return x == p.x; }
8700 bool operator!=(const udcall_map_iterator_t &p) const { return x != p.x; }
8701};
8702
8703//-------------------------------------------------------------------------
8704/// Get reference to the current map key
8706{
8707 return *(ea_t *)HEXDSP(hx_udcall_map_first, &p);
8708}
8709
8710//-------------------------------------------------------------------------
8711/// Get reference to the current map value
8713{
8714 return *(udcall_t *)HEXDSP(hx_udcall_map_second, &p);
8715}
8716
8717//-------------------------------------------------------------------------
8718/// Find the specified key in udcall_map_t
8719inline udcall_map_iterator_t udcall_map_find(const udcall_map_t *map, const ea_t &key)
8720{
8722 HEXDSP(hx_udcall_map_find, &p, map, &key);
8723 return p;
8724}
8725
8726//-------------------------------------------------------------------------
8727/// Insert new (ea_t, udcall_t) pair into udcall_map_t
8728inline udcall_map_iterator_t udcall_map_insert(udcall_map_t *map, const ea_t &key, const udcall_t &val)
8729{
8731 HEXDSP(hx_udcall_map_insert, &p, map, &key, &val);
8732 return p;
8733}
8734
8735//-------------------------------------------------------------------------
8736/// Get iterator pointing to the beginning of udcall_map_t
8737inline udcall_map_iterator_t udcall_map_begin(const udcall_map_t *map)
8738{
8740 HEXDSP(hx_udcall_map_begin, &p, map);
8741 return p;
8742}
8743
8744//-------------------------------------------------------------------------
8745/// Get iterator pointing to the end of udcall_map_t
8746inline udcall_map_iterator_t udcall_map_end(const udcall_map_t *map)
8747{
8749 HEXDSP(hx_udcall_map_end, &p, map);
8750 return p;
8751}
8752
8753//-------------------------------------------------------------------------
8754/// Move to the next element
8756{
8757 HEXDSP(hx_udcall_map_next, &p);
8758 return p;
8759}
8760
8761//-------------------------------------------------------------------------
8762/// Move to the previous element
8764{
8765 HEXDSP(hx_udcall_map_prev, &p);
8766 return p;
8767}
8768
8769//-------------------------------------------------------------------------
8770/// Erase current element from udcall_map_t
8771inline void udcall_map_erase(udcall_map_t *map, udcall_map_iterator_t p)
8772{
8773 HEXDSP(hx_udcall_map_erase, map, &p);
8774}
8775
8776//-------------------------------------------------------------------------
8777/// Clear udcall_map_t
8778inline void udcall_map_clear(udcall_map_t *map)
8779{
8780 HEXDSP(hx_udcall_map_clear, map);
8781}
8782
8783//-------------------------------------------------------------------------
8784/// Get size of udcall_map_t
8785inline size_t udcall_map_size(udcall_map_t *map)
8786{
8787 return (size_t)HEXDSP(hx_udcall_map_size, map);
8788}
8789
8790//-------------------------------------------------------------------------
8791/// Delete udcall_map_t instance
8792inline void udcall_map_free(udcall_map_t *map)
8793{
8794 HEXDSP(hx_udcall_map_free, map);
8795}
8796
8797//-------------------------------------------------------------------------
8798/// Create a new udcall_map_t instance
8799inline udcall_map_t *udcall_map_new()
8800{
8801 return (udcall_map_t *)HEXDSP(hx_udcall_map_new);
8802}
8803
8804//-------------------------------------------------------------------------
8806{
8807 iterator_word x;
8808 bool operator==(const user_cmts_iterator_t &p) const { return x == p.x; }
8809 bool operator!=(const user_cmts_iterator_t &p) const { return x != p.x; }
8810};
8811
8812//-------------------------------------------------------------------------
8813/// Get reference to the current map key
8815{
8816 return *(treeloc_t *)HEXDSP(hx_user_cmts_first, &p);
8817}
8818
8819//-------------------------------------------------------------------------
8820/// Get reference to the current map value
8822{
8823 return *(citem_cmt_t *)HEXDSP(hx_user_cmts_second, &p);
8824}
8825
8826//-------------------------------------------------------------------------
8827/// Find the specified key in user_cmts_t
8829{
8831 HEXDSP(hx_user_cmts_find, &p, map, &key);
8832 return p;
8833}
8834
8835//-------------------------------------------------------------------------
8836/// Insert new (treeloc_t, citem_cmt_t) pair into user_cmts_t
8838{
8840 HEXDSP(hx_user_cmts_insert, &p, map, &key, &val);
8841 return p;
8842}
8843
8844//-------------------------------------------------------------------------
8845/// Get iterator pointing to the beginning of user_cmts_t
8847{
8849 HEXDSP(hx_user_cmts_begin, &p, map);
8850 return p;
8851}
8852
8853//-------------------------------------------------------------------------
8854/// Get iterator pointing to the end of user_cmts_t
8856{
8858 HEXDSP(hx_user_cmts_end, &p, map);
8859 return p;
8860}
8861
8862//-------------------------------------------------------------------------
8863/// Move to the next element
8865{
8866 HEXDSP(hx_user_cmts_next, &p);
8867 return p;
8868}
8869
8870//-------------------------------------------------------------------------
8871/// Move to the previous element
8873{
8874 HEXDSP(hx_user_cmts_prev, &p);
8875 return p;
8876}
8877
8878//-------------------------------------------------------------------------
8879/// Erase current element from user_cmts_t
8881{
8882 HEXDSP(hx_user_cmts_erase, map, &p);
8883}
8884
8885//-------------------------------------------------------------------------
8886/// Clear user_cmts_t
8888{
8889 HEXDSP(hx_user_cmts_clear, map);
8890}
8891
8892//-------------------------------------------------------------------------
8893/// Get size of user_cmts_t
8894inline size_t user_cmts_size(user_cmts_t *map)
8895{
8896 return (size_t)HEXDSP(hx_user_cmts_size, map);
8897}
8898
8899//-------------------------------------------------------------------------
8900/// Delete user_cmts_t instance
8902{
8903 HEXDSP(hx_user_cmts_free, map);
8904}
8905
8906//-------------------------------------------------------------------------
8907/// Create a new user_cmts_t instance
8909{
8910 return (user_cmts_t *)HEXDSP(hx_user_cmts_new);
8911}
8912
8913//-------------------------------------------------------------------------
8915{
8916 iterator_word x;
8917 bool operator==(const user_iflags_iterator_t &p) const { return x == p.x; }
8918 bool operator!=(const user_iflags_iterator_t &p) const { return x != p.x; }
8919};
8920
8921//-------------------------------------------------------------------------
8922/// Get reference to the current map key
8924{
8925 return *(citem_locator_t *)HEXDSP(hx_user_iflags_first, &p);
8926}
8927
8928//-------------------------------------------------------------------------
8929/// Get reference to the current map value
8931{
8932 return *(int32 *)HEXDSP(hx_user_iflags_second, &p);
8933}
8934
8935//-------------------------------------------------------------------------
8936/// Find the specified key in user_iflags_t
8937inline user_iflags_iterator_t user_iflags_find(const user_iflags_t *map, const citem_locator_t &key)
8938{
8940 HEXDSP(hx_user_iflags_find, &p, map, &key);
8941 return p;
8942}
8943
8944//-------------------------------------------------------------------------
8945/// Insert new (citem_locator_t, int32) pair into user_iflags_t
8946inline user_iflags_iterator_t user_iflags_insert(user_iflags_t *map, const citem_locator_t &key, const int32 &val)
8947{
8949 HEXDSP(hx_user_iflags_insert, &p, map, &key, &val);
8950 return p;
8951}
8952
8953//-------------------------------------------------------------------------
8954/// Get iterator pointing to the beginning of user_iflags_t
8955inline user_iflags_iterator_t user_iflags_begin(const user_iflags_t *map)
8956{
8958 HEXDSP(hx_user_iflags_begin, &p, map);
8959 return p;
8960}
8961
8962//-------------------------------------------------------------------------
8963/// Get iterator pointing to the end of user_iflags_t
8964inline user_iflags_iterator_t user_iflags_end(const user_iflags_t *map)
8965{
8967 HEXDSP(hx_user_iflags_end, &p, map);
8968 return p;
8969}
8970
8971//-------------------------------------------------------------------------
8972/// Move to the next element
8974{
8975 HEXDSP(hx_user_iflags_next, &p);
8976 return p;
8977}
8978
8979//-------------------------------------------------------------------------
8980/// Move to the previous element
8982{
8983 HEXDSP(hx_user_iflags_prev, &p);
8984 return p;
8985}
8986
8987//-------------------------------------------------------------------------
8988/// Erase current element from user_iflags_t
8989inline void user_iflags_erase(user_iflags_t *map, user_iflags_iterator_t p)
8990{
8991 HEXDSP(hx_user_iflags_erase, map, &p);
8992}
8993
8994//-------------------------------------------------------------------------
8995/// Clear user_iflags_t
8996inline void user_iflags_clear(user_iflags_t *map)
8997{
8998 HEXDSP(hx_user_iflags_clear, map);
8999}
9000
9001//-------------------------------------------------------------------------
9002/// Get size of user_iflags_t
9003inline size_t user_iflags_size(user_iflags_t *map)
9004{
9005 return (size_t)HEXDSP(hx_user_iflags_size, map);
9006}
9007
9008//-------------------------------------------------------------------------
9009/// Delete user_iflags_t instance
9010inline void user_iflags_free(user_iflags_t *map)
9011{
9012 HEXDSP(hx_user_iflags_free, map);
9013}
9014
9015//-------------------------------------------------------------------------
9016/// Create a new user_iflags_t instance
9017inline user_iflags_t *user_iflags_new()
9018{
9019 return (user_iflags_t *)HEXDSP(hx_user_iflags_new);
9020}
9021
9022//-------------------------------------------------------------------------
9024{
9025 iterator_word x;
9026 bool operator==(const user_unions_iterator_t &p) const { return x == p.x; }
9027 bool operator!=(const user_unions_iterator_t &p) const { return x != p.x; }
9028};
9029
9030//-------------------------------------------------------------------------
9031/// Get reference to the current map key
9033{
9034 return *(ea_t *)HEXDSP(hx_user_unions_first, &p);
9035}
9036
9037//-------------------------------------------------------------------------
9038/// Get reference to the current map value
9040{
9041 return *(intvec_t *)HEXDSP(hx_user_unions_second, &p);
9042}
9043
9044//-------------------------------------------------------------------------
9045/// Find the specified key in user_unions_t
9046inline user_unions_iterator_t user_unions_find(const user_unions_t *map, const ea_t &key)
9047{
9049 HEXDSP(hx_user_unions_find, &p, map, &key);
9050 return p;
9051}
9052
9053//-------------------------------------------------------------------------
9054/// Insert new (ea_t, intvec_t) pair into user_unions_t
9055inline user_unions_iterator_t user_unions_insert(user_unions_t *map, const ea_t &key, const intvec_t &val)
9056{
9058 HEXDSP(hx_user_unions_insert, &p, map, &key, &val);
9059 return p;
9060}
9061
9062//-------------------------------------------------------------------------
9063/// Get iterator pointing to the beginning of user_unions_t
9064inline user_unions_iterator_t user_unions_begin(const user_unions_t *map)
9065{
9067 HEXDSP(hx_user_unions_begin, &p, map);
9068 return p;
9069}
9070
9071//-------------------------------------------------------------------------
9072/// Get iterator pointing to the end of user_unions_t
9073inline user_unions_iterator_t user_unions_end(const user_unions_t *map)
9074{
9076 HEXDSP(hx_user_unions_end, &p, map);
9077 return p;
9078}
9079
9080//-------------------------------------------------------------------------
9081/// Move to the next element
9083{
9084 HEXDSP(hx_user_unions_next, &p);
9085 return p;
9086}
9087
9088//-------------------------------------------------------------------------
9089/// Move to the previous element
9091{
9092 HEXDSP(hx_user_unions_prev, &p);
9093 return p;
9094}
9095
9096//-------------------------------------------------------------------------
9097/// Erase current element from user_unions_t
9098inline void user_unions_erase(user_unions_t *map, user_unions_iterator_t p)
9099{
9100 HEXDSP(hx_user_unions_erase, map, &p);
9101}
9102
9103//-------------------------------------------------------------------------
9104/// Clear user_unions_t
9105inline void user_unions_clear(user_unions_t *map)
9106{
9107 HEXDSP(hx_user_unions_clear, map);
9108}
9109
9110//-------------------------------------------------------------------------
9111/// Get size of user_unions_t
9112inline size_t user_unions_size(user_unions_t *map)
9113{
9114 return (size_t)HEXDSP(hx_user_unions_size, map);
9115}
9116
9117//-------------------------------------------------------------------------
9118/// Delete user_unions_t instance
9119inline void user_unions_free(user_unions_t *map)
9120{
9121 HEXDSP(hx_user_unions_free, map);
9122}
9123
9124//-------------------------------------------------------------------------
9125/// Create a new user_unions_t instance
9126inline user_unions_t *user_unions_new()
9127{
9128 return (user_unions_t *)HEXDSP(hx_user_unions_new);
9129}
9130
9131//-------------------------------------------------------------------------
9133{
9134 iterator_word x;
9135 bool operator==(const user_labels_iterator_t &p) const { return x == p.x; }
9136 bool operator!=(const user_labels_iterator_t &p) const { return x != p.x; }
9137};
9138
9139//-------------------------------------------------------------------------
9140/// Get reference to the current map key
9142{
9143 return *(int *)HEXDSP(hx_user_labels_first, &p);
9144}
9145
9146//-------------------------------------------------------------------------
9147/// Get reference to the current map value
9149{
9150 return *(qstring *)HEXDSP(hx_user_labels_second, &p);
9151}
9152
9153//-------------------------------------------------------------------------
9154/// Find the specified key in user_labels_t
9156{
9158 HEXDSP(hx_user_labels_find, &p, map, &key);
9159 return p;
9160}
9161
9162//-------------------------------------------------------------------------
9163/// Insert new (int, qstring) pair into user_labels_t
9164inline user_labels_iterator_t user_labels_insert(user_labels_t *map, const int &key, const qstring &val)
9165{
9167 HEXDSP(hx_user_labels_insert, &p, map, &key, &val);
9168 return p;
9169}
9170
9171//-------------------------------------------------------------------------
9172/// Get iterator pointing to the beginning of user_labels_t
9174{
9176 HEXDSP(hx_user_labels_begin, &p, map);
9177 return p;
9178}
9179
9180//-------------------------------------------------------------------------
9181/// Get iterator pointing to the end of user_labels_t
9183{
9185 HEXDSP(hx_user_labels_end, &p, map);
9186 return p;
9187}
9188
9189//-------------------------------------------------------------------------
9190/// Move to the next element
9192{
9193 HEXDSP(hx_user_labels_next, &p);
9194 return p;
9195}
9196
9197//-------------------------------------------------------------------------
9198/// Move to the previous element
9200{
9201 HEXDSP(hx_user_labels_prev, &p);
9202 return p;
9203}
9204
9205//-------------------------------------------------------------------------
9206/// Erase current element from user_labels_t
9208{
9209 HEXDSP(hx_user_labels_erase, map, &p);
9210}
9211
9212//-------------------------------------------------------------------------
9213/// Clear user_labels_t
9215{
9216 HEXDSP(hx_user_labels_clear, map);
9217}
9218
9219//-------------------------------------------------------------------------
9220/// Get size of user_labels_t
9222{
9223 return (size_t)HEXDSP(hx_user_labels_size, map);
9224}
9225
9226//-------------------------------------------------------------------------
9227/// Delete user_labels_t instance
9229{
9230 HEXDSP(hx_user_labels_free, map);
9231}
9232
9233//-------------------------------------------------------------------------
9234/// Create a new user_labels_t instance
9236{
9237 return (user_labels_t *)HEXDSP(hx_user_labels_new);
9238}
9239
9240//-------------------------------------------------------------------------
9242{
9243 iterator_word x;
9244 bool operator==(const eamap_iterator_t &p) const { return x == p.x; }
9245 bool operator!=(const eamap_iterator_t &p) const { return x != p.x; }
9246};
9247
9248//-------------------------------------------------------------------------
9249/// Get reference to the current map key
9250inline ea_t const &eamap_first(eamap_iterator_t p)
9251{
9252 return *(ea_t *)HEXDSP(hx_eamap_first, &p);
9253}
9254
9255//-------------------------------------------------------------------------
9256/// Get reference to the current map value
9258{
9259 return *(cinsnptrvec_t *)HEXDSP(hx_eamap_second, &p);
9260}
9261
9262//-------------------------------------------------------------------------
9263/// Find the specified key in eamap_t
9264inline eamap_iterator_t eamap_find(const eamap_t *map, const ea_t &key)
9265{
9267 HEXDSP(hx_eamap_find, &p, map, &key);
9268 return p;
9269}
9270
9271//-------------------------------------------------------------------------
9272/// Insert new (ea_t, cinsnptrvec_t) pair into eamap_t
9273inline eamap_iterator_t eamap_insert(eamap_t *map, const ea_t &key, const cinsnptrvec_t &val)
9274{
9276 HEXDSP(hx_eamap_insert, &p, map, &key, &val);
9277 return p;
9278}
9279
9280//-------------------------------------------------------------------------
9281/// Get iterator pointing to the beginning of eamap_t
9282inline eamap_iterator_t eamap_begin(const eamap_t *map)
9283{
9285 HEXDSP(hx_eamap_begin, &p, map);
9286 return p;
9287}
9288
9289//-------------------------------------------------------------------------
9290/// Get iterator pointing to the end of eamap_t
9291inline eamap_iterator_t eamap_end(const eamap_t *map)
9292{
9294 HEXDSP(hx_eamap_end, &p, map);
9295 return p;
9296}
9297
9298//-------------------------------------------------------------------------
9299/// Move to the next element
9301{
9302 HEXDSP(hx_eamap_next, &p);
9303 return p;
9304}
9305
9306//-------------------------------------------------------------------------
9307/// Move to the previous element
9309{
9310 HEXDSP(hx_eamap_prev, &p);
9311 return p;
9312}
9313
9314//-------------------------------------------------------------------------
9315/// Erase current element from eamap_t
9316inline void eamap_erase(eamap_t *map, eamap_iterator_t p)
9317{
9318 HEXDSP(hx_eamap_erase, map, &p);
9319}
9320
9321//-------------------------------------------------------------------------
9322/// Clear eamap_t
9323inline void eamap_clear(eamap_t *map)
9324{
9325 HEXDSP(hx_eamap_clear, map);
9326}
9327
9328//-------------------------------------------------------------------------
9329/// Get size of eamap_t
9330inline size_t eamap_size(eamap_t *map)
9331{
9332 return (size_t)HEXDSP(hx_eamap_size, map);
9333}
9334
9335//-------------------------------------------------------------------------
9336/// Delete eamap_t instance
9337inline void eamap_free(eamap_t *map)
9338{
9339 HEXDSP(hx_eamap_free, map);
9340}
9341
9342//-------------------------------------------------------------------------
9343/// Create a new eamap_t instance
9344inline eamap_t *eamap_new()
9345{
9346 return (eamap_t *)HEXDSP(hx_eamap_new);
9347}
9348
9349//-------------------------------------------------------------------------
9351{
9352 iterator_word x;
9353 bool operator==(const boundaries_iterator_t &p) const { return x == p.x; }
9354 bool operator!=(const boundaries_iterator_t &p) const { return x != p.x; }
9355};
9356
9357//-------------------------------------------------------------------------
9358/// Get reference to the current map key
9360{
9361 return *(cinsn_t * *)HEXDSP(hx_boundaries_first, &p);
9362}
9363
9364//-------------------------------------------------------------------------
9365/// Get reference to the current map value
9367{
9368 return *(rangeset_t *)HEXDSP(hx_boundaries_second, &p);
9369}
9370
9371//-------------------------------------------------------------------------
9372/// Find the specified key in boundaries_t
9373inline boundaries_iterator_t boundaries_find(const boundaries_t *map, const cinsn_t * &key)
9374{
9376 HEXDSP(hx_boundaries_find, &p, map, &key);
9377 return p;
9378}
9379
9380//-------------------------------------------------------------------------
9381/// Insert new (cinsn_t *, rangeset_t) pair into boundaries_t
9382inline boundaries_iterator_t boundaries_insert(boundaries_t *map, const cinsn_t * &key, const rangeset_t &val)
9383{
9385 HEXDSP(hx_boundaries_insert, &p, map, &key, &val);
9386 return p;
9387}
9388
9389//-------------------------------------------------------------------------
9390/// Get iterator pointing to the beginning of boundaries_t
9391inline boundaries_iterator_t boundaries_begin(const boundaries_t *map)
9392{
9394 HEXDSP(hx_boundaries_begin, &p, map);
9395 return p;
9396}
9397
9398//-------------------------------------------------------------------------
9399/// Get iterator pointing to the end of boundaries_t
9400inline boundaries_iterator_t boundaries_end(const boundaries_t *map)
9401{
9403 HEXDSP(hx_boundaries_end, &p, map);
9404 return p;
9405}
9406
9407//-------------------------------------------------------------------------
9408/// Move to the next element
9410{
9411 HEXDSP(hx_boundaries_next, &p);
9412 return p;
9413}
9414
9415//-------------------------------------------------------------------------
9416/// Move to the previous element
9418{
9419 HEXDSP(hx_boundaries_prev, &p);
9420 return p;
9421}
9422
9423//-------------------------------------------------------------------------
9424/// Erase current element from boundaries_t
9425inline void boundaries_erase(boundaries_t *map, boundaries_iterator_t p)
9426{
9427 HEXDSP(hx_boundaries_erase, map, &p);
9428}
9429
9430//-------------------------------------------------------------------------
9431/// Clear boundaries_t
9432inline void boundaries_clear(boundaries_t *map)
9433{
9434 HEXDSP(hx_boundaries_clear, map);
9435}
9436
9437//-------------------------------------------------------------------------
9438/// Get size of boundaries_t
9439inline size_t boundaries_size(boundaries_t *map)
9440{
9441 return (size_t)HEXDSP(hx_boundaries_size, map);
9442}
9443
9444//-------------------------------------------------------------------------
9445/// Delete boundaries_t instance
9446inline void boundaries_free(boundaries_t *map)
9447{
9448 HEXDSP(hx_boundaries_free, map);
9449}
9450
9451//-------------------------------------------------------------------------
9452/// Create a new boundaries_t instance
9453inline boundaries_t *boundaries_new()
9454{
9455 return (boundaries_t *)HEXDSP(hx_boundaries_new);
9456}
9457
9458//-------------------------------------------------------------------------
9460{
9461 iterator_word x;
9462 bool operator==(const block_chains_iterator_t &p) const { return x == p.x; }
9463 bool operator!=(const block_chains_iterator_t &p) const { return x != p.x; }
9464};
9465
9466//-------------------------------------------------------------------------
9467/// Get reference to the current set value
9469{
9470 return *(chain_t *)HEXDSP(hx_block_chains_get, &p);
9471}
9472
9473//-------------------------------------------------------------------------
9474/// Find the specified key in set block_chains_t
9476{
9478 HEXDSP(hx_block_chains_find, &p, set, &val);
9479 return p;
9480}
9481
9482//-------------------------------------------------------------------------
9483/// Insert new (chain_t) into set block_chains_t
9485{
9487 HEXDSP(hx_block_chains_insert, &p, set, &val);
9488 return p;
9489}
9490
9491//-------------------------------------------------------------------------
9492/// Get iterator pointing to the beginning of block_chains_t
9494{
9496 HEXDSP(hx_block_chains_begin, &p, set);
9497 return p;
9498}
9499
9500//-------------------------------------------------------------------------
9501/// Get iterator pointing to the end of block_chains_t
9503{
9505 HEXDSP(hx_block_chains_end, &p, set);
9506 return p;
9507}
9508
9509//-------------------------------------------------------------------------
9510/// Move to the next element
9512{
9513 HEXDSP(hx_block_chains_next, &p);
9514 return p;
9515}
9516
9517//-------------------------------------------------------------------------
9518/// Move to the previous element
9520{
9521 HEXDSP(hx_block_chains_prev, &p);
9522 return p;
9523}
9524
9525//-------------------------------------------------------------------------
9526/// Erase current element from block_chains_t
9528{
9529 HEXDSP(hx_block_chains_erase, set, &p);
9530}
9531
9532//-------------------------------------------------------------------------
9533/// Clear block_chains_t
9535{
9536 HEXDSP(hx_block_chains_clear, set);
9537}
9538
9539//-------------------------------------------------------------------------
9540/// Get size of block_chains_t
9542{
9543 return (size_t)HEXDSP(hx_block_chains_size, set);
9544}
9545
9546//-------------------------------------------------------------------------
9547/// Delete block_chains_t instance
9549{
9550 HEXDSP(hx_block_chains_free, set);
9551}
9552
9553//-------------------------------------------------------------------------
9554/// Create a new block_chains_t instance
9556{
9557 return (block_chains_t *)HEXDSP(hx_block_chains_new);
9558}
9559
9560//--------------------------------------------------------------------------
9561inline void *hexrays_alloc(size_t size)
9562{
9563 return HEXDSP(hx_hexrays_alloc, size);
9564}
9565
9566//--------------------------------------------------------------------------
9567inline void hexrays_free(void *ptr)
9568{
9569 HEXDSP(hx_hexrays_free, ptr);
9570}
9571
9572//--------------------------------------------------------------------------
9573inline void valrng_t::clear(void)
9574{
9575 HEXDSP(hx_valrng_t_clear, this);
9576}
9577
9578//--------------------------------------------------------------------------
9579inline void valrng_t::copy(const valrng_t &r)
9580{
9581 HEXDSP(hx_valrng_t_copy, this, &r);
9582}
9583
9584//--------------------------------------------------------------------------
9585inline valrng_t &valrng_t::assign(const valrng_t &r)
9586{
9587 return *(valrng_t *)HEXDSP(hx_valrng_t_assign, this, &r);
9588}
9589
9590//--------------------------------------------------------------------------
9591inline int valrng_t::compare(const valrng_t &r) const
9592{
9593 return (int)(size_t)HEXDSP(hx_valrng_t_compare, this, &r);
9594}
9595
9596//--------------------------------------------------------------------------
9597inline void valrng_t::set_eq(uvlr_t v)
9598{
9599 HEXDSP(hx_valrng_t_set_eq, this, v);
9600}
9601
9602//--------------------------------------------------------------------------
9603inline void valrng_t::set_cmp(cmpop_t cmp, uvlr_t _value)
9604{
9605 HEXDSP(hx_valrng_t_set_cmp, this, cmp, _value);
9606}
9607
9608//--------------------------------------------------------------------------
9609inline bool valrng_t::reduce_size(int new_size)
9610{
9611 return (uchar)(size_t)HEXDSP(hx_valrng_t_reduce_size, this, new_size) != 0;
9612}
9613
9614//--------------------------------------------------------------------------
9615inline bool valrng_t::intersect_with(const valrng_t &r)
9616{
9617 return (uchar)(size_t)HEXDSP(hx_valrng_t_intersect_with, this, &r) != 0;
9618}
9619
9620//--------------------------------------------------------------------------
9621inline bool valrng_t::unite_with(const valrng_t &r)
9622{
9623 return (uchar)(size_t)HEXDSP(hx_valrng_t_unite_with, this, &r) != 0;
9624}
9625
9626//--------------------------------------------------------------------------
9627inline void valrng_t::inverse(void)
9628{
9629 HEXDSP(hx_valrng_t_inverse, this);
9630}
9631
9632//--------------------------------------------------------------------------
9633inline bool valrng_t::has(uvlr_t v) const
9634{
9635 return (uchar)(size_t)HEXDSP(hx_valrng_t_has, this, v) != 0;
9636}
9637
9638//--------------------------------------------------------------------------
9639inline void valrng_t::print(qstring *vout) const
9640{
9641 HEXDSP(hx_valrng_t_print, this, vout);
9642}
9643
9644//--------------------------------------------------------------------------
9645inline const char *valrng_t::dstr(void) const
9646{
9647 return (const char *)HEXDSP(hx_valrng_t_dstr, this);
9648}
9649
9650//--------------------------------------------------------------------------
9651inline bool valrng_t::cvt_to_single_value(uvlr_t *v) const
9652{
9653 return (uchar)(size_t)HEXDSP(hx_valrng_t_cvt_to_single_value, this, v) != 0;
9654}
9655
9656//--------------------------------------------------------------------------
9657inline bool valrng_t::cvt_to_cmp(cmpop_t *cmp, uvlr_t *val, bool strict) const
9658{
9659 return (uchar)(size_t)HEXDSP(hx_valrng_t_cvt_to_cmp, this, cmp, val, strict) != 0;
9660}
9661
9662//--------------------------------------------------------------------------
9663inline ea_t get_merror_desc(qstring *out, merror_t code, mba_t *mba)
9664{
9665 ea_t retval;
9666 HEXDSP(hx_get_merror_desc, &retval, out, code, mba);
9667 return retval;
9668}
9669
9670//--------------------------------------------------------------------------
9671inline THREAD_SAFE bool must_mcode_close_block(mcode_t mcode, bool including_calls)
9672{
9673 return (uchar)(size_t)HEXDSP(hx_must_mcode_close_block, mcode, including_calls) != 0;
9674}
9675
9676//--------------------------------------------------------------------------
9677inline THREAD_SAFE bool is_mcode_propagatable(mcode_t mcode)
9678{
9679 return (uchar)(size_t)HEXDSP(hx_is_mcode_propagatable, mcode) != 0;
9680}
9681
9682//--------------------------------------------------------------------------
9683inline THREAD_SAFE mcode_t negate_mcode_relation(mcode_t code)
9684{
9685 return (mcode_t)(size_t)HEXDSP(hx_negate_mcode_relation, code);
9686}
9687
9688//--------------------------------------------------------------------------
9689inline THREAD_SAFE mcode_t swap_mcode_relation(mcode_t code)
9690{
9691 return (mcode_t)(size_t)HEXDSP(hx_swap_mcode_relation, code);
9692}
9693
9694//--------------------------------------------------------------------------
9695inline THREAD_SAFE mcode_t get_signed_mcode(mcode_t code)
9696{
9697 return (mcode_t)(size_t)HEXDSP(hx_get_signed_mcode, code);
9698}
9699
9700//--------------------------------------------------------------------------
9701inline THREAD_SAFE mcode_t get_unsigned_mcode(mcode_t code)
9702{
9703 return (mcode_t)(size_t)HEXDSP(hx_get_unsigned_mcode, code);
9704}
9705
9706//--------------------------------------------------------------------------
9707inline THREAD_SAFE bool mcode_modifies_d(mcode_t mcode)
9708{
9709 return (uchar)(size_t)HEXDSP(hx_mcode_modifies_d, mcode) != 0;
9710}
9711
9712//--------------------------------------------------------------------------
9713inline int operand_locator_t::compare(const operand_locator_t &r) const
9714{
9715 return (int)(size_t)HEXDSP(hx_operand_locator_t_compare, this, &r);
9716}
9717
9718//--------------------------------------------------------------------------
9719inline AS_PRINTF(3, 4) int vd_printer_t::print(int indent, const char *format, ...)
9720{
9721 va_list va;
9722 va_start(va, format);
9723 int retval = (int)(size_t)HEXDSP(hx_vd_printer_t_print, this, indent, format, va);
9724 va_end(va);
9725 return retval;
9726}
9727
9728//--------------------------------------------------------------------------
9729inline AS_PRINTF(3, 4) int file_printer_t::print(int indent, const char *format, ...)
9730{
9731 va_list va;
9732 va_start(va, format);
9733 int retval = (int)(size_t)HEXDSP(hx_file_printer_t_print, this, indent, format, va);
9734 va_end(va);
9735 return retval;
9736}
9737
9738//--------------------------------------------------------------------------
9739inline AS_PRINTF(3, 4) int qstring_printer_t::print(int indent, const char *format, ...)
9740{
9741 va_list va;
9742 va_start(va, format);
9743 int retval = (int)(size_t)HEXDSP(hx_qstring_printer_t_print, this, indent, format, va);
9744 va_end(va);
9745 return retval;
9746}
9747
9748//--------------------------------------------------------------------------
9749inline const char *dstr(const tinfo_t *tif)
9750{
9751 return (const char *)HEXDSP(hx_dstr, tif);
9752}
9753
9754//--------------------------------------------------------------------------
9755inline bool is_type_correct(const type_t *ptr)
9756{
9757 return (uchar)(size_t)HEXDSP(hx_is_type_correct, ptr) != 0;
9758}
9759
9760//--------------------------------------------------------------------------
9761inline bool is_small_udt(const tinfo_t &tif)
9762{
9763 return (uchar)(size_t)HEXDSP(hx_is_small_udt, &tif) != 0;
9764}
9765
9766//--------------------------------------------------------------------------
9767inline bool is_nonbool_type(const tinfo_t &type)
9768{
9769 return (uchar)(size_t)HEXDSP(hx_is_nonbool_type, &type) != 0;
9770}
9771
9772//--------------------------------------------------------------------------
9773inline bool is_bool_type(const tinfo_t &type)
9774{
9775 return (uchar)(size_t)HEXDSP(hx_is_bool_type, &type) != 0;
9776}
9777
9778//--------------------------------------------------------------------------
9779inline int partial_type_num(const tinfo_t &type)
9780{
9781 return (int)(size_t)HEXDSP(hx_partial_type_num, &type);
9782}
9783
9784//--------------------------------------------------------------------------
9785inline tinfo_t get_float_type(int width)
9786{
9787 tinfo_t retval;
9788 HEXDSP(hx_get_float_type, &retval, width);
9789 return retval;
9790}
9791
9792//--------------------------------------------------------------------------
9793inline tinfo_t get_int_type_by_width_and_sign(int srcwidth, type_sign_t sign)
9794{
9795 tinfo_t retval;
9796 HEXDSP(hx_get_int_type_by_width_and_sign, &retval, srcwidth, sign);
9797 return retval;
9798}
9799
9800//--------------------------------------------------------------------------
9801inline tinfo_t get_unk_type(int size)
9802{
9803 tinfo_t retval;
9804 HEXDSP(hx_get_unk_type, &retval, size);
9805 return retval;
9806}
9807
9808//--------------------------------------------------------------------------
9809inline tinfo_t dummy_ptrtype(int ptrsize, bool isfp)
9810{
9811 tinfo_t retval;
9812 HEXDSP(hx_dummy_ptrtype, &retval, ptrsize, isfp);
9813 return retval;
9814}
9815
9816//--------------------------------------------------------------------------
9817inline bool get_member_type(const member_t *mptr, tinfo_t *type)
9818{
9819 return (uchar)(size_t)HEXDSP(hx_get_member_type, mptr, type) != 0;
9820}
9821
9822//--------------------------------------------------------------------------
9823inline tinfo_t make_pointer(const tinfo_t &type)
9824{
9825 tinfo_t retval;
9826 HEXDSP(hx_make_pointer, &retval, &type);
9827 return retval;
9828}
9829
9830//--------------------------------------------------------------------------
9831inline tinfo_t create_typedef(const char *name)
9832{
9833 tinfo_t retval;
9834 HEXDSP(hx_create_typedef, &retval, name);
9835 return retval;
9836}
9837
9838//--------------------------------------------------------------------------
9839inline bool get_type(uval_t id, tinfo_t *tif, type_source_t guess)
9840{
9841 return (uchar)(size_t)HEXDSP(hx_get_type, id, tif, guess) != 0;
9842}
9843
9844//--------------------------------------------------------------------------
9845inline bool set_type(uval_t id, const tinfo_t &tif, type_source_t source, bool force)
9846{
9847 return (uchar)(size_t)HEXDSP(hx_set_type, id, &tif, source, force) != 0;
9848}
9849
9850//--------------------------------------------------------------------------
9851inline const char *vdloc_t::dstr(int width) const
9852{
9853 return (const char *)HEXDSP(hx_vdloc_t_dstr, this, width);
9854}
9855
9856//--------------------------------------------------------------------------
9857inline int vdloc_t::compare(const vdloc_t &r) const
9858{
9859 return (int)(size_t)HEXDSP(hx_vdloc_t_compare, this, &r);
9860}
9861
9862//--------------------------------------------------------------------------
9863inline bool vdloc_t::is_aliasable(const mba_t *mb, int size) const
9864{
9865 return (uchar)(size_t)HEXDSP(hx_vdloc_t_is_aliasable, this, mb, size) != 0;
9866}
9867
9868//--------------------------------------------------------------------------
9869inline void print_vdloc(qstring *vout, const vdloc_t &loc, int nbytes)
9870{
9871 HEXDSP(hx_print_vdloc, vout, &loc, nbytes);
9872}
9873
9874//--------------------------------------------------------------------------
9875inline bool arglocs_overlap(const vdloc_t &loc1, size_t w1, const vdloc_t &loc2, size_t w2)
9876{
9877 return (uchar)(size_t)HEXDSP(hx_arglocs_overlap, &loc1, w1, &loc2, w2) != 0;
9878}
9879
9880//--------------------------------------------------------------------------
9881inline int lvar_locator_t::compare(const lvar_locator_t &r) const
9882{
9883 return (int)(size_t)HEXDSP(hx_lvar_locator_t_compare, this, &r);
9884}
9885
9886//--------------------------------------------------------------------------
9887inline const char *lvar_locator_t::dstr(void) const
9888{
9889 return (const char *)HEXDSP(hx_lvar_locator_t_dstr, this);
9890}
9891
9892//--------------------------------------------------------------------------
9893inline const char *lvar_t::dstr(void) const
9894{
9895 return (const char *)HEXDSP(hx_lvar_t_dstr, this);
9896}
9897
9898//--------------------------------------------------------------------------
9899inline bool lvar_t::is_promoted_arg(void) const
9900{
9901 return (uchar)(size_t)HEXDSP(hx_lvar_t_is_promoted_arg, this) != 0;
9902}
9903
9904//--------------------------------------------------------------------------
9905inline bool lvar_t::accepts_type(const tinfo_t &t, bool may_change_thisarg)
9906{
9907 return (uchar)(size_t)HEXDSP(hx_lvar_t_accepts_type, this, &t, may_change_thisarg) != 0;
9908}
9909
9910//--------------------------------------------------------------------------
9911inline bool lvar_t::set_lvar_type(const tinfo_t &t, bool may_fail)
9912{
9913 return (uchar)(size_t)HEXDSP(hx_lvar_t_set_lvar_type, this, &t, may_fail) != 0;
9914}
9915
9916//--------------------------------------------------------------------------
9917inline bool lvar_t::set_width(int w, int svw_flags)
9918{
9919 return (uchar)(size_t)HEXDSP(hx_lvar_t_set_width, this, w, svw_flags) != 0;
9920}
9921
9922//--------------------------------------------------------------------------
9923inline void lvar_t::append_list(const mba_t *mba, mlist_t *lst, bool pad_if_scattered) const
9924{
9925 HEXDSP(hx_lvar_t_append_list, this, mba, lst, pad_if_scattered);
9926}
9927
9928//--------------------------------------------------------------------------
9929inline int lvars_t::find_stkvar(sval_t spoff, int width)
9930{
9931 return (int)(size_t)HEXDSP(hx_lvars_t_find_stkvar, this, spoff, width);
9932}
9933
9934//--------------------------------------------------------------------------
9936{
9937 return (lvar_t *)HEXDSP(hx_lvars_t_find, this, &ll);
9938}
9939
9940//--------------------------------------------------------------------------
9941inline int lvars_t::find_lvar(const vdloc_t &location, int width, int defblk) const
9942{
9943 return (int)(size_t)HEXDSP(hx_lvars_t_find_lvar, this, &location, width, defblk);
9944}
9945
9946//--------------------------------------------------------------------------
9947inline bool restore_user_lvar_settings(lvar_uservec_t *lvinf, ea_t func_ea)
9948{
9949 return (uchar)(size_t)HEXDSP(hx_restore_user_lvar_settings, lvinf, func_ea) != 0;
9950}
9951
9952//--------------------------------------------------------------------------
9953inline void save_user_lvar_settings(ea_t func_ea, const lvar_uservec_t &lvinf)
9954{
9955 HEXDSP(hx_save_user_lvar_settings, func_ea, &lvinf);
9956}
9957
9958//--------------------------------------------------------------------------
9959inline bool modify_user_lvars(ea_t entry_ea, user_lvar_modifier_t &mlv)
9960{
9961 return (uchar)(size_t)HEXDSP(hx_modify_user_lvars, entry_ea, &mlv) != 0;
9962}
9963
9964//--------------------------------------------------------------------------
9965inline bool modify_user_lvar_info(ea_t func_ea, uint mli_flags, const lvar_saved_info_t &info)
9966{
9967 return (uchar)(size_t)HEXDSP(hx_modify_user_lvar_info, func_ea, mli_flags, &info) != 0;
9968}
9969
9970//--------------------------------------------------------------------------
9971inline bool locate_lvar(lvar_locator_t *out, ea_t func_ea, const char *varname)
9972{
9973 return (uchar)(size_t)HEXDSP(hx_locate_lvar, out, func_ea, varname) != 0;
9974}
9975
9976//--------------------------------------------------------------------------
9977inline bool restore_user_defined_calls(udcall_map_t *udcalls, ea_t func_ea)
9978{
9979 return (uchar)(size_t)HEXDSP(hx_restore_user_defined_calls, udcalls, func_ea) != 0;
9980}
9981
9982//--------------------------------------------------------------------------
9983inline void save_user_defined_calls(ea_t func_ea, const udcall_map_t &udcalls)
9984{
9985 HEXDSP(hx_save_user_defined_calls, func_ea, &udcalls);
9986}
9987
9988//--------------------------------------------------------------------------
9989inline bool parse_user_call(udcall_t *udc, const char *decl, bool silent)
9990{
9991 return (uchar)(size_t)HEXDSP(hx_parse_user_call, udc, decl, silent) != 0;
9992}
9993
9994//--------------------------------------------------------------------------
9996{
9997 return (merror_t)(size_t)HEXDSP(hx_convert_to_user_call, &udc, &cdg);
9998}
9999
10000//--------------------------------------------------------------------------
10001inline bool install_microcode_filter(microcode_filter_t *filter, bool install)
10002{
10003 auto hrdsp = HEXDSP;
10004 return hrdsp != nullptr && (uchar)(size_t)hrdsp(hx_install_microcode_filter, filter, install) != 0;
10005}
10006
10007//--------------------------------------------------------------------------
10008inline void udc_filter_t::cleanup(void)
10009{
10010 HEXDSP(hx_udc_filter_t_cleanup, this);
10011}
10012
10013//--------------------------------------------------------------------------
10014inline bool udc_filter_t::init(const char *decl)
10015{
10016 return (uchar)(size_t)HEXDSP(hx_udc_filter_t_init, this, decl) != 0;
10017}
10018
10019//--------------------------------------------------------------------------
10021{
10022 return (merror_t)(size_t)HEXDSP(hx_udc_filter_t_apply, this, &cdg);
10023}
10024
10025//--------------------------------------------------------------------------
10026inline bitset_t::bitset_t(const bitset_t &m)
10027{
10028 HEXDSP(hx_bitset_t_bitset_t, this, &m);
10029}
10030
10031//--------------------------------------------------------------------------
10032inline bitset_t &bitset_t::copy(const bitset_t &m)
10033{
10034 return *(bitset_t *)HEXDSP(hx_bitset_t_copy, this, &m);
10035}
10036
10037//--------------------------------------------------------------------------
10038inline bool bitset_t::add(int bit)
10039{
10040 return (uchar)(size_t)HEXDSP(hx_bitset_t_add, this, bit) != 0;
10041}
10042
10043//--------------------------------------------------------------------------
10044inline bool bitset_t::add(int bit, int width)
10045{
10046 return (uchar)(size_t)HEXDSP(hx_bitset_t_add_, this, bit, width) != 0;
10047}
10048
10049//--------------------------------------------------------------------------
10050inline bool bitset_t::add(const bitset_t &ml)
10051{
10052 return (uchar)(size_t)HEXDSP(hx_bitset_t_add__, this, &ml) != 0;
10053}
10054
10055//--------------------------------------------------------------------------
10056inline bool bitset_t::sub(int bit)
10057{
10058 return (uchar)(size_t)HEXDSP(hx_bitset_t_sub, this, bit) != 0;
10059}
10060
10061//--------------------------------------------------------------------------
10062inline bool bitset_t::sub(int bit, int width)
10063{
10064 return (uchar)(size_t)HEXDSP(hx_bitset_t_sub_, this, bit, width) != 0;
10065}
10066
10067//--------------------------------------------------------------------------
10068inline bool bitset_t::sub(const bitset_t &ml)
10069{
10070 return (uchar)(size_t)HEXDSP(hx_bitset_t_sub__, this, &ml) != 0;
10071}
10072
10073//--------------------------------------------------------------------------
10074inline bool bitset_t::cut_at(int maxbit)
10075{
10076 return (uchar)(size_t)HEXDSP(hx_bitset_t_cut_at, this, maxbit) != 0;
10077}
10078
10079//--------------------------------------------------------------------------
10080inline void bitset_t::shift_down(int shift)
10081{
10082 HEXDSP(hx_bitset_t_shift_down, this, shift);
10083}
10084
10085//--------------------------------------------------------------------------
10086inline bool bitset_t::has(int bit) const
10087{
10088 return (uchar)(size_t)HEXDSP(hx_bitset_t_has, this, bit) != 0;
10089}
10090
10091//--------------------------------------------------------------------------
10092inline bool bitset_t::has_all(int bit, int width) const
10093{
10094 return (uchar)(size_t)HEXDSP(hx_bitset_t_has_all, this, bit, width) != 0;
10095}
10096
10097//--------------------------------------------------------------------------
10098inline bool bitset_t::has_any(int bit, int width) const
10099{
10100 return (uchar)(size_t)HEXDSP(hx_bitset_t_has_any, this, bit, width) != 0;
10101}
10102
10103//--------------------------------------------------------------------------
10104inline const char *bitset_t::dstr(void) const
10105{
10106 return (const char *)HEXDSP(hx_bitset_t_dstr, this);
10107}
10108
10109//--------------------------------------------------------------------------
10110inline bool bitset_t::empty(void) const
10111{
10112 return (uchar)(size_t)HEXDSP(hx_bitset_t_empty, this) != 0;
10113}
10114
10115//--------------------------------------------------------------------------
10116inline int bitset_t::count(void) const
10117{
10118 return (int)(size_t)HEXDSP(hx_bitset_t_count, this);
10119}
10120
10121//--------------------------------------------------------------------------
10122inline int bitset_t::count(int bit) const
10123{
10124 return (int)(size_t)HEXDSP(hx_bitset_t_count_, this, bit);
10125}
10126
10127//--------------------------------------------------------------------------
10128inline int bitset_t::last(void) const
10129{
10130 return (int)(size_t)HEXDSP(hx_bitset_t_last, this);
10131}
10132
10133//--------------------------------------------------------------------------
10134inline void bitset_t::fill_with_ones(int maxbit)
10135{
10136 HEXDSP(hx_bitset_t_fill_with_ones, this, maxbit);
10137}
10138
10139//--------------------------------------------------------------------------
10140inline bool bitset_t::fill_gaps(int total_nbits)
10141{
10142 return (uchar)(size_t)HEXDSP(hx_bitset_t_fill_gaps, this, total_nbits) != 0;
10143}
10144
10145//--------------------------------------------------------------------------
10146inline bool bitset_t::has_common(const bitset_t &ml) const
10147{
10148 return (uchar)(size_t)HEXDSP(hx_bitset_t_has_common, this, &ml) != 0;
10149}
10150
10151//--------------------------------------------------------------------------
10152inline bool bitset_t::intersect(const bitset_t &ml)
10153{
10154 return (uchar)(size_t)HEXDSP(hx_bitset_t_intersect, this, &ml) != 0;
10155}
10156
10157//--------------------------------------------------------------------------
10158inline bool bitset_t::is_subset_of(const bitset_t &ml) const
10159{
10160 return (uchar)(size_t)HEXDSP(hx_bitset_t_is_subset_of, this, &ml) != 0;
10161}
10162
10163//--------------------------------------------------------------------------
10164inline int bitset_t::compare(const bitset_t &r) const
10165{
10166 return (int)(size_t)HEXDSP(hx_bitset_t_compare, this, &r);
10167}
10168
10169//--------------------------------------------------------------------------
10170inline int bitset_t::goup(int reg) const
10171{
10172 return (int)(size_t)HEXDSP(hx_bitset_t_goup, this, reg);
10173}
10174
10175//--------------------------------------------------------------------------
10176inline const char *ivl_t::dstr(void) const
10177{
10178 return (const char *)HEXDSP(hx_ivl_t_dstr, this);
10179}
10180
10181//--------------------------------------------------------------------------
10182inline int ivl_t::compare(const ivl_t &r) const
10183{
10184 return (int)(size_t)HEXDSP(hx_ivl_t_compare, this, &r);
10185}
10186
10187//--------------------------------------------------------------------------
10188inline bool ivlset_t::add(const ivl_t &ivl)
10189{
10190 return (uchar)(size_t)HEXDSP(hx_ivlset_t_add, this, &ivl) != 0;
10191}
10192
10193//--------------------------------------------------------------------------
10194inline bool ivlset_t::add(const ivlset_t &ivs)
10195{
10196 return (uchar)(size_t)HEXDSP(hx_ivlset_t_add_, this, &ivs) != 0;
10197}
10198
10199//--------------------------------------------------------------------------
10200inline bool ivlset_t::addmasked(const ivlset_t &ivs, const ivl_t &mask)
10201{
10202 return (uchar)(size_t)HEXDSP(hx_ivlset_t_addmasked, this, &ivs, &mask) != 0;
10203}
10204
10205//--------------------------------------------------------------------------
10206inline bool ivlset_t::sub(const ivl_t &ivl)
10207{
10208 return (uchar)(size_t)HEXDSP(hx_ivlset_t_sub, this, &ivl) != 0;
10209}
10210
10211//--------------------------------------------------------------------------
10212inline bool ivlset_t::sub(const ivlset_t &ivs)
10213{
10214 return (uchar)(size_t)HEXDSP(hx_ivlset_t_sub_, this, &ivs) != 0;
10215}
10216
10217//--------------------------------------------------------------------------
10218inline bool ivlset_t::has_common(const ivl_t &ivl, bool strict) const
10219{
10220 return (uchar)(size_t)HEXDSP(hx_ivlset_t_has_common, this, &ivl, strict) != 0;
10221}
10222
10223//--------------------------------------------------------------------------
10224inline void ivlset_t::print(qstring *vout) const
10225{
10226 HEXDSP(hx_ivlset_t_print, this, vout);
10227}
10228
10229//--------------------------------------------------------------------------
10230inline const char *ivlset_t::dstr(void) const
10231{
10232 return (const char *)HEXDSP(hx_ivlset_t_dstr, this);
10233}
10234
10235//--------------------------------------------------------------------------
10236inline asize_t ivlset_t::count(void) const
10237{
10238 asize_t retval;
10239 HEXDSP(hx_ivlset_t_count, &retval, this);
10240 return retval;
10241}
10242
10243//--------------------------------------------------------------------------
10244inline bool ivlset_t::has_common(const ivlset_t &ivs) const
10245{
10246 return (uchar)(size_t)HEXDSP(hx_ivlset_t_has_common_, this, &ivs) != 0;
10247}
10248
10249//--------------------------------------------------------------------------
10250inline bool ivlset_t::contains(uval_t off) const
10251{
10252 return (uchar)(size_t)HEXDSP(hx_ivlset_t_contains, this, off) != 0;
10253}
10254
10255//--------------------------------------------------------------------------
10256inline bool ivlset_t::includes(const ivlset_t &ivs) const
10257{
10258 return (uchar)(size_t)HEXDSP(hx_ivlset_t_includes, this, &ivs) != 0;
10259}
10260
10261//--------------------------------------------------------------------------
10262inline bool ivlset_t::intersect(const ivlset_t &ivs)
10263{
10264 return (uchar)(size_t)HEXDSP(hx_ivlset_t_intersect, this, &ivs) != 0;
10265}
10266
10267//--------------------------------------------------------------------------
10268inline int ivlset_t::compare(const ivlset_t &r) const
10269{
10270 return (int)(size_t)HEXDSP(hx_ivlset_t_compare, this, &r);
10271}
10272
10273//--------------------------------------------------------------------------
10274inline void rlist_t::print(qstring *vout) const
10275{
10276 HEXDSP(hx_rlist_t_print, this, vout);
10277}
10278
10279//--------------------------------------------------------------------------
10280inline const char *rlist_t::dstr(void) const
10281{
10282 return (const char *)HEXDSP(hx_rlist_t_dstr, this);
10283}
10284
10285//--------------------------------------------------------------------------
10286inline bool mlist_t::addmem(ea_t ea, asize_t size)
10287{
10288 return (uchar)(size_t)HEXDSP(hx_mlist_t_addmem, this, ea, size) != 0;
10289}
10290
10291//--------------------------------------------------------------------------
10292inline void mlist_t::print(qstring *vout) const
10293{
10294 HEXDSP(hx_mlist_t_print, this, vout);
10295}
10296
10297//--------------------------------------------------------------------------
10298inline const char *mlist_t::dstr(void) const
10299{
10300 return (const char *)HEXDSP(hx_mlist_t_dstr, this);
10301}
10302
10303//--------------------------------------------------------------------------
10304inline int mlist_t::compare(const mlist_t &r) const
10305{
10306 return (int)(size_t)HEXDSP(hx_mlist_t_compare, this, &r);
10307}
10308
10309//--------------------------------------------------------------------------
10310inline const mlist_t &get_temp_regs(void)
10311{
10312 return *(const mlist_t *)HEXDSP(hx_get_temp_regs);
10313}
10314
10315//--------------------------------------------------------------------------
10316inline bool is_kreg(mreg_t r)
10317{
10318 return (uchar)(size_t)HEXDSP(hx_is_kreg, r) != 0;
10319}
10320
10321//--------------------------------------------------------------------------
10322inline mreg_t reg2mreg(int reg)
10323{
10324 return (mreg_t)(size_t)HEXDSP(hx_reg2mreg, reg);
10325}
10326
10327//--------------------------------------------------------------------------
10328inline int mreg2reg(mreg_t reg, int width)
10329{
10330 return (int)(size_t)HEXDSP(hx_mreg2reg, reg, width);
10331}
10332
10333//--------------------------------------------------------------------------
10334inline int get_mreg_name(qstring *out, mreg_t reg, int width, void *ud)
10335{
10336 return (int)(size_t)HEXDSP(hx_get_mreg_name, out, reg, width, ud);
10337}
10338
10339//--------------------------------------------------------------------------
10341{
10342 HEXDSP(hx_install_optinsn_handler, opt);
10343}
10344
10345//--------------------------------------------------------------------------
10347{
10348 return (uchar)(size_t)HEXDSP(hx_remove_optinsn_handler, opt) != 0;
10349}
10350
10351//--------------------------------------------------------------------------
10353{
10354 HEXDSP(hx_install_optblock_handler, opt);
10355}
10356
10357//--------------------------------------------------------------------------
10359{
10360 auto hrdsp = HEXDSP;
10361 return hrdsp != nullptr && (uchar)(size_t)hrdsp(hx_remove_optblock_handler, opt) != 0;
10362}
10363
10364//--------------------------------------------------------------------------
10365inline int lvar_ref_t::compare(const lvar_ref_t &r) const
10366{
10367 return (int)(size_t)HEXDSP(hx_lvar_ref_t_compare, this, &r);
10368}
10369
10370//--------------------------------------------------------------------------
10371inline lvar_t &lvar_ref_t::var(void) const
10372{
10373 return *(lvar_t *)HEXDSP(hx_lvar_ref_t_var, this);
10374}
10375
10376//--------------------------------------------------------------------------
10377inline int stkvar_ref_t::compare(const stkvar_ref_t &r) const
10378{
10379 return (int)(size_t)HEXDSP(hx_stkvar_ref_t_compare, this, &r);
10380}
10381
10382//--------------------------------------------------------------------------
10383inline member_t *stkvar_ref_t::get_stkvar(uval_t *p_off) const
10384{
10385 return (member_t *)HEXDSP(hx_stkvar_ref_t_get_stkvar, this, p_off);
10386}
10387
10388//--------------------------------------------------------------------------
10389inline void fnumber_t::print(qstring *vout) const
10390{
10391 HEXDSP(hx_fnumber_t_print, this, vout);
10392}
10393
10394//--------------------------------------------------------------------------
10395inline const char *fnumber_t::dstr(void) const
10396{
10397 return (const char *)HEXDSP(hx_fnumber_t_dstr, this);
10398}
10399
10400//--------------------------------------------------------------------------
10401inline void mop_t::copy(const mop_t &rop)
10402{
10403 HEXDSP(hx_mop_t_copy, this, &rop);
10404}
10405
10406//--------------------------------------------------------------------------
10407inline mop_t &mop_t::assign(const mop_t &rop)
10408{
10409 return *(mop_t *)HEXDSP(hx_mop_t_assign, this, &rop);
10410}
10411
10412//--------------------------------------------------------------------------
10413inline void mop_t::swap(mop_t &rop)
10414{
10415 HEXDSP(hx_mop_t_swap, this, &rop);
10416}
10417
10418//--------------------------------------------------------------------------
10419inline void mop_t::erase(void)
10420{
10421 HEXDSP(hx_mop_t_erase, this);
10422}
10423
10424//--------------------------------------------------------------------------
10425inline void mop_t::print(qstring *vout, int shins_flags) const
10426{
10427 HEXDSP(hx_mop_t_print, this, vout, shins_flags);
10428}
10429
10430//--------------------------------------------------------------------------
10431inline const char *mop_t::dstr(void) const
10432{
10433 return (const char *)HEXDSP(hx_mop_t_dstr, this);
10434}
10435
10436//--------------------------------------------------------------------------
10437inline bool mop_t::create_from_mlist(mba_t *mba, const mlist_t &lst, sval_t fullsize)
10438{
10439 return (uchar)(size_t)HEXDSP(hx_mop_t_create_from_mlist, this, mba, &lst, fullsize) != 0;
10440}
10441
10442//--------------------------------------------------------------------------
10443inline bool mop_t::create_from_ivlset(mba_t *mba, const ivlset_t &ivs, sval_t fullsize)
10444{
10445 return (uchar)(size_t)HEXDSP(hx_mop_t_create_from_ivlset, this, mba, &ivs, fullsize) != 0;
10446}
10447
10448//--------------------------------------------------------------------------
10449inline void mop_t::create_from_vdloc(mba_t *mba, const vdloc_t &loc, int _size)
10450{
10451 HEXDSP(hx_mop_t_create_from_vdloc, this, mba, &loc, _size);
10452}
10453
10454//--------------------------------------------------------------------------
10455inline void mop_t::create_from_scattered_vdloc(mba_t *mba, const char *name, tinfo_t type, const vdloc_t &loc)
10456{
10457 HEXDSP(hx_mop_t_create_from_scattered_vdloc, this, mba, name, &type, &loc);
10458}
10459
10460//--------------------------------------------------------------------------
10462{
10463 HEXDSP(hx_mop_t_create_from_insn, this, m);
10464}
10465
10466//--------------------------------------------------------------------------
10467inline void mop_t::make_number(uint64 _value, int _size, ea_t _ea, int opnum)
10468{
10469 HEXDSP(hx_mop_t_make_number, this, _value, _size, _ea, opnum);
10470}
10471
10472//--------------------------------------------------------------------------
10473inline bool mop_t::make_fpnum(const void *bytes, size_t _size)
10474{
10475 return (uchar)(size_t)HEXDSP(hx_mop_t_make_fpnum, this, bytes, _size) != 0;
10476}
10477
10478//--------------------------------------------------------------------------
10479inline void mop_t::_make_gvar(ea_t ea)
10480{
10481 HEXDSP(hx_mop_t__make_gvar, this, ea);
10482}
10483
10484//--------------------------------------------------------------------------
10485inline void mop_t::make_gvar(ea_t ea)
10486{
10487 HEXDSP(hx_mop_t_make_gvar, this, ea);
10488}
10489
10490//--------------------------------------------------------------------------
10491inline void mop_t::make_reg_pair(int loreg, int hireg, int halfsize)
10492{
10493 HEXDSP(hx_mop_t_make_reg_pair, this, loreg, hireg, halfsize);
10494}
10495
10496//--------------------------------------------------------------------------
10497inline void mop_t::make_helper(const char *name)
10498{
10499 HEXDSP(hx_mop_t_make_helper, this, name);
10500}
10501
10502//--------------------------------------------------------------------------
10504{
10505 return (uchar)(size_t)HEXDSP(hx_mop_t_is_bit_reg, reg) != 0;
10506}
10507
10508//--------------------------------------------------------------------------
10509inline bool mop_t::may_use_aliased_memory(void) const
10510{
10511 return (uchar)(size_t)HEXDSP(hx_mop_t_may_use_aliased_memory, this) != 0;
10512}
10513
10514//--------------------------------------------------------------------------
10515inline bool mop_t::is01(void) const
10516{
10517 return (uchar)(size_t)HEXDSP(hx_mop_t_is01, this) != 0;
10518}
10519
10520//--------------------------------------------------------------------------
10521inline bool mop_t::is_sign_extended_from(int nbytes) const
10522{
10523 return (uchar)(size_t)HEXDSP(hx_mop_t_is_sign_extended_from, this, nbytes) != 0;
10524}
10525
10526//--------------------------------------------------------------------------
10527inline bool mop_t::is_zero_extended_from(int nbytes) const
10528{
10529 return (uchar)(size_t)HEXDSP(hx_mop_t_is_zero_extended_from, this, nbytes) != 0;
10530}
10531
10532//--------------------------------------------------------------------------
10533inline bool mop_t::equal_mops(const mop_t &rop, int eqflags) const
10534{
10535 return (uchar)(size_t)HEXDSP(hx_mop_t_equal_mops, this, &rop, eqflags) != 0;
10536}
10537
10538//--------------------------------------------------------------------------
10539inline int mop_t::lexcompare(const mop_t &rop) const
10540{
10541 return (int)(size_t)HEXDSP(hx_mop_t_lexcompare, this, &rop);
10542}
10543
10544//--------------------------------------------------------------------------
10545inline int mop_t::for_all_ops(mop_visitor_t &mv, const tinfo_t *type, bool is_target)
10546{
10547 return (int)(size_t)HEXDSP(hx_mop_t_for_all_ops, this, &mv, type, is_target);
10548}
10549
10550//--------------------------------------------------------------------------
10552{
10553 return (int)(size_t)HEXDSP(hx_mop_t_for_all_scattered_submops, this, &sv);
10554}
10555
10556//--------------------------------------------------------------------------
10557inline bool mop_t::is_constant(uint64 *out, bool is_signed) const
10558{
10559 return (uchar)(size_t)HEXDSP(hx_mop_t_is_constant, this, out, is_signed) != 0;
10560}
10561
10562//--------------------------------------------------------------------------
10563inline bool mop_t::get_stkoff(sval_t *p_off) const
10564{
10565 return (uchar)(size_t)HEXDSP(hx_mop_t_get_stkoff, this, p_off) != 0;
10566}
10567
10568//--------------------------------------------------------------------------
10569inline bool mop_t::make_low_half(int width)
10570{
10571 return (uchar)(size_t)HEXDSP(hx_mop_t_make_low_half, this, width) != 0;
10572}
10573
10574//--------------------------------------------------------------------------
10575inline bool mop_t::make_high_half(int width)
10576{
10577 return (uchar)(size_t)HEXDSP(hx_mop_t_make_high_half, this, width) != 0;
10578}
10579
10580//--------------------------------------------------------------------------
10581inline bool mop_t::make_first_half(int width)
10582{
10583 return (uchar)(size_t)HEXDSP(hx_mop_t_make_first_half, this, width) != 0;
10584}
10585
10586//--------------------------------------------------------------------------
10587inline bool mop_t::make_second_half(int width)
10588{
10589 return (uchar)(size_t)HEXDSP(hx_mop_t_make_second_half, this, width) != 0;
10590}
10591
10592//--------------------------------------------------------------------------
10593inline bool mop_t::shift_mop(int offset)
10594{
10595 return (uchar)(size_t)HEXDSP(hx_mop_t_shift_mop, this, offset) != 0;
10596}
10597
10598//--------------------------------------------------------------------------
10599inline bool mop_t::change_size(int nsize, side_effect_t sideff)
10600{
10601 return (uchar)(size_t)HEXDSP(hx_mop_t_change_size, this, nsize, sideff) != 0;
10602}
10603
10604//--------------------------------------------------------------------------
10605inline bool mop_t::preserve_side_effects(mblock_t *blk, minsn_t *top, bool *moved_calls)
10606{
10607 return (uchar)(size_t)HEXDSP(hx_mop_t_preserve_side_effects, this, blk, top, moved_calls) != 0;
10608}
10609
10610//--------------------------------------------------------------------------
10611inline void mop_t::apply_ld_mcode(mcode_t mcode, ea_t ea, int newsize)
10612{
10613 HEXDSP(hx_mop_t_apply_ld_mcode, this, mcode, ea, newsize);
10614}
10615
10616//--------------------------------------------------------------------------
10617inline void mcallarg_t::print(qstring *vout, int shins_flags) const
10618{
10619 HEXDSP(hx_mcallarg_t_print, this, vout, shins_flags);
10620}
10621
10622//--------------------------------------------------------------------------
10623inline const char *mcallarg_t::dstr(void) const
10624{
10625 return (const char *)HEXDSP(hx_mcallarg_t_dstr, this);
10626}
10627
10628//--------------------------------------------------------------------------
10629inline void mcallarg_t::set_regarg(mreg_t mr, int sz, const tinfo_t &tif)
10630{
10631 HEXDSP(hx_mcallarg_t_set_regarg, this, mr, sz, &tif);
10632}
10633
10634//--------------------------------------------------------------------------
10635inline int mcallinfo_t::lexcompare(const mcallinfo_t &f) const
10636{
10637 return (int)(size_t)HEXDSP(hx_mcallinfo_t_lexcompare, this, &f);
10638}
10639
10640//--------------------------------------------------------------------------
10641inline bool mcallinfo_t::set_type(const tinfo_t &type)
10642{
10643 return (uchar)(size_t)HEXDSP(hx_mcallinfo_t_set_type, this, &type) != 0;
10644}
10645
10646//--------------------------------------------------------------------------
10647inline tinfo_t mcallinfo_t::get_type(void) const
10648{
10649 tinfo_t retval;
10650 HEXDSP(hx_mcallinfo_t_get_type, &retval, this);
10651 return retval;
10652}
10653
10654//--------------------------------------------------------------------------
10655inline void mcallinfo_t::print(qstring *vout, int size, int shins_flags) const
10656{
10657 HEXDSP(hx_mcallinfo_t_print, this, vout, size, shins_flags);
10658}
10659
10660//--------------------------------------------------------------------------
10661inline const char *mcallinfo_t::dstr(void) const
10662{
10663 return (const char *)HEXDSP(hx_mcallinfo_t_dstr, this);
10664}
10665
10666//--------------------------------------------------------------------------
10667inline int mcases_t::compare(const mcases_t &r) const
10668{
10669 return (int)(size_t)HEXDSP(hx_mcases_t_compare, this, &r);
10670}
10671
10672//--------------------------------------------------------------------------
10673inline void mcases_t::print(qstring *vout) const
10674{
10675 HEXDSP(hx_mcases_t_print, this, vout);
10676}
10677
10678//--------------------------------------------------------------------------
10679inline const char *mcases_t::dstr(void) const
10680{
10681 return (const char *)HEXDSP(hx_mcases_t_dstr, this);
10682}
10683
10684//--------------------------------------------------------------------------
10685inline bool vivl_t::extend_to_cover(const vivl_t &r)
10686{
10687 return (uchar)(size_t)HEXDSP(hx_vivl_t_extend_to_cover, this, &r) != 0;
10688}
10689
10690//--------------------------------------------------------------------------
10691inline uval_t vivl_t::intersect(const vivl_t &r)
10692{
10693 uval_t retval;
10694 HEXDSP(hx_vivl_t_intersect, &retval, this, &r);
10695 return retval;
10696}
10697
10698//--------------------------------------------------------------------------
10699inline void vivl_t::print(qstring *vout) const
10700{
10701 HEXDSP(hx_vivl_t_print, this, vout);
10702}
10703
10704//--------------------------------------------------------------------------
10705inline const char *vivl_t::dstr(void) const
10706{
10707 return (const char *)HEXDSP(hx_vivl_t_dstr, this);
10708}
10709
10710//--------------------------------------------------------------------------
10711inline void chain_t::print(qstring *vout) const
10712{
10713 HEXDSP(hx_chain_t_print, this, vout);
10714}
10715
10716//--------------------------------------------------------------------------
10717inline const char *chain_t::dstr(void) const
10718{
10719 return (const char *)HEXDSP(hx_chain_t_dstr, this);
10720}
10721
10722//--------------------------------------------------------------------------
10723inline void chain_t::append_list(const mba_t *mba, mlist_t *list) const
10724{
10725 HEXDSP(hx_chain_t_append_list, this, mba, list);
10726}
10727
10728//--------------------------------------------------------------------------
10729inline const chain_t *block_chains_t::get_chain(const chain_t &ch) const
10730{
10731 return (const chain_t *)HEXDSP(hx_block_chains_t_get_chain, this, &ch);
10732}
10733
10734//--------------------------------------------------------------------------
10735inline void block_chains_t::print(qstring *vout) const
10736{
10737 HEXDSP(hx_block_chains_t_print, this, vout);
10738}
10739
10740//--------------------------------------------------------------------------
10741inline const char *block_chains_t::dstr(void) const
10742{
10743 return (const char *)HEXDSP(hx_block_chains_t_dstr, this);
10744}
10745
10746//--------------------------------------------------------------------------
10748{
10749 return (int)(size_t)HEXDSP(hx_graph_chains_t_for_all_chains, this, &cv, gca_flags);
10750}
10751
10752//--------------------------------------------------------------------------
10754{
10755 HEXDSP(hx_graph_chains_t_release, this);
10756}
10757
10758//--------------------------------------------------------------------------
10759inline void minsn_t::init(ea_t _ea)
10760{
10761 HEXDSP(hx_minsn_t_init, this, _ea);
10762}
10763
10764//--------------------------------------------------------------------------
10765inline void minsn_t::copy(const minsn_t &m)
10766{
10767 HEXDSP(hx_minsn_t_copy, this, &m);
10768}
10769
10770//--------------------------------------------------------------------------
10771inline void minsn_t::set_combined(void)
10772{
10773 HEXDSP(hx_minsn_t_set_combined, this);
10774}
10775
10776//--------------------------------------------------------------------------
10777inline void minsn_t::swap(minsn_t &m)
10778{
10779 HEXDSP(hx_minsn_t_swap, this, &m);
10780}
10781
10782//--------------------------------------------------------------------------
10783inline void minsn_t::print(qstring *vout, int shins_flags) const
10784{
10785 HEXDSP(hx_minsn_t_print, this, vout, shins_flags);
10786}
10787
10788//--------------------------------------------------------------------------
10789inline const char *minsn_t::dstr(void) const
10790{
10791 return (const char *)HEXDSP(hx_minsn_t_dstr, this);
10792}
10793
10794//--------------------------------------------------------------------------
10795inline void minsn_t::setaddr(ea_t new_ea)
10796{
10797 HEXDSP(hx_minsn_t_setaddr, this, new_ea);
10798}
10799
10800//--------------------------------------------------------------------------
10801inline int minsn_t::optimize_subtree(mblock_t *blk, minsn_t *top, minsn_t *parent, ea_t *converted_call, int optflags)
10802{
10803 return (int)(size_t)HEXDSP(hx_minsn_t_optimize_subtree, this, blk, top, parent, converted_call, optflags);
10804}
10805
10806//--------------------------------------------------------------------------
10808{
10809 return (int)(size_t)HEXDSP(hx_minsn_t_for_all_ops, this, &mv);
10810}
10811
10812//--------------------------------------------------------------------------
10814{
10815 return (int)(size_t)HEXDSP(hx_minsn_t_for_all_insns, this, &mv);
10816}
10817
10818//--------------------------------------------------------------------------
10819inline void minsn_t::_make_nop(void)
10820{
10821 HEXDSP(hx_minsn_t__make_nop, this);
10822}
10823
10824//--------------------------------------------------------------------------
10825inline bool minsn_t::equal_insns(const minsn_t &m, int eqflags) const
10826{
10827 return (uchar)(size_t)HEXDSP(hx_minsn_t_equal_insns, this, &m, eqflags) != 0;
10828}
10829
10830//--------------------------------------------------------------------------
10831inline int minsn_t::lexcompare(const minsn_t &ri) const
10832{
10833 return (int)(size_t)HEXDSP(hx_minsn_t_lexcompare, this, &ri);
10834}
10835
10836//--------------------------------------------------------------------------
10837inline bool minsn_t::is_noret_call(int flags)
10838{
10839 return (uchar)(size_t)HEXDSP(hx_minsn_t_is_noret_call, this, flags) != 0;
10840}
10841
10842//--------------------------------------------------------------------------
10843inline bool minsn_t::is_helper(const char *name) const
10844{
10845 return (uchar)(size_t)HEXDSP(hx_minsn_t_is_helper, this, name) != 0;
10846}
10847
10848//--------------------------------------------------------------------------
10849inline minsn_t *minsn_t::find_call(bool with_helpers) const
10850{
10851 return (minsn_t *)HEXDSP(hx_minsn_t_find_call, this, with_helpers);
10852}
10853
10854//--------------------------------------------------------------------------
10855inline bool minsn_t::has_side_effects(bool include_ldx_and_divs) const
10856{
10857 return (uchar)(size_t)HEXDSP(hx_minsn_t_has_side_effects, this, include_ldx_and_divs) != 0;
10858}
10859
10860//--------------------------------------------------------------------------
10861inline minsn_t *minsn_t::find_opcode(mcode_t mcode)
10862{
10863 return (minsn_t *)HEXDSP(hx_minsn_t_find_opcode, this, mcode);
10864}
10865
10866//--------------------------------------------------------------------------
10867inline const minsn_t *minsn_t::find_ins_op(const mop_t **other, mcode_t op) const
10868{
10869 return (const minsn_t *)HEXDSP(hx_minsn_t_find_ins_op, this, other, op);
10870}
10871
10872//--------------------------------------------------------------------------
10873inline const mop_t *minsn_t::find_num_op(const mop_t **other) const
10874{
10875 return (const mop_t *)HEXDSP(hx_minsn_t_find_num_op, this, other);
10876}
10877
10878//--------------------------------------------------------------------------
10879inline bool minsn_t::modifies_d(void) const
10880{
10881 return (uchar)(size_t)HEXDSP(hx_minsn_t_modifies_d, this) != 0;
10882}
10883
10884//--------------------------------------------------------------------------
10885inline bool minsn_t::is_between(const minsn_t *m1, const minsn_t *m2) const
10886{
10887 return (uchar)(size_t)HEXDSP(hx_minsn_t_is_between, this, m1, m2) != 0;
10888}
10889
10890//--------------------------------------------------------------------------
10891inline bool minsn_t::may_use_aliased_memory(void) const
10892{
10893 return (uchar)(size_t)HEXDSP(hx_minsn_t_may_use_aliased_memory, this) != 0;
10894}
10895
10896//--------------------------------------------------------------------------
10897inline const minsn_t *getf_reginsn(const minsn_t *ins)
10898{
10899 return (const minsn_t *)HEXDSP(hx_getf_reginsn, ins);
10900}
10901
10902//--------------------------------------------------------------------------
10903inline const minsn_t *getb_reginsn(const minsn_t *ins)
10904{
10905 return (const minsn_t *)HEXDSP(hx_getb_reginsn, ins);
10906}
10907
10908//--------------------------------------------------------------------------
10909inline void mblock_t::init(void)
10910{
10911 HEXDSP(hx_mblock_t_init, this);
10912}
10913
10914//--------------------------------------------------------------------------
10915inline void mblock_t::print(vd_printer_t &vp) const
10916{
10917 HEXDSP(hx_mblock_t_print, this, &vp);
10918}
10919
10920//--------------------------------------------------------------------------
10921inline void mblock_t::dump(void) const
10922{
10923 HEXDSP(hx_mblock_t_dump, this);
10924}
10925
10926//--------------------------------------------------------------------------
10927inline AS_PRINTF(2, 0) void mblock_t::vdump_block(const char *title, va_list va) const
10928{
10929 HEXDSP(hx_mblock_t_vdump_block, this, title, va);
10930}
10931
10932//--------------------------------------------------------------------------
10934{
10935 return (minsn_t *)HEXDSP(hx_mblock_t_insert_into_block, this, nm, om);
10936}
10937
10938//--------------------------------------------------------------------------
10940{
10941 return (minsn_t *)HEXDSP(hx_mblock_t_remove_from_block, this, m);
10942}
10943
10944//--------------------------------------------------------------------------
10946{
10947 return (int)(size_t)HEXDSP(hx_mblock_t_for_all_insns, this, &mv);
10948}
10949
10950//--------------------------------------------------------------------------
10952{
10953 return (int)(size_t)HEXDSP(hx_mblock_t_for_all_ops, this, &mv);
10954}
10955
10956//--------------------------------------------------------------------------
10958{
10959 return (int)(size_t)HEXDSP(hx_mblock_t_for_all_uses, this, list, i1, i2, &mmv);
10960}
10961
10962//--------------------------------------------------------------------------
10963inline int mblock_t::optimize_insn(minsn_t *m, int optflags)
10964{
10965 return (int)(size_t)HEXDSP(hx_mblock_t_optimize_insn, this, m, optflags);
10966}
10967
10968//--------------------------------------------------------------------------
10970{
10971 return (int)(size_t)HEXDSP(hx_mblock_t_optimize_block, this);
10972}
10973
10974//--------------------------------------------------------------------------
10975inline int mblock_t::build_lists(bool kill_deads)
10976{
10977 return (int)(size_t)HEXDSP(hx_mblock_t_build_lists, this, kill_deads);
10978}
10979
10980//--------------------------------------------------------------------------
10982{
10983 return (int)(size_t)HEXDSP(hx_mblock_t_optimize_useless_jump, this);
10984}
10985
10986//--------------------------------------------------------------------------
10987inline void mblock_t::append_use_list(mlist_t *list, const mop_t &op, maymust_t maymust, bitrange_t mask) const
10988{
10989 HEXDSP(hx_mblock_t_append_use_list, this, list, &op, maymust, &mask);
10990}
10991
10992//--------------------------------------------------------------------------
10993inline void mblock_t::append_def_list(mlist_t *list, const mop_t &op, maymust_t maymust) const
10994{
10995 HEXDSP(hx_mblock_t_append_def_list, this, list, &op, maymust);
10996}
10997
10998//--------------------------------------------------------------------------
10999inline mlist_t mblock_t::build_use_list(const minsn_t &ins, maymust_t maymust) const
11000{
11001 mlist_t retval;
11002 HEXDSP(hx_mblock_t_build_use_list, &retval, this, &ins, maymust);
11003 return retval;
11004}
11005
11006//--------------------------------------------------------------------------
11007inline mlist_t mblock_t::build_def_list(const minsn_t &ins, maymust_t maymust) const
11008{
11009 mlist_t retval;
11010 HEXDSP(hx_mblock_t_build_def_list, &retval, this, &ins, maymust);
11011 return retval;
11012}
11013
11014//--------------------------------------------------------------------------
11015inline const minsn_t *mblock_t::find_first_use(mlist_t *list, const minsn_t *i1, const minsn_t *i2, maymust_t maymust) const
11016{
11017 return (const minsn_t *)HEXDSP(hx_mblock_t_find_first_use, this, list, i1, i2, maymust);
11018}
11019
11020//--------------------------------------------------------------------------
11021inline const minsn_t *mblock_t::find_redefinition(const mlist_t &list, const minsn_t *i1, const minsn_t *i2, maymust_t maymust) const
11022{
11023 return (const minsn_t *)HEXDSP(hx_mblock_t_find_redefinition, this, &list, i1, i2, maymust);
11024}
11025
11026//--------------------------------------------------------------------------
11027inline bool mblock_t::is_rhs_redefined(const minsn_t *ins, const minsn_t *i1, const minsn_t *i2) const
11028{
11029 return (uchar)(size_t)HEXDSP(hx_mblock_t_is_rhs_redefined, this, ins, i1, i2) != 0;
11030}
11031
11032//--------------------------------------------------------------------------
11033inline minsn_t *mblock_t::find_access(const mop_t &op, minsn_t **parent, const minsn_t *mend, int fdflags) const
11034{
11035 return (minsn_t *)HEXDSP(hx_mblock_t_find_access, this, &op, parent, mend, fdflags);
11036}
11037
11038//--------------------------------------------------------------------------
11039inline bool mblock_t::get_valranges(valrng_t *res, const vivl_t &vivl, int vrflags) const
11040{
11041 return (uchar)(size_t)HEXDSP(hx_mblock_t_get_valranges, this, res, &vivl, vrflags) != 0;
11042}
11043
11044//--------------------------------------------------------------------------
11045inline bool mblock_t::get_valranges(valrng_t *res, const vivl_t &vivl, const minsn_t *m, int vrflags) const
11046{
11047 return (uchar)(size_t)HEXDSP(hx_mblock_t_get_valranges_, this, res, &vivl, m, vrflags) != 0;
11048}
11049
11050//--------------------------------------------------------------------------
11051inline size_t mblock_t::get_reginsn_qty(void) const
11052{
11053 return (size_t)HEXDSP(hx_mblock_t_get_reginsn_qty, this);
11054}
11055
11056//--------------------------------------------------------------------------
11057inline bool mba_ranges_t::range_contains(ea_t ea) const
11058{
11059 return (uchar)(size_t)HEXDSP(hx_mba_ranges_t_range_contains, this, ea) != 0;
11060}
11061
11062//--------------------------------------------------------------------------
11063inline vdloc_t mba_t::idaloc2vd(const argloc_t &loc, int width, sval_t spd)
11064{
11065 vdloc_t retval;
11066 HEXDSP(hx_mba_t_idaloc2vd, &retval, &loc, width, spd);
11067 return retval;
11068}
11069
11070//--------------------------------------------------------------------------
11071inline vdloc_t mba_t::idaloc2vd(const argloc_t &loc, int width) const
11072{
11073 vdloc_t retval;
11074 HEXDSP(hx_mba_t_idaloc2vd_, &retval, this, &loc, width);
11075 return retval;
11076}
11077
11078//--------------------------------------------------------------------------
11079inline argloc_t mba_t::vd2idaloc(const vdloc_t &loc, int width, sval_t spd)
11080{
11081 argloc_t retval;
11082 HEXDSP(hx_mba_t_vd2idaloc, &retval, &loc, width, spd);
11083 return retval;
11084}
11085
11086//--------------------------------------------------------------------------
11087inline argloc_t mba_t::vd2idaloc(const vdloc_t &loc, int width) const
11088{
11089 argloc_t retval;
11090 HEXDSP(hx_mba_t_vd2idaloc_, &retval, this, &loc, width);
11091 return retval;
11092}
11093
11094//--------------------------------------------------------------------------
11095inline void mba_t::term(void)
11096{
11097 HEXDSP(hx_mba_t_term, this);
11098}
11099
11100//--------------------------------------------------------------------------
11101inline func_t *mba_t::get_curfunc(void) const
11102{
11103 return (func_t *)HEXDSP(hx_mba_t_get_curfunc, this);
11104}
11105
11106//--------------------------------------------------------------------------
11108{
11109 return (uchar)(size_t)HEXDSP(hx_mba_t_set_maturity, this, mat) != 0;
11110}
11111
11112//--------------------------------------------------------------------------
11113inline int mba_t::optimize_local(int locopt_bits)
11114{
11115 return (int)(size_t)HEXDSP(hx_mba_t_optimize_local, this, locopt_bits);
11116}
11117
11118//--------------------------------------------------------------------------
11120{
11121 return (merror_t)(size_t)HEXDSP(hx_mba_t_build_graph, this);
11122}
11123
11124//--------------------------------------------------------------------------
11126{
11127 return (mbl_graph_t *)HEXDSP(hx_mba_t_get_graph, this);
11128}
11129
11130//--------------------------------------------------------------------------
11131inline int mba_t::analyze_calls(int acflags)
11132{
11133 return (int)(size_t)HEXDSP(hx_mba_t_analyze_calls, this, acflags);
11134}
11135
11136//--------------------------------------------------------------------------
11138{
11139 return (merror_t)(size_t)HEXDSP(hx_mba_t_optimize_global, this);
11140}
11141
11142//--------------------------------------------------------------------------
11143inline void mba_t::alloc_lvars(void)
11144{
11145 HEXDSP(hx_mba_t_alloc_lvars, this);
11146}
11147
11148//--------------------------------------------------------------------------
11149inline void mba_t::dump(void) const
11150{
11151 HEXDSP(hx_mba_t_dump, this);
11152}
11153
11154//--------------------------------------------------------------------------
11155inline AS_PRINTF(3, 0) void mba_t::vdump_mba(bool _verify, const char *title, va_list va) const
11156{
11157 HEXDSP(hx_mba_t_vdump_mba, this, _verify, title, va);
11158}
11159
11160//--------------------------------------------------------------------------
11161inline void mba_t::print(vd_printer_t &vp) const
11162{
11163 HEXDSP(hx_mba_t_print, this, &vp);
11164}
11165
11166//--------------------------------------------------------------------------
11167inline void mba_t::verify(bool always) const
11168{
11169 HEXDSP(hx_mba_t_verify, this, always);
11170}
11171
11172//--------------------------------------------------------------------------
11174{
11175 HEXDSP(hx_mba_t_mark_chains_dirty, this);
11176}
11177
11178//--------------------------------------------------------------------------
11180{
11181 return (mblock_t *)HEXDSP(hx_mba_t_insert_block, this, bblk);
11182}
11183
11184//--------------------------------------------------------------------------
11186{
11187 return (uchar)(size_t)HEXDSP(hx_mba_t_remove_block, this, blk) != 0;
11188}
11189
11190//--------------------------------------------------------------------------
11191inline mblock_t *mba_t::copy_block(mblock_t *blk, int new_serial, int cpblk_flags)
11192{
11193 return (mblock_t *)HEXDSP(hx_mba_t_copy_block, this, blk, new_serial, cpblk_flags);
11194}
11195
11196//--------------------------------------------------------------------------
11198{
11199 return (uchar)(size_t)HEXDSP(hx_mba_t_remove_empty_and_unreachable_blocks, this) != 0;
11200}
11201
11202//--------------------------------------------------------------------------
11203inline bool mba_t::combine_blocks(void)
11204{
11205 return (uchar)(size_t)HEXDSP(hx_mba_t_combine_blocks, this) != 0;
11206}
11207
11208//--------------------------------------------------------------------------
11210{
11211 return (int)(size_t)HEXDSP(hx_mba_t_for_all_ops, this, &mv);
11212}
11213
11214//--------------------------------------------------------------------------
11216{
11217 return (int)(size_t)HEXDSP(hx_mba_t_for_all_insns, this, &mv);
11218}
11219
11220//--------------------------------------------------------------------------
11222{
11223 return (int)(size_t)HEXDSP(hx_mba_t_for_all_topinsns, this, &mv);
11224}
11225
11226//--------------------------------------------------------------------------
11227inline mop_t *mba_t::find_mop(op_parent_info_t *ctx, ea_t ea, bool is_dest, const mlist_t &list)
11228{
11229 return (mop_t *)HEXDSP(hx_mba_t_find_mop, this, ctx, ea, is_dest, &list);
11230}
11231
11232//--------------------------------------------------------------------------
11233inline minsn_t *mba_t::create_helper_call(ea_t ea, const char *helper, const tinfo_t *rettype, const mcallargs_t *callargs, const mop_t *out)
11234{
11235 return (minsn_t *)HEXDSP(hx_mba_t_create_helper_call, this, ea, helper, rettype, callargs, out);
11236}
11237
11238//--------------------------------------------------------------------------
11239inline lvar_t &mba_t::arg(int n)
11240{
11241 return *(lvar_t *)HEXDSP(hx_mba_t_arg, this, n);
11242}
11243
11244//--------------------------------------------------------------------------
11245inline ea_t mba_t::alloc_fict_ea(ea_t real_ea)
11246{
11247 ea_t retval;
11248 HEXDSP(hx_mba_t_alloc_fict_ea, &retval, this, real_ea);
11249 return retval;
11250}
11251
11252//--------------------------------------------------------------------------
11253inline ea_t mba_t::map_fict_ea(ea_t fict_ea) const
11254{
11255 ea_t retval;
11256 HEXDSP(hx_mba_t_map_fict_ea, &retval, this, fict_ea);
11257 return retval;
11258}
11259
11260//--------------------------------------------------------------------------
11261inline void mba_t::serialize(bytevec_t &vout) const
11262{
11263 HEXDSP(hx_mba_t_serialize, this, &vout);
11264}
11265
11266//--------------------------------------------------------------------------
11267inline WARN_UNUSED_RESULT mba_t *mba_t::deserialize(const uchar *bytes, size_t nbytes)
11268{
11269 return (mba_t *)HEXDSP(hx_mba_t_deserialize, bytes, nbytes);
11270}
11271
11272//--------------------------------------------------------------------------
11273inline void mba_t::save_snapshot(const char *description)
11274{
11275 HEXDSP(hx_mba_t_save_snapshot, this, description);
11276}
11277
11278//--------------------------------------------------------------------------
11279inline mreg_t mba_t::alloc_kreg(size_t size, bool check_size)
11280{
11281 return (mreg_t)(size_t)HEXDSP(hx_mba_t_alloc_kreg, this, size, check_size);
11282}
11283
11284//--------------------------------------------------------------------------
11285inline void mba_t::free_kreg(mreg_t reg, size_t size)
11286{
11287 HEXDSP(hx_mba_t_free_kreg, this, reg, size);
11288}
11289
11290//--------------------------------------------------------------------------
11291inline bool mbl_graph_t::is_accessed_globally(const mlist_t &list, int b1, int b2, const minsn_t *m1, const minsn_t *m2, access_type_t access_type, maymust_t maymust) const
11292{
11293 return (uchar)(size_t)HEXDSP(hx_mbl_graph_t_is_accessed_globally, this, &list, b1, b2, m1, m2, access_type, maymust) != 0;
11294}
11295
11296//--------------------------------------------------------------------------
11298{
11299 return (graph_chains_t *)HEXDSP(hx_mbl_graph_t_get_ud, this, gctype);
11300}
11301
11302//--------------------------------------------------------------------------
11304{
11305 return (graph_chains_t *)HEXDSP(hx_mbl_graph_t_get_du, this, gctype);
11306}
11307
11308//--------------------------------------------------------------------------
11309inline merror_t cdg_insn_iterator_t::next(insn_t *ins)
11310{
11311 return (merror_t)(size_t)HEXDSP(hx_cdg_insn_iterator_t_next, this, ins);
11312}
11313
11314//--------------------------------------------------------------------------
11315inline minsn_t *codegen_t::emit(mcode_t code, int width, uval_t l, uval_t r, uval_t d, int offsize)
11316{
11317 return (minsn_t *)HEXDSP(hx_codegen_t_emit, this, code, width, l, r, d, offsize);
11318}
11319
11320//--------------------------------------------------------------------------
11321inline minsn_t *codegen_t::emit(mcode_t code, const mop_t *l, const mop_t *r, const mop_t *d)
11322{
11323 return (minsn_t *)HEXDSP(hx_codegen_t_emit_, this, code, l, r, d);
11324}
11325
11326//--------------------------------------------------------------------------
11327inline const char *get_hexrays_version(void)
11328{
11329 return (const char *)HEXDSP(hx_get_hexrays_version);
11330}
11331
11332//--------------------------------------------------------------------------
11333inline bool checkout_hexrays_license(bool silent)
11334{
11335 return (uchar)(size_t)HEXDSP(hx_checkout_hexrays_license, silent) != 0;
11336}
11337
11338//--------------------------------------------------------------------------
11339inline vdui_t *open_pseudocode(ea_t ea, int flags)
11340{
11341 return (vdui_t *)HEXDSP(hx_open_pseudocode, ea, flags);
11342}
11343
11344//--------------------------------------------------------------------------
11346{
11347 return (uchar)(size_t)HEXDSP(hx_close_pseudocode, f) != 0;
11348}
11349
11350//--------------------------------------------------------------------------
11352{
11353 return (vdui_t *)HEXDSP(hx_get_widget_vdui, f);
11354}
11355
11356//--------------------------------------------------------------------------
11357inline bool decompile_many(const char *outfile, const eavec_t *funcaddrs, int flags)
11358{
11359 return (uchar)(size_t)HEXDSP(hx_decompile_many, outfile, funcaddrs, flags) != 0;
11360}
11361
11362//--------------------------------------------------------------------------
11363inline qstring hexrays_failure_t::desc(void) const
11364{
11365 qstring retval;
11366 HEXDSP(hx_hexrays_failure_t_desc, &retval, this);
11367 return retval;
11368}
11369
11370//--------------------------------------------------------------------------
11371inline void send_database(const hexrays_failure_t &err, bool silent)
11372{
11373 HEXDSP(hx_send_database, &err, silent);
11374}
11375
11376//--------------------------------------------------------------------------
11377inline bool gco_info_t::append_to_list(mlist_t *list, const mba_t *mba) const
11378{
11379 return (uchar)(size_t)HEXDSP(hx_gco_info_t_append_to_list, this, list, mba) != 0;
11380}
11381
11382//--------------------------------------------------------------------------
11384{
11385 return (uchar)(size_t)HEXDSP(hx_get_current_operand, out) != 0;
11386}
11387
11388//--------------------------------------------------------------------------
11389inline void remitem(const citem_t *e)
11390{
11391 HEXDSP(hx_remitem, e);
11392}
11393
11394//--------------------------------------------------------------------------
11396{
11397 return (ctype_t)(size_t)HEXDSP(hx_negated_relation, op);
11398}
11399
11400//--------------------------------------------------------------------------
11402{
11403 return (ctype_t)(size_t)HEXDSP(hx_swapped_relation, op);
11404}
11405
11406//--------------------------------------------------------------------------
11407inline type_sign_t get_op_signness(ctype_t op)
11408{
11409 return (type_sign_t)(size_t)HEXDSP(hx_get_op_signness, op);
11410}
11411
11412//--------------------------------------------------------------------------
11414{
11415 return (ctype_t)(size_t)HEXDSP(hx_asgop, cop);
11416}
11417
11418//--------------------------------------------------------------------------
11420{
11421 return (ctype_t)(size_t)HEXDSP(hx_asgop_revert, cop);
11422}
11423
11424//--------------------------------------------------------------------------
11425inline void cnumber_t::print(qstring *vout, const tinfo_t &type, const citem_t *parent, bool *nice_stroff) const
11426{
11427 HEXDSP(hx_cnumber_t_print, this, vout, &type, parent, nice_stroff);
11428}
11429
11430//--------------------------------------------------------------------------
11431inline uint64 cnumber_t::value(const tinfo_t &type) const
11432{
11433 uint64 retval;
11434 HEXDSP(hx_cnumber_t_value, &retval, this, &type);
11435 return retval;
11436}
11437
11438//--------------------------------------------------------------------------
11439inline void cnumber_t::assign(uint64 v, int nbytes, type_sign_t sign)
11440{
11441 HEXDSP(hx_cnumber_t_assign, this, v, nbytes, sign);
11442}
11443
11444//--------------------------------------------------------------------------
11445inline int cnumber_t::compare(const cnumber_t &r) const
11446{
11447 return (int)(size_t)HEXDSP(hx_cnumber_t_compare, this, &r);
11448}
11449
11450//--------------------------------------------------------------------------
11451inline int var_ref_t::compare(const var_ref_t &r) const
11452{
11453 return (int)(size_t)HEXDSP(hx_var_ref_t_compare, this, &r);
11454}
11455
11456//--------------------------------------------------------------------------
11458{
11459 return (int)(size_t)HEXDSP(hx_ctree_visitor_t_apply_to, this, item, parent);
11460}
11461
11462//--------------------------------------------------------------------------
11464{
11465 return (int)(size_t)HEXDSP(hx_ctree_visitor_t_apply_to_exprs, this, item, parent);
11466}
11467
11468//--------------------------------------------------------------------------
11470{
11471 return (uchar)(size_t)HEXDSP(hx_ctree_parentee_t_recalc_parent_types, this) != 0;
11472}
11473
11474//--------------------------------------------------------------------------
11475inline bool cfunc_parentee_t::calc_rvalue_type(tinfo_t *target, const cexpr_t *e)
11476{
11477 return (uchar)(size_t)HEXDSP(hx_cfunc_parentee_t_calc_rvalue_type, this, target, e) != 0;
11478}
11479
11480//--------------------------------------------------------------------------
11481inline int citem_locator_t::compare(const citem_locator_t &r) const
11482{
11483 return (int)(size_t)HEXDSP(hx_citem_locator_t_compare, this, &r);
11484}
11485
11486//--------------------------------------------------------------------------
11487inline bool citem_t::contains_expr(const cexpr_t *e) const
11488{
11489 return (uchar)(size_t)HEXDSP(hx_citem_t_contains_expr, this, e) != 0;
11490}
11491
11492//--------------------------------------------------------------------------
11493inline bool citem_t::contains_label(void) const
11494{
11495 return (uchar)(size_t)HEXDSP(hx_citem_t_contains_label, this) != 0;
11496}
11497
11498//--------------------------------------------------------------------------
11499inline const citem_t *citem_t::find_parent_of(const citem_t *sitem) const
11500{
11501 return (const citem_t *)HEXDSP(hx_citem_t_find_parent_of, this, sitem);
11502}
11503
11504//--------------------------------------------------------------------------
11505inline citem_t *citem_t::find_closest_addr(ea_t _ea)
11506{
11507 return (citem_t *)HEXDSP(hx_citem_t_find_closest_addr, this, _ea);
11508}
11509
11510//--------------------------------------------------------------------------
11511inline cexpr_t &cexpr_t::assign(const cexpr_t &r)
11512{
11513 return *(cexpr_t *)HEXDSP(hx_cexpr_t_assign, this, &r);
11514}
11515
11516//--------------------------------------------------------------------------
11517inline int cexpr_t::compare(const cexpr_t &r) const
11518{
11519 return (int)(size_t)HEXDSP(hx_cexpr_t_compare, this, &r);
11520}
11521
11522//--------------------------------------------------------------------------
11524{
11525 HEXDSP(hx_cexpr_t_replace_by, this, r);
11526}
11527
11528//--------------------------------------------------------------------------
11529inline void cexpr_t::cleanup(void)
11530{
11531 HEXDSP(hx_cexpr_t_cleanup, this);
11532}
11533
11534//--------------------------------------------------------------------------
11535inline void cexpr_t::put_number(cfunc_t *func, uint64 value, int nbytes, type_sign_t sign)
11536{
11537 HEXDSP(hx_cexpr_t_put_number, this, func, value, nbytes, sign);
11538}
11539
11540//--------------------------------------------------------------------------
11541inline void cexpr_t::print1(qstring *vout, const cfunc_t *func) const
11542{
11543 HEXDSP(hx_cexpr_t_print1, this, vout, func);
11544}
11545
11546//--------------------------------------------------------------------------
11547inline void cexpr_t::calc_type(bool recursive)
11548{
11549 HEXDSP(hx_cexpr_t_calc_type, this, recursive);
11550}
11551
11552//--------------------------------------------------------------------------
11553inline bool cexpr_t::equal_effect(const cexpr_t &r) const
11554{
11555 return (uchar)(size_t)HEXDSP(hx_cexpr_t_equal_effect, this, &r) != 0;
11556}
11557
11558//--------------------------------------------------------------------------
11559inline bool cexpr_t::is_child_of(const citem_t *parent) const
11560{
11561 return (uchar)(size_t)HEXDSP(hx_cexpr_t_is_child_of, this, parent) != 0;
11562}
11563
11564//--------------------------------------------------------------------------
11565inline bool cexpr_t::contains_operator(ctype_t needed_op, int times) const
11566{
11567 return (uchar)(size_t)HEXDSP(hx_cexpr_t_contains_operator, this, needed_op, times) != 0;
11568}
11569
11570//--------------------------------------------------------------------------
11572{
11573 bit_bound_t retval;
11574 HEXDSP(hx_cexpr_t_get_high_nbit_bound, &retval, this);
11575 return retval;
11576}
11577
11578//--------------------------------------------------------------------------
11579inline int cexpr_t::get_low_nbit_bound(void) const
11580{
11581 return (int)(size_t)HEXDSP(hx_cexpr_t_get_low_nbit_bound, this);
11582}
11583
11584//--------------------------------------------------------------------------
11585inline bool cexpr_t::requires_lvalue(const cexpr_t *child) const
11586{
11587 return (uchar)(size_t)HEXDSP(hx_cexpr_t_requires_lvalue, this, child) != 0;
11588}
11589
11590//--------------------------------------------------------------------------
11591inline bool cexpr_t::has_side_effects(void) const
11592{
11593 return (uchar)(size_t)HEXDSP(hx_cexpr_t_has_side_effects, this) != 0;
11594}
11595
11596//--------------------------------------------------------------------------
11597inline bool cexpr_t::maybe_ptr(void) const
11598{
11599 return (uchar)(size_t)HEXDSP(hx_cexpr_t_maybe_ptr, this) != 0;
11600}
11601
11602//--------------------------------------------------------------------------
11603inline cif_t &cif_t::assign(const cif_t &r)
11604{
11605 return *(cif_t *)HEXDSP(hx_cif_t_assign, this, &r);
11606}
11607
11608//--------------------------------------------------------------------------
11609inline int cif_t::compare(const cif_t &r) const
11610{
11611 return (int)(size_t)HEXDSP(hx_cif_t_compare, this, &r);
11612}
11613
11614//--------------------------------------------------------------------------
11615inline cloop_t &cloop_t::assign(const cloop_t &r)
11616{
11617 return *(cloop_t *)HEXDSP(hx_cloop_t_assign, this, &r);
11618}
11619
11620//--------------------------------------------------------------------------
11621inline int cfor_t::compare(const cfor_t &r) const
11622{
11623 return (int)(size_t)HEXDSP(hx_cfor_t_compare, this, &r);
11624}
11625
11626//--------------------------------------------------------------------------
11627inline int cwhile_t::compare(const cwhile_t &r) const
11628{
11629 return (int)(size_t)HEXDSP(hx_cwhile_t_compare, this, &r);
11630}
11631
11632//--------------------------------------------------------------------------
11633inline int cdo_t::compare(const cdo_t &r) const
11634{
11635 return (int)(size_t)HEXDSP(hx_cdo_t_compare, this, &r);
11636}
11637
11638//--------------------------------------------------------------------------
11639inline int creturn_t::compare(const creturn_t &r) const
11640{
11641 return (int)(size_t)HEXDSP(hx_creturn_t_compare, this, &r);
11642}
11643
11644//--------------------------------------------------------------------------
11645inline int cgoto_t::compare(const cgoto_t &r) const
11646{
11647 return (int)(size_t)HEXDSP(hx_cgoto_t_compare, this, &r);
11648}
11649
11650//--------------------------------------------------------------------------
11651inline int casm_t::compare(const casm_t &r) const
11652{
11653 return (int)(size_t)HEXDSP(hx_casm_t_compare, this, &r);
11654}
11655
11656//--------------------------------------------------------------------------
11657inline cinsn_t &cinsn_t::assign(const cinsn_t &r)
11658{
11659 return *(cinsn_t *)HEXDSP(hx_cinsn_t_assign, this, &r);
11660}
11661
11662//--------------------------------------------------------------------------
11663inline int cinsn_t::compare(const cinsn_t &r) const
11664{
11665 return (int)(size_t)HEXDSP(hx_cinsn_t_compare, this, &r);
11666}
11667
11668//--------------------------------------------------------------------------
11670{
11671 HEXDSP(hx_cinsn_t_replace_by, this, r);
11672}
11673
11674//--------------------------------------------------------------------------
11675inline void cinsn_t::cleanup(void)
11676{
11677 HEXDSP(hx_cinsn_t_cleanup, this);
11678}
11679
11680//--------------------------------------------------------------------------
11681inline cinsn_t &cinsn_t::new_insn(ea_t insn_ea)
11682{
11683 return *(cinsn_t *)HEXDSP(hx_cinsn_t_new_insn, this, insn_ea);
11684}
11685
11686//--------------------------------------------------------------------------
11688{
11689 return *(cif_t *)HEXDSP(hx_cinsn_t_create_if, this, cnd);
11690}
11691
11692//--------------------------------------------------------------------------
11693inline void cinsn_t::print(int indent, vc_printer_t &vp, use_curly_t use_curly) const
11694{
11695 HEXDSP(hx_cinsn_t_print, this, indent, &vp, use_curly);
11696}
11697
11698//--------------------------------------------------------------------------
11699inline void cinsn_t::print1(qstring *vout, const cfunc_t *func) const
11700{
11701 HEXDSP(hx_cinsn_t_print1, this, vout, func);
11702}
11703
11704//--------------------------------------------------------------------------
11705inline bool cinsn_t::is_ordinary_flow(void) const
11706{
11707 return (uchar)(size_t)HEXDSP(hx_cinsn_t_is_ordinary_flow, this) != 0;
11708}
11709
11710//--------------------------------------------------------------------------
11711inline bool cinsn_t::contains_insn(ctype_t type, int times) const
11712{
11713 return (uchar)(size_t)HEXDSP(hx_cinsn_t_contains_insn, this, type, times) != 0;
11714}
11715
11716//--------------------------------------------------------------------------
11718{
11719 return (uchar)(size_t)HEXDSP(hx_cinsn_t_collect_free_breaks, this, breaks) != 0;
11720}
11721
11722//--------------------------------------------------------------------------
11724{
11725 return (uchar)(size_t)HEXDSP(hx_cinsn_t_collect_free_continues, this, continues) != 0;
11726}
11727
11728//--------------------------------------------------------------------------
11729inline int cblock_t::compare(const cblock_t &r) const
11730{
11731 return (int)(size_t)HEXDSP(hx_cblock_t_compare, this, &r);
11732}
11733
11734//--------------------------------------------------------------------------
11735inline int carglist_t::compare(const carglist_t &r) const
11736{
11737 return (int)(size_t)HEXDSP(hx_carglist_t_compare, this, &r);
11738}
11739
11740//--------------------------------------------------------------------------
11741inline int ccase_t::compare(const ccase_t &r) const
11742{
11743 return (int)(size_t)HEXDSP(hx_ccase_t_compare, this, &r);
11744}
11745
11746//--------------------------------------------------------------------------
11747inline int ccases_t::compare(const ccases_t &r) const
11748{
11749 return (int)(size_t)HEXDSP(hx_ccases_t_compare, this, &r);
11750}
11751
11752//--------------------------------------------------------------------------
11753inline int cswitch_t::compare(const cswitch_t &r) const
11754{
11755 return (int)(size_t)HEXDSP(hx_cswitch_t_compare, this, &r);
11756}
11757
11758//--------------------------------------------------------------------------
11759inline member_t *ctree_item_t::get_memptr(struc_t **p_sptr) const
11760{
11761 return (member_t *)HEXDSP(hx_ctree_item_t_get_memptr, this, p_sptr);
11762}
11763
11764//--------------------------------------------------------------------------
11766{
11767 return (lvar_t *)HEXDSP(hx_ctree_item_t_get_lvar, this);
11768}
11769
11770//--------------------------------------------------------------------------
11771inline ea_t ctree_item_t::get_ea(void) const
11772{
11773 ea_t retval;
11774 HEXDSP(hx_ctree_item_t_get_ea, &retval, this);
11775 return retval;
11776}
11777
11778//--------------------------------------------------------------------------
11779inline int ctree_item_t::get_label_num(int gln_flags) const
11780{
11781 return (int)(size_t)HEXDSP(hx_ctree_item_t_get_label_num, this, gln_flags);
11782}
11783
11784//--------------------------------------------------------------------------
11786{
11787 return (cexpr_t *)HEXDSP(hx_lnot, e);
11788}
11789
11790//--------------------------------------------------------------------------
11791inline cinsn_t *new_block(void)
11792{
11793 return (cinsn_t *)HEXDSP(hx_new_block);
11794}
11795
11796//--------------------------------------------------------------------------
11797inline AS_PRINTF(3, 0) cexpr_t *vcreate_helper(bool standalone, const tinfo_t &type, const char *format, va_list va)
11798{
11799 return (cexpr_t *)HEXDSP(hx_vcreate_helper, standalone, &type, format, va);
11800}
11801
11802//--------------------------------------------------------------------------
11803inline AS_PRINTF(3, 0) cexpr_t *vcall_helper(const tinfo_t &rettype, carglist_t *args, const char *format, va_list va)
11804{
11805 return (cexpr_t *)HEXDSP(hx_vcall_helper, &rettype, args, format, va);
11806}
11807
11808//--------------------------------------------------------------------------
11809inline cexpr_t *make_num(uint64 n, cfunc_t *func, ea_t ea, int opnum, type_sign_t sign, int size)
11810{
11811 return (cexpr_t *)HEXDSP(hx_make_num, n, func, ea, opnum, sign, size);
11812}
11813
11814//--------------------------------------------------------------------------
11816{
11817 return (cexpr_t *)HEXDSP(hx_make_ref, e);
11818}
11819
11820//--------------------------------------------------------------------------
11821inline cexpr_t *dereference(cexpr_t *e, int ptrsize, bool is_flt)
11822{
11823 return (cexpr_t *)HEXDSP(hx_dereference, e, ptrsize, is_flt);
11824}
11825
11826//--------------------------------------------------------------------------
11827inline void save_user_labels(ea_t func_ea, const user_labels_t *user_labels)
11828{
11829 HEXDSP(hx_save_user_labels, func_ea, user_labels);
11830}
11831
11832//--------------------------------------------------------------------------
11833inline void save_user_labels2(ea_t func_ea, const user_labels_t *user_labels, const cfunc_t *func)
11834{
11835 HEXDSP(hx_save_user_labels2, func_ea, user_labels, func);
11836}
11837
11838//--------------------------------------------------------------------------
11839inline void save_user_cmts(ea_t func_ea, const user_cmts_t *user_cmts)
11840{
11841 HEXDSP(hx_save_user_cmts, func_ea, user_cmts);
11842}
11843
11844//--------------------------------------------------------------------------
11845inline void save_user_numforms(ea_t func_ea, const user_numforms_t *numforms)
11846{
11847 HEXDSP(hx_save_user_numforms, func_ea, numforms);
11848}
11849
11850//--------------------------------------------------------------------------
11851inline void save_user_iflags(ea_t func_ea, const user_iflags_t *iflags)
11852{
11853 HEXDSP(hx_save_user_iflags, func_ea, iflags);
11854}
11855
11856//--------------------------------------------------------------------------
11857inline void save_user_unions(ea_t func_ea, const user_unions_t *unions)
11858{
11859 HEXDSP(hx_save_user_unions, func_ea, unions);
11860}
11861
11862//--------------------------------------------------------------------------
11864{
11865 return (user_labels_t *)HEXDSP(hx_restore_user_labels, func_ea);
11866}
11867
11868//--------------------------------------------------------------------------
11869inline user_labels_t *restore_user_labels2(ea_t func_ea, const cfunc_t *func)
11870{
11871 return (user_labels_t *)HEXDSP(hx_restore_user_labels2, func_ea, func);
11872}
11873
11874//--------------------------------------------------------------------------
11875inline user_cmts_t *restore_user_cmts(ea_t func_ea)
11876{
11877 return (user_cmts_t *)HEXDSP(hx_restore_user_cmts, func_ea);
11878}
11879
11880//--------------------------------------------------------------------------
11882{
11883 return (user_numforms_t *)HEXDSP(hx_restore_user_numforms, func_ea);
11884}
11885
11886//--------------------------------------------------------------------------
11887inline user_iflags_t *restore_user_iflags(ea_t func_ea)
11888{
11889 return (user_iflags_t *)HEXDSP(hx_restore_user_iflags, func_ea);
11890}
11891
11892//--------------------------------------------------------------------------
11893inline user_unions_t *restore_user_unions(ea_t func_ea)
11894{
11895 return (user_unions_t *)HEXDSP(hx_restore_user_unions, func_ea);
11896}
11897
11898//--------------------------------------------------------------------------
11899inline void cfunc_t::build_c_tree(void)
11900{
11901 HEXDSP(hx_cfunc_t_build_c_tree, this);
11902}
11903
11904//--------------------------------------------------------------------------
11905inline void cfunc_t::verify(allow_unused_labels_t aul, bool even_without_debugger) const
11906{
11907 HEXDSP(hx_cfunc_t_verify, this, aul, even_without_debugger);
11908}
11909
11910//--------------------------------------------------------------------------
11911inline void cfunc_t::print_dcl(qstring *vout) const
11912{
11913 HEXDSP(hx_cfunc_t_print_dcl, this, vout);
11914}
11915
11916//--------------------------------------------------------------------------
11917inline void cfunc_t::print_func(vc_printer_t &vp) const
11918{
11919 HEXDSP(hx_cfunc_t_print_func, this, &vp);
11920}
11921
11922//--------------------------------------------------------------------------
11923inline bool cfunc_t::get_func_type(tinfo_t *type) const
11924{
11925 return (uchar)(size_t)HEXDSP(hx_cfunc_t_get_func_type, this, type) != 0;
11926}
11927
11928//--------------------------------------------------------------------------
11930{
11931 return (lvars_t *)HEXDSP(hx_cfunc_t_get_lvars, this);
11932}
11933
11934//--------------------------------------------------------------------------
11935inline sval_t cfunc_t::get_stkoff_delta(void)
11936{
11937 sval_t retval;
11938 HEXDSP(hx_cfunc_t_get_stkoff_delta, &retval, this);
11939 return retval;
11940}
11941
11942//--------------------------------------------------------------------------
11944{
11945 return (citem_t *)HEXDSP(hx_cfunc_t_find_label, this, label);
11946}
11947
11948//--------------------------------------------------------------------------
11950{
11951 HEXDSP(hx_cfunc_t_remove_unused_labels, this);
11952}
11953
11954//--------------------------------------------------------------------------
11955inline const char *cfunc_t::get_user_cmt(const treeloc_t &loc, cmt_retrieval_type_t rt) const
11956{
11957 return (const char *)HEXDSP(hx_cfunc_t_get_user_cmt, this, &loc, rt);
11958}
11959
11960//--------------------------------------------------------------------------
11961inline void cfunc_t::set_user_cmt(const treeloc_t &loc, const char *cmt)
11962{
11963 HEXDSP(hx_cfunc_t_set_user_cmt, this, &loc, cmt);
11964}
11965
11966//--------------------------------------------------------------------------
11967inline int32 cfunc_t::get_user_iflags(const citem_locator_t &loc) const
11968{
11969 return (int32)(size_t)HEXDSP(hx_cfunc_t_get_user_iflags, this, &loc);
11970}
11971
11972//--------------------------------------------------------------------------
11973inline void cfunc_t::set_user_iflags(const citem_locator_t &loc, int32 iflags)
11974{
11975 HEXDSP(hx_cfunc_t_set_user_iflags, this, &loc, iflags);
11976}
11977
11978//--------------------------------------------------------------------------
11979inline bool cfunc_t::has_orphan_cmts(void) const
11980{
11981 return (uchar)(size_t)HEXDSP(hx_cfunc_t_has_orphan_cmts, this) != 0;
11982}
11983
11984//--------------------------------------------------------------------------
11986{
11987 return (int)(size_t)HEXDSP(hx_cfunc_t_del_orphan_cmts, this);
11988}
11989
11990//--------------------------------------------------------------------------
11991inline bool cfunc_t::get_user_union_selection(ea_t ea, intvec_t *path)
11992{
11993 return (uchar)(size_t)HEXDSP(hx_cfunc_t_get_user_union_selection, this, ea, path) != 0;
11994}
11995
11996//--------------------------------------------------------------------------
11997inline void cfunc_t::set_user_union_selection(ea_t ea, const intvec_t &path)
11998{
11999 HEXDSP(hx_cfunc_t_set_user_union_selection, this, ea, &path);
12000}
12001
12002//--------------------------------------------------------------------------
12003inline void cfunc_t::save_user_labels(void) const
12004{
12005 HEXDSP(hx_cfunc_t_save_user_labels, this);
12006}
12007
12008//--------------------------------------------------------------------------
12009inline void cfunc_t::save_user_cmts(void) const
12010{
12011 HEXDSP(hx_cfunc_t_save_user_cmts, this);
12012}
12013
12014//--------------------------------------------------------------------------
12015inline void cfunc_t::save_user_numforms(void) const
12016{
12017 HEXDSP(hx_cfunc_t_save_user_numforms, this);
12018}
12019
12020//--------------------------------------------------------------------------
12021inline void cfunc_t::save_user_iflags(void) const
12022{
12023 HEXDSP(hx_cfunc_t_save_user_iflags, this);
12024}
12025
12026//--------------------------------------------------------------------------
12027inline void cfunc_t::save_user_unions(void) const
12028{
12029 HEXDSP(hx_cfunc_t_save_user_unions, this);
12030}
12031
12032//--------------------------------------------------------------------------
12033inline bool cfunc_t::get_line_item(const char *line, int x, bool is_ctree_line, ctree_item_t *phead, ctree_item_t *pitem, ctree_item_t *ptail)
12034{
12035 return (uchar)(size_t)HEXDSP(hx_cfunc_t_get_line_item, this, line, x, is_ctree_line, phead, pitem, ptail) != 0;
12036}
12037
12038//--------------------------------------------------------------------------
12039inline hexwarns_t &cfunc_t::get_warnings(void)
12040{
12041 return *(hexwarns_t *)HEXDSP(hx_cfunc_t_get_warnings, this);
12042}
12043
12044//--------------------------------------------------------------------------
12045inline eamap_t &cfunc_t::get_eamap(void)
12046{
12047 return *(eamap_t *)HEXDSP(hx_cfunc_t_get_eamap, this);
12048}
12049
12050//--------------------------------------------------------------------------
12051inline boundaries_t &cfunc_t::get_boundaries(void)
12052{
12053 return *(boundaries_t *)HEXDSP(hx_cfunc_t_get_boundaries, this);
12054}
12055
12056//--------------------------------------------------------------------------
12058{
12059 return *(const strvec_t *)HEXDSP(hx_cfunc_t_get_pseudocode, this);
12060}
12061
12062//--------------------------------------------------------------------------
12064{
12065 HEXDSP(hx_cfunc_t_refresh_func_ctext, this);
12066}
12067
12068//--------------------------------------------------------------------------
12069inline bool cfunc_t::gather_derefs(const ctree_item_t &ci, udt_type_data_t *udm) const
12070{
12071 return (uchar)(size_t)HEXDSP(hx_cfunc_t_gather_derefs, this, &ci, udm) != 0;
12072}
12073
12074//--------------------------------------------------------------------------
12075inline bool cfunc_t::find_item_coords(const citem_t *item, int *px, int *py)
12076{
12077 return (uchar)(size_t)HEXDSP(hx_cfunc_t_find_item_coords, this, item, px, py) != 0;
12078}
12079
12080//--------------------------------------------------------------------------
12081inline void cfunc_t::cleanup(void)
12082{
12083 HEXDSP(hx_cfunc_t_cleanup, this);
12084}
12085
12086//--------------------------------------------------------------------------
12087inline void close_hexrays_waitbox(void)
12088{
12089 HEXDSP(hx_close_hexrays_waitbox);
12090}
12091
12092//--------------------------------------------------------------------------
12093inline cfuncptr_t decompile(const mba_ranges_t &mbr, hexrays_failure_t *hf, int decomp_flags)
12094{
12095 return cfuncptr_t((cfunc_t *)HEXDSP(hx_decompile, &mbr, hf, decomp_flags));
12096}
12097
12098//--------------------------------------------------------------------------
12099inline mba_t *gen_microcode(const mba_ranges_t &mbr, hexrays_failure_t *hf, const mlist_t *retlist, int decomp_flags, mba_maturity_t reqmat)
12100{
12101 return (mba_t *)HEXDSP(hx_gen_microcode, &mbr, hf, retlist, decomp_flags, reqmat);
12102}
12103
12104//--------------------------------------------------------------------------
12105inline cfuncptr_t create_cfunc(mba_t *mba)
12106{
12107 return cfuncptr_t((cfunc_t *)HEXDSP(hx_create_cfunc, mba));
12108}
12109
12110//--------------------------------------------------------------------------
12111inline bool mark_cfunc_dirty(ea_t ea, bool close_views)
12112{
12113 return (uchar)(size_t)HEXDSP(hx_mark_cfunc_dirty, ea, close_views) != 0;
12114}
12115
12116//--------------------------------------------------------------------------
12117inline void clear_cached_cfuncs(void)
12118{
12119 HEXDSP(hx_clear_cached_cfuncs);
12120}
12121
12122//--------------------------------------------------------------------------
12123inline bool has_cached_cfunc(ea_t ea)
12124{
12125 return (uchar)(size_t)HEXDSP(hx_has_cached_cfunc, ea) != 0;
12126}
12127
12128//--------------------------------------------------------------------------
12129inline const char *get_ctype_name(ctype_t op)
12130{
12131 return (const char *)HEXDSP(hx_get_ctype_name, op);
12132}
12133
12134//--------------------------------------------------------------------------
12135inline qstring create_field_name(const tinfo_t &type, uval_t offset)
12136{
12137 qstring retval;
12138 HEXDSP(hx_create_field_name, &retval, &type, offset);
12139 return retval;
12140}
12141
12142//--------------------------------------------------------------------------
12143inline bool install_hexrays_callback(hexrays_cb_t *callback, void *ud)
12144{
12145 return (uchar)(size_t)HEXDSP(hx_install_hexrays_callback, callback, ud) != 0;
12146}
12147
12148//--------------------------------------------------------------------------
12149inline int remove_hexrays_callback(hexrays_cb_t *callback, void *ud)
12150{
12151 auto hrdsp = HEXDSP;
12152 return hrdsp == nullptr ? 0 : (int)(size_t)hrdsp(hx_remove_hexrays_callback, callback, ud);
12153}
12154
12155//--------------------------------------------------------------------------
12156inline bool vdui_t::set_locked(bool v)
12157{
12158 return (uchar)(size_t)HEXDSP(hx_vdui_t_set_locked, this, v) != 0;
12159}
12160
12161//--------------------------------------------------------------------------
12162inline void vdui_t::refresh_view(bool redo_mba)
12163{
12164 HEXDSP(hx_vdui_t_refresh_view, this, redo_mba);
12165}
12166
12167//--------------------------------------------------------------------------
12168inline void vdui_t::refresh_ctext(bool activate)
12169{
12170 HEXDSP(hx_vdui_t_refresh_ctext, this, activate);
12171}
12172
12173//--------------------------------------------------------------------------
12174inline void vdui_t::switch_to(cfuncptr_t f, bool activate)
12175{
12176 HEXDSP(hx_vdui_t_switch_to, this, &f, activate);
12177}
12178
12179//--------------------------------------------------------------------------
12181{
12182 return (cnumber_t *)HEXDSP(hx_vdui_t_get_number, this);
12183}
12184
12185//--------------------------------------------------------------------------
12187{
12188 return (int)(size_t)HEXDSP(hx_vdui_t_get_current_label, this);
12189}
12190
12191//--------------------------------------------------------------------------
12192inline void vdui_t::clear(void)
12193{
12194 HEXDSP(hx_vdui_t_clear, this);
12195}
12196
12197//--------------------------------------------------------------------------
12199{
12200 return (uchar)(size_t)HEXDSP(hx_vdui_t_refresh_cpos, this, idv) != 0;
12201}
12202
12203//--------------------------------------------------------------------------
12205{
12206 return (uchar)(size_t)HEXDSP(hx_vdui_t_get_current_item, this, idv) != 0;
12207}
12208
12209//--------------------------------------------------------------------------
12211{
12212 return (uchar)(size_t)HEXDSP(hx_vdui_t_ui_rename_lvar, this, v) != 0;
12213}
12214
12215//--------------------------------------------------------------------------
12216inline bool vdui_t::rename_lvar(lvar_t *v, const char *name, bool is_user_name)
12217{
12218 return (uchar)(size_t)HEXDSP(hx_vdui_t_rename_lvar, this, v, name, is_user_name) != 0;
12219}
12220
12221//--------------------------------------------------------------------------
12223{
12224 return (uchar)(size_t)HEXDSP(hx_vdui_t_ui_set_call_type, this, e) != 0;
12225}
12226
12227//--------------------------------------------------------------------------
12229{
12230 return (uchar)(size_t)HEXDSP(hx_vdui_t_ui_set_lvar_type, this, v) != 0;
12231}
12232
12233//--------------------------------------------------------------------------
12234inline bool vdui_t::set_lvar_type(lvar_t *v, const tinfo_t &type)
12235{
12236 return (uchar)(size_t)HEXDSP(hx_vdui_t_set_lvar_type, this, v, &type) != 0;
12237}
12238
12239//--------------------------------------------------------------------------
12241{
12242 return (uchar)(size_t)HEXDSP(hx_vdui_t_set_noptr_lvar, this, v) != 0;
12243}
12244
12245//--------------------------------------------------------------------------
12247{
12248 return (uchar)(size_t)HEXDSP(hx_vdui_t_ui_edit_lvar_cmt, this, v) != 0;
12249}
12250
12251//--------------------------------------------------------------------------
12252inline bool vdui_t::set_lvar_cmt(lvar_t *v, const char *cmt)
12253{
12254 return (uchar)(size_t)HEXDSP(hx_vdui_t_set_lvar_cmt, this, v, cmt) != 0;
12255}
12256
12257//--------------------------------------------------------------------------
12259{
12260 return (uchar)(size_t)HEXDSP(hx_vdui_t_ui_map_lvar, this, v) != 0;
12261}
12262
12263//--------------------------------------------------------------------------
12265{
12266 return (uchar)(size_t)HEXDSP(hx_vdui_t_ui_unmap_lvar, this, v) != 0;
12267}
12268
12269//--------------------------------------------------------------------------
12270inline bool vdui_t::map_lvar(lvar_t *from, lvar_t *to)
12271{
12272 return (uchar)(size_t)HEXDSP(hx_vdui_t_map_lvar, this, from, to) != 0;
12273}
12274
12275//--------------------------------------------------------------------------
12276inline bool vdui_t::set_strmem_type(struc_t *sptr, member_t *mptr)
12277{
12278 return (uchar)(size_t)HEXDSP(hx_vdui_t_set_strmem_type, this, sptr, mptr) != 0;
12279}
12280
12281//--------------------------------------------------------------------------
12282inline bool vdui_t::rename_strmem(struc_t *sptr, member_t *mptr)
12283{
12284 return (uchar)(size_t)HEXDSP(hx_vdui_t_rename_strmem, this, sptr, mptr) != 0;
12285}
12286
12287//--------------------------------------------------------------------------
12288inline bool vdui_t::set_global_type(ea_t ea)
12289{
12290 return (uchar)(size_t)HEXDSP(hx_vdui_t_set_global_type, this, ea) != 0;
12291}
12292
12293//--------------------------------------------------------------------------
12294inline bool vdui_t::rename_global(ea_t ea)
12295{
12296 return (uchar)(size_t)HEXDSP(hx_vdui_t_rename_global, this, ea) != 0;
12297}
12298
12299//--------------------------------------------------------------------------
12300inline bool vdui_t::rename_label(int label)
12301{
12302 return (uchar)(size_t)HEXDSP(hx_vdui_t_rename_label, this, label) != 0;
12303}
12304
12305//--------------------------------------------------------------------------
12306inline bool vdui_t::jump_enter(input_device_t idv, int omflags)
12307{
12308 return (uchar)(size_t)HEXDSP(hx_vdui_t_jump_enter, this, idv, omflags) != 0;
12309}
12310
12311//--------------------------------------------------------------------------
12313{
12314 return (uchar)(size_t)HEXDSP(hx_vdui_t_ctree_to_disasm, this) != 0;
12315}
12316
12317//--------------------------------------------------------------------------
12318inline cmt_type_t vdui_t::calc_cmt_type(size_t lnnum, cmt_type_t cmttype) const
12319{
12320 return (cmt_type_t)(size_t)HEXDSP(hx_vdui_t_calc_cmt_type, this, lnnum, cmttype);
12321}
12322
12323//--------------------------------------------------------------------------
12324inline bool vdui_t::edit_cmt(const treeloc_t &loc)
12325{
12326 return (uchar)(size_t)HEXDSP(hx_vdui_t_edit_cmt, this, &loc) != 0;
12327}
12328
12329//--------------------------------------------------------------------------
12330inline bool vdui_t::edit_func_cmt(void)
12331{
12332 return (uchar)(size_t)HEXDSP(hx_vdui_t_edit_func_cmt, this) != 0;
12333}
12334
12335//--------------------------------------------------------------------------
12337{
12338 return (uchar)(size_t)HEXDSP(hx_vdui_t_del_orphan_cmts, this) != 0;
12339}
12340
12341//--------------------------------------------------------------------------
12342inline bool vdui_t::set_num_radix(int base)
12343{
12344 return (uchar)(size_t)HEXDSP(hx_vdui_t_set_num_radix, this, base) != 0;
12345}
12346
12347//--------------------------------------------------------------------------
12348inline bool vdui_t::set_num_enum(void)
12349{
12350 return (uchar)(size_t)HEXDSP(hx_vdui_t_set_num_enum, this) != 0;
12351}
12352
12353//--------------------------------------------------------------------------
12354inline bool vdui_t::set_num_stroff(void)
12355{
12356 return (uchar)(size_t)HEXDSP(hx_vdui_t_set_num_stroff, this) != 0;
12357}
12358
12359//--------------------------------------------------------------------------
12360inline bool vdui_t::invert_sign(void)
12361{
12362 return (uchar)(size_t)HEXDSP(hx_vdui_t_invert_sign, this) != 0;
12363}
12364
12365//--------------------------------------------------------------------------
12366inline bool vdui_t::invert_bits(void)
12367{
12368 return (uchar)(size_t)HEXDSP(hx_vdui_t_invert_bits, this) != 0;
12369}
12370
12371//--------------------------------------------------------------------------
12372inline bool vdui_t::collapse_item(bool hide)
12373{
12374 return (uchar)(size_t)HEXDSP(hx_vdui_t_collapse_item, this, hide) != 0;
12375}
12376
12377//--------------------------------------------------------------------------
12378inline bool vdui_t::collapse_lvars(bool hide)
12379{
12380 return (uchar)(size_t)HEXDSP(hx_vdui_t_collapse_lvars, this, hide) != 0;
12381}
12382
12383//--------------------------------------------------------------------------
12384inline bool vdui_t::split_item(bool split)
12385{
12386 return (uchar)(size_t)HEXDSP(hx_vdui_t_split_item, this, split) != 0;
12387}
12388
12389//--------------------------------------------------------------------------
12390inline int select_udt_by_offset(const qvector<tinfo_t> *udts, const ui_stroff_ops_t &ops, ui_stroff_applicator_t &applicator)
12391{
12392 return (int)(size_t)HEXDSP(hx_select_udt_by_offset, udts, &ops, &applicator);
12393}
12394
12395#ifdef __NT__
12396#pragma warning(pop)
12397#endif
12398#endif
IDA custom view.
Definition: hexrays.dox:72
Bit set class. See https://en.wikipedia.org/wiki/Bit_array.
Definition: hexrays.hpp:1749
Chains of one block.
Definition: hexrays.hpp:3353
const chain_t * get_stk_chain(sval_t off, int width=1) const
Get chain for the specified stack offset.
Definition: hexrays.hpp:3368
const chain_t * get_reg_chain(mreg_t reg, int width=1) const
Get chain for the specified register.
Definition: hexrays.hpp:3360
const chain_t * get_chain(const voff_t &k, int width=1) const
Get chain for the specified value offset.
Definition: hexrays.hpp:3376
Convenience class to release graph chains automatically.
Definition: hexrays.hpp:4980
ud (use->def) and du (def->use) chain.
Definition: hexrays.hpp:3284
void append_list(const mba_t *mba, mlist_t *list) const
Append the contents of the chain to the specified list of locations.
Definition: hexrays.hpp:10723
int width
size of the value in bytes
Definition: hexrays.hpp:3289
uchar flags
combination Chain properties bits
Definition: hexrays.hpp:3291
int varnum
allocated variable index (-1 - not allocated yet)
Definition: hexrays.hpp:3290
Helper class to generate the initial microcode.
Definition: hexrays.hpp:5111
virtual merror_t gen_micro()=0
Generate microcode for one instruction.
virtual mreg_t load_operand(int opnum, int flags=0)=0
Generate microcode to load one operand.
virtual mreg_t load_effective_address(int n, int flags=0)=0
Generate microcode to calculate the address of a memory operand.
minsn_t * emit_micro_mvm(mcode_t code, op_dtype_t dtype, uval_t l, uval_t r, uval_t d, int offsize)
Emit one microinstruction.
Definition: hexrays.hpp:5197
virtual merror_t prepare_gen_micro()
Setup internal data to handle new instruction.
Definition: hexrays.hpp:5158
virtual bool store_operand(int n, const mop_t &mop, int flags=0, minsn_t **outins=nullptr)
Generate microcode to store an operand.
virtual merror_t analyze_prolog(const class qflow_chart_t &fc, const class bitset_t &reachable)=0
Analyze prolog/epilog of the function to decompile.
minsn_t * emit(mcode_t code, int width, uval_t l, uval_t r, uval_t d, int offsize)
Emit one microinstruction.
Definition: hexrays.hpp:11315
virtual void microgen_completed()
This method is called when the microcode generation is done.
Definition: hexrays.hpp:5149
void release(void)
Unlock the chains.
Definition: hexrays.hpp:10753
void acquire(void)
Lock the chains.
Definition: hexrays.hpp:3429
int for_all_chains(chain_visitor_t &cv, int gca_flags)
Visit all chains.
Definition: hexrays.hpp:10747
bool is_locked(void) const
Are the chains locked? It is a good idea to lock the chains before using them.
Definition: hexrays.hpp:3427
Definition of a local variable (register or stack) #var #lvar.
Definition: hexrays.hpp:1161
bool has_nice_name(void) const
Does the variable have a nice name?
Definition: hexrays.hpp:1226
tinfo_t tif
variable type
Definition: hexrays.hpp:1205
bool is_aliasable(const mba_t *mba) const
Is the variable aliasable?
Definition: hexrays.hpp:1382
qstring cmt
variable comment string
Definition: hexrays.hpp:1204
void append_list(const mba_t *mba, mlist_t *lst, bool pad_if_scattered=false) const
Append local variable to mlist.
Definition: hexrays.hpp:9923
bool set_lvar_type(const tinfo_t &t, bool may_fail=false)
Set variable type Note: this function does not modify the idb, only the lvar instance in the memory.
Definition: hexrays.hpp:9911
bool is_notarg(void) const
Is a local variable? (local variable cannot be an input argument)
Definition: hexrays.hpp:1270
bool typed(void) const
Has the variable a type?
Definition: hexrays.hpp:1222
bool is_spoiled_var(void) const
Is spoiled var? (meaningful only during lvar allocation)
Definition: hexrays.hpp:1252
bool is_overlapped_var(void) const
Is overlapped variable?
Definition: hexrays.hpp:1248
bool is_mapdst_var(void) const
Other variable(s) map to this var?
Definition: hexrays.hpp:1258
bool has_common_bit(const vdloc_t &loc, asize_t width2) const
Does the variable overlap with the specified location?
Definition: hexrays.hpp:1331
bool used(void) const
Is the variable used in the code?
Definition: hexrays.hpp:1220
bool is_partialy_typed(void) const
Variable type should be handled as a partial one.
Definition: hexrays.hpp:1254
bool mreg_done(void) const
Have corresponding microregs been replaced by references to this variable?
Definition: hexrays.hpp:1224
bool has_common(const lvar_t &v) const
Do variables overlap?
Definition: hexrays.hpp:1326
bool is_arg_var(void) const
Is the function argument?
Definition: hexrays.hpp:1242
qstring name
variable name.
Definition: hexrays.hpp:1201
bool set_width(int w, int svw_flags=0)
Change the variable width.
Definition: hexrays.hpp:9917
bool has_regname(void) const
Has a register name? (like _RAX)
Definition: hexrays.hpp:1264
bool is_used_byref(void) const
Was the address of the variable taken?
Definition: hexrays.hpp:1274
bool has_user_type(void) const
Has user-defined type?
Definition: hexrays.hpp:1238
bool is_dummy_arg(void) const
Is a dummy argument (added to fill a hole in the argument list)
Definition: hexrays.hpp:1268
const tinfo_t & type(void) const
Get variable type.
Definition: hexrays.hpp:1336
bool accepts_type(const tinfo_t &t, bool may_change_thisarg=false)
Check if the variable accept the specified type.
Definition: hexrays.hpp:9905
bool is_noptr_var(void) const
Variable type should not be a pointer.
Definition: hexrays.hpp:1256
bool is_fake_var(void) const
Is fake return variable?
Definition: hexrays.hpp:1246
bool has_user_name(void) const
Has user-defined name?
Definition: hexrays.hpp:1236
bool is_automapped(void) const
Was the variable automatically mapped to another variable?
Definition: hexrays.hpp:1272
bool is_decl_unused(void) const
Was declared as __unused by the user? See CVAR_UNUSED.
Definition: hexrays.hpp:1276
bool is_promoted_arg(void) const
Is the promoted function argument?
Definition: hexrays.hpp:9899
bool is_floating_var(void) const
Used by a fpu insn?
Definition: hexrays.hpp:1250
bool is_shared(void) const
Is lvar mapped to several chains.
Definition: hexrays.hpp:1278
bool is_thisarg(void) const
Is 'this' argument of a C++ member function?
Definition: hexrays.hpp:1260
bool is_result_var(void) const
Is the function result?
Definition: hexrays.hpp:1240
bool is_unknown_width(void) const
Do we know the width of the variable?
Definition: hexrays.hpp:1228
bool is_forced_var(void) const
Is a forced variable?
Definition: hexrays.hpp:1262
bool has_user_info(void) const
Has any user-defined information?
Definition: hexrays.hpp:1230
int width
variable size in bytes
Definition: hexrays.hpp:1206
bool in_asm(void) const
Is variable used in an instruction translated into __asm?
Definition: hexrays.hpp:1266
void set_final_lvar_type(const tinfo_t &t)
Set final variable type.
Definition: hexrays.hpp:1355
Micro block array (internal representation of the decompiled code).
Definition: hexrays.dox:59
int for_all_ops(mop_visitor_t &mv)
Visit all operands of all instructions.
Definition: hexrays.hpp:11209
mblock_t * copy_block(mblock_t *blk, int new_serial, int cpblk_flags=3)
Make a copy of a block.
Definition: hexrays.hpp:11191
mreg_t alloc_kreg(size_t size, bool check_size=true)
Allocate a kernel register.
Definition: hexrays.hpp:11279
int pfn_flags
copy of func_t::flags
Definition: hexrays.hpp:4644
mblock_t ** natural
natural order of blocks
Definition: hexrays.hpp:4692
mblock_t * blocks
double linked list of blocks
Definition: hexrays.hpp:4691
sval_t minstkref
The lowest stack location whose address was taken.
Definition: hexrays.hpp:4654
ivlset_t aliased_memory
aliased_memory+restricted_memory=ALLMEM
Definition: hexrays.hpp:4664
ea_t map_fict_ea(ea_t fict_ea) const
Resolve a fictional address.
Definition: hexrays.hpp:11253
mbl_graph_t * get_graph(void)
Get control graph.
Definition: hexrays.hpp:11125
ea_t alloc_fict_ea(ea_t real_ea)
Allocate a fictional address.
Definition: hexrays.hpp:11245
ivl_t aliased_vars
Aliased stkvar locations.
Definition: hexrays.hpp:4660
sval_t stacksize
The maximal size of the function stack including bytes allocated for outgoing call arguments (up to r...
Definition: hexrays.hpp:4648
ivl_t aliased_args
Aliased stkarg locations.
Definition: hexrays.hpp:4661
mlist_t spoiled_list
MBA_SPLINFO && !final_type: info in vd format.
Definition: hexrays.hpp:4674
sval_t frregs
size of saved registers range in the stack frame
Definition: hexrays.hpp:4642
int for_all_topinsns(minsn_visitor_t &mv)
Visit all top level instructions.
Definition: hexrays.hpp:11221
sval_t minargref
The lowest stack argument location whose address was taken This location and locations above it can b...
Definition: hexrays.hpp:4656
lvars_t vars
local variables
Definition: hexrays.hpp:4683
reginfovec_t idb_spoiled
MBA_SPLINFO && final_type: info in ida format.
Definition: hexrays.hpp:4673
sval_t frsize
size of local stkvars range in the stack frame
Definition: hexrays.hpp:4641
ivl_with_name_t std_ivls[6]
we treat memory as consisting of 6 parts see memreg_index_t
Definition: hexrays.hpp:4694
int retvaridx
index of variable holding the return value -1 means none
Definition: hexrays.hpp:4685
int fti_flags
FTI_... constants for the current function.
Definition: hexrays.hpp:4675
sval_t fullsize
Full stack size including incoming args.
Definition: hexrays.hpp:4647
void alloc_lvars(void)
Allocate local variables.
Definition: hexrays.hpp:11143
mba_maturity_t maturity
current maturity level
Definition: hexrays.hpp:4668
int optimize_local(int locopt_bits)
Optimize each basic block locally.
Definition: hexrays.hpp:11113
void free_kreg(mreg_t reg, size_t size)
Free a kernel register.
Definition: hexrays.hpp:11285
mba_maturity_t reqmat
required maturity level
Definition: hexrays.hpp:4669
sval_t fpd
frame pointer delta
Definition: hexrays.hpp:4643
void print(vd_printer_t &vp) const
Print microcode to any destination.
Definition: hexrays.hpp:11161
qstring label
name of the function or pattern (colored)
Definition: hexrays.hpp:4682
rlist_t consumed_argregs
registers converted into stack arguments, should not be used as arguments
Definition: hexrays.hpp:4666
void save_snapshot(const char *description)
Create and save microcode snapshot.
Definition: hexrays.hpp:11273
merror_t optimize_global(void)
Optimize microcode globally.
Definition: hexrays.hpp:11137
const ivl_t & get_std_region(memreg_index_t idx) const
Get information about various memory regions.
Definition: hexrays.hpp:5278
sval_t tmpstk_size
size of the temporary stack part (which dynamically changes with push/pops)
Definition: hexrays.hpp:4639
bool remove_block(mblock_t *blk)
Delete a block.
Definition: hexrays.hpp:11185
tinfo_t idb_type
function type as retrieved from the database
Definition: hexrays.hpp:4672
bool final_type
is the function type final? (specified by the user)
Definition: hexrays.hpp:4671
sval_t spd_adjust
If sp>0, the max positive sp value.
Definition: hexrays.hpp:4659
int npurged
-1 - unknown
Definition: hexrays.hpp:4637
ea_t error_ea
during microcode generation holds ins.ea
Definition: hexrays.hpp:4688
int qty
number of basic blocks
Definition: hexrays.hpp:4636
int shadow_args
size of shadow argument area
Definition: hexrays.hpp:4646
bool combine_blocks(void)
Combine blocks.
Definition: hexrays.hpp:11203
minsn_t * create_helper_call(ea_t ea, const char *helper, const tinfo_t *rettype=nullptr, const mcallargs_t *callargs=nullptr, const mop_t *out=nullptr)
Create a call of a helper function.
Definition: hexrays.hpp:11233
void dump(void) const
Dump microcode to a file.
Definition: hexrays.hpp:11149
intvec_t argidx
input arguments (indexes into 'vars')
Definition: hexrays.hpp:4684
bool set_maturity(mba_maturity_t mat)
Set maturity level.
Definition: hexrays.hpp:11107
static WARN_UNUSED_RESULT mba_t * deserialize(const uchar *bytes, size_t nbytes)
Deserialize a byte sequence into mbl array.
Definition: hexrays.hpp:11267
void verify(bool always) const
Verify microcode consistency.
Definition: hexrays.hpp:11167
int for_all_insns(minsn_visitor_t &mv)
Visit all instructions.
Definition: hexrays.hpp:11215
int retsize
size of return address in the stack frame
Definition: hexrays.hpp:4645
netnode deprecated_idb_node
netnode with additional decompiler info.
Definition: hexrays.hpp:4677
int analyze_calls(int acflags)
Analyze calls and determine calling conventions.
Definition: hexrays.hpp:11131
void mark_chains_dirty(void)
Mark the microcode use-def chains dirty.
Definition: hexrays.hpp:11173
cm_t cc
calling convention
Definition: hexrays.hpp:4638
const mblock_t * get_mblock(int n) const
Get basic block by its serial number.
Definition: hexrays.hpp:4821
mblock_t * insert_block(int bblk)
Insert a block in the middle of the mbl array.
Definition: hexrays.hpp:11179
merror_t build_graph(void)
Build control flow graph.
Definition: hexrays.hpp:11119
void serialize(bytevec_t &vout) const
Serialize mbl array into a sequence of bytes.
Definition: hexrays.hpp:11261
mlist_t nodel_memory
global dead elimination may not delete references to this area
Definition: hexrays.hpp:4665
sval_t inargoff
offset of the first stack argument; after fix_scattered_movs() INARGOFF may be less than STACKSIZE
Definition: hexrays.hpp:4651
mop_t * find_mop(op_parent_info_t *ctx, ea_t ea, bool is_dest, const mlist_t &list)
Find an operand in the microcode.
Definition: hexrays.hpp:11227
ivlset_t gotoff_stkvars
stkvars that hold .got offsets. considered to be unaliasable
Definition: hexrays.hpp:4662
lvar_t & arg(int n)
Get input argument of the decompiled function.
Definition: hexrays.hpp:11239
ea_t minstkref_ea
address with lowest minstkref (for debugging)
Definition: hexrays.hpp:4655
bool remove_empty_and_unreachable_blocks(void)
Delete all empty and unreachable blocks.
Definition: hexrays.hpp:11197
Control flow graph of microcode.
Definition: hexrays.hpp:5011
bool is_redefined_globally(const mlist_t &list, int b1, int b2, const minsn_t *m1, const minsn_t *m2, maymust_t maymust=MAY_ACCESS) const
Is LIST redefined in the graph?
Definition: hexrays.hpp:5068
graph_chains_t * get_ud(gctype_t gctype)
Get use-def chains.
Definition: hexrays.hpp:11297
graph_chains_t * get_du(gctype_t gctype)
Get def-use chains.
Definition: hexrays.hpp:11303
bool is_ud_chain_dirty(gctype_t gctype)
Is the use-def chain of the specified kind dirty?
Definition: hexrays.hpp:5047
bool is_used_globally(const mlist_t &list, int b1, int b2, const minsn_t *m1, const minsn_t *m2, maymust_t maymust=MAY_ACCESS) const
Is LIST used in the graph?
Definition: hexrays.hpp:5072
bool is_du_chain_dirty(gctype_t gctype)
Is the def-use chain of the specified kind dirty?
Definition: hexrays.hpp:5054
Microcode of one basic block.
Definition: hexrays.hpp:3768
ea_t end
end address note: we cannot rely on start/end addresses very much because instructions are propagated...
Definition: hexrays.hpp:3799
mlist_t dnu
data that is defined but not used in the block
Definition: hexrays.hpp:3814
sval_t minbargref
the same for arguments
Definition: hexrays.hpp:3820
minsn_t * head
pointer to the first instruction of the block
Definition: hexrays.hpp:3803
void append_use_list(mlist_t *list, const mop_t &op, maymust_t maymust, bitrange_t mask=MAXRANGE) const
Append use-list of an operand.
Definition: hexrays.hpp:10987
minsn_t * tail
pointer to the last instruction of the block
Definition: hexrays.hpp:3804
int optimize_useless_jump(void)
Remove a jump at the end of the block if it is useless.
Definition: hexrays.hpp:10981
int optimize_block(void)
Optimize a basic block.
Definition: hexrays.hpp:10969
minsn_t * insert_into_block(minsn_t *nm, minsn_t *om)
Insert instruction into the doubly linked list.
Definition: hexrays.hpp:10933
mblock_type_t type
block type (BLT_NONE - not computed yet)
Definition: hexrays.hpp:3807
int serial
block number
Definition: hexrays.hpp:3806
intvec_t succset
control flow graph: list of our successors use nsucc() and succ() to access it
Definition: hexrays.hpp:3824
void print(vd_printer_t &vp) const
Print block contents.
Definition: hexrays.hpp:10915
const minsn_t * find_redefinition(const mlist_t &list, const minsn_t *i1, const minsn_t *i2, maymust_t maymust=MAY_ACCESS) const
Find the first insn that redefines any part of the list in the insn range.
Definition: hexrays.hpp:11021
int optimize_insn(minsn_t *m, int optflags=OPTI_MINSTKREF|OPTI_COMBINSNS)
Optimize one instruction in the context of the block.
Definition: hexrays.hpp:10963
int for_all_ops(mop_visitor_t &mv)
Visit all operands.
Definition: hexrays.hpp:10951
bool is_used(mlist_t *list, const minsn_t *i1, const minsn_t *i2, maymust_t maymust=MAY_ACCESS) const
Is the list used by the specified instruction range?
Definition: hexrays.hpp:4030
const minsn_t * find_first_use(mlist_t *list, const minsn_t *i1, const minsn_t *i2, maymust_t maymust=MAY_ACCESS) const
Find the first insn that uses the specified list in the insn range.
Definition: hexrays.hpp:11015
size_t get_reginsn_qty(void) const
Calculate number of regular instructions in the block.
Definition: hexrays.hpp:11051
mblock_t * prevb
previous block in the doubly linked list
Definition: hexrays.hpp:3774
mlist_t mustbuse
data that must be used by the block
Definition: hexrays.hpp:3810
intvec_t predset
control flow graph: list of our predecessors use npred() and pred() to access it
Definition: hexrays.hpp:3822
minsn_t * find_access(const mop_t &op, minsn_t **parent, const minsn_t *mend, int fdflags) const
Find the instruction that accesses the specified operand.
Definition: hexrays.hpp:11033
mlist_t maybuse
data that may be used by the block
Definition: hexrays.hpp:3811
bool is_rhs_redefined(const minsn_t *ins, const minsn_t *i1, const minsn_t *i2) const
Is the right hand side of the instruction redefined the insn range? "right hand side" corresponds to ...
Definition: hexrays.hpp:11027
mlist_t build_def_list(const minsn_t &ins, maymust_t maymust) const
Build def-list of an instruction.
Definition: hexrays.hpp:11007
mlist_t maybdef
data that may be defined by the block
Definition: hexrays.hpp:3813
mlist_t dead_at_start
data that is dead at the block entry
Definition: hexrays.hpp:3809
bool get_valranges(valrng_t *res, const vivl_t &vivl, int vrflags) const
Find possible values for a block.
Definition: hexrays.hpp:11039
mlist_t mustbdef
data that must be defined by the block
Definition: hexrays.hpp:3812
int for_all_insns(minsn_visitor_t &mv)
Visit all instructions.
Definition: hexrays.hpp:10945
sval_t maxbsp
maximal sp value in the block (0...stacksize)
Definition: hexrays.hpp:3816
uint32 flags
combination of Basic block properties bits
Definition: hexrays.hpp:3775
bool is_redefined(const mlist_t &list, const minsn_t *i1, const minsn_t *i2, maymust_t maymust=MAY_ACCESS) const
Is the list redefined by the specified instructions?
Definition: hexrays.hpp:4060
void append_def_list(mlist_t *list, const mop_t &op, maymust_t maymust) const
Append def-list of an operand.
Definition: hexrays.hpp:10993
int nsucc(void) const
Get number of block successors.
Definition: hexrays.hpp:3846
void make_nop(minsn_t *m)
Erase the instruction (convert it to nop) and mark the lists dirty.
Definition: hexrays.hpp:4183
int npred(void) const
Get number of block predecessors.
Definition: hexrays.hpp:3844
sval_t minbstkref
lowest stack location accessible with indirect addressing (offset from the stack bottom) initially it...
Definition: hexrays.hpp:3817
mba_t * mba
the parent micro block array
Definition: hexrays.hpp:3805
minsn_t * remove_from_block(minsn_t *m)
Remove instruction from the doubly linked list.
Definition: hexrays.hpp:10939
mblock_t * nextb
next block in the doubly linked list
Definition: hexrays.hpp:3773
int build_lists(bool kill_deads)
Build def-use lists and eliminate deads.
Definition: hexrays.hpp:10975
mlist_t build_use_list(const minsn_t &ins, maymust_t maymust) const
Build use-list of an instruction.
Definition: hexrays.hpp:10999
void dump(void) const
Dump block info.
Definition: hexrays.hpp:10921
int for_all_uses(mlist_t *list, minsn_t *i1, minsn_t *i2, mlist_mop_visitor_t &mmv)
Visit all operands that use LIST.
Definition: hexrays.hpp:10957
A call argument.
Definition: hexrays.hpp:2991
tinfo_t type
formal argument type
Definition: hexrays.hpp:2995
argloc_t argloc
ida argloc
Definition: hexrays.hpp:2997
qstring name
formal argument name
Definition: hexrays.hpp:2996
Information about a call.
Definition: hexrays.hpp:3105
mcallargs_t args
call arguments
Definition: hexrays.hpp:3113
int flags
combination of Call properties... bits
Definition: hexrays.hpp:3128
int call_spd
sp value at call insn
Definition: hexrays.hpp:3110
mlist_t return_regs
list of values returned by the function
Definition: hexrays.hpp:3119
cm_t cc
calling convention
Definition: hexrays.hpp:3112
ivlset_t visible_memory
what memory is visible to the call?
Definition: hexrays.hpp:3123
mlist_t spoiled
list of spoiled locations (includes return_regs)
Definition: hexrays.hpp:3120
ea_t callee
address of the called function, if known
Definition: hexrays.hpp:3107
type_attrs_t fti_attrs
extended function attributes
Definition: hexrays.hpp:3150
mlist_t dead_regs
registers defined by the function but never used.
Definition: hexrays.hpp:3124
mopvec_t retregs
return register(s) (e.g., AX, AX:DX, etc.) this vector is built from return_regs
Definition: hexrays.hpp:3114
funcrole_t role
function role
Definition: hexrays.hpp:3149
tinfo_t return_type
type of the returned value
Definition: hexrays.hpp:3116
int stkargs_top
first offset past stack arguments
Definition: hexrays.hpp:3111
argloc_t return_argloc
location of the returned value
Definition: hexrays.hpp:3117
int solid_args
number of solid args.
Definition: hexrays.hpp:3108
mlist_t pass_regs
passthrough registers: registers that depend on input values (subset of spoiled)
Definition: hexrays.hpp:3121
List of switch cases and targets.
Definition: hexrays.hpp:3166
casevec_t values
expression values for each target
Definition: hexrays.hpp:3168
intvec_t targets
target block numbers
Definition: hexrays.hpp:3169
Microinstruction class #insn.
Definition: hexrays.hpp:3441
int optimize_subtree(mblock_t *blk, minsn_t *top, minsn_t *parent, ea_t *converted_call, int optflags=OPTI_MINSTKREF)
Optimize instruction in its context.
Definition: hexrays.hpp:10801
mop_t r
right operand
Definition: hexrays.hpp:3451
minsn_t * prev
prev insn in doubly linked list. check also previ()
Definition: hexrays.hpp:3448
bool is_noret_call(int flags=0)
Is a non-returing call?
Definition: hexrays.hpp:10837
bool contains_opcode(mcode_t mcode) const
Does the instruction have the specified opcode? This function searches subinstructions as well.
Definition: hexrays.hpp:3691
minsn_t * next
next insn in doubly linked list. check also nexti()
Definition: hexrays.hpp:3447
bool contains_call(bool with_helpers=false) const
Does the instruction contain a call?
Definition: hexrays.hpp:3669
int for_all_insns(minsn_visitor_t &mv)
Visit all instructions.
Definition: hexrays.hpp:10813
bool has_side_effects(bool include_ldx_and_divs=false) const
Does the instruction have a side effect?
Definition: hexrays.hpp:10855
bool may_use_aliased_memory(void) const
Is it possible for the instruction to use aliased memory?
Definition: hexrays.hpp:10891
funcrole_t get_role(void) const
Get the function role of a call.
Definition: hexrays.hpp:3678
const minsn_t * find_ins_op(const mop_t **other, mcode_t op=m_nop) const
Find an operand that is a subinsruction with the specified opcode.
Definition: hexrays.hpp:10867
void _make_nop(void)
Convert instruction to nop.
Definition: hexrays.hpp:10819
void setaddr(ea_t new_ea)
Change the instruction address.
Definition: hexrays.hpp:10795
ea_t ea
instruction address
Definition: hexrays.hpp:3449
void print(qstring *vout, int shins_flags=SHINS_SHORT|SHINS_VALNUM) const
Generate insn text into the buffer.
Definition: hexrays.hpp:10783
bool modifies_d(void) const
Does the instruction modify its 'd' operand? Some instructions (e.g.
Definition: hexrays.hpp:10879
const char * dstr(void) const
Get displayable text without tags in a static buffer.
Definition: hexrays.hpp:10789
minsn_t(ea_t _ea)
Constructor.
Definition: hexrays.hpp:3556
mop_t l
left operand
Definition: hexrays.hpp:3450
int optimize_solo(int optflags=0)
Optimize one instruction without context.
Definition: hexrays.hpp:3585
bool is_between(const minsn_t *m1, const minsn_t *m2) const
Is the instruction in the specified range of instructions?
Definition: hexrays.hpp:10885
const mop_t * find_num_op(const mop_t **other) const
Find a numeric operand of the current instruction.
Definition: hexrays.hpp:10873
int for_all_ops(mop_visitor_t &mv)
Visit all instruction operands.
Definition: hexrays.hpp:10807
bool is_after(const minsn_t *m) const
Is the instruction after the specified one?
Definition: hexrays.hpp:3732
void swap(minsn_t &m)
Swap two instructions.
Definition: hexrays.hpp:10777
mop_t d
destination operand
Definition: hexrays.hpp:3452
minsn_t * find_call(bool with_helpers=false) const
Find a call instruction.
Definition: hexrays.hpp:10849
bool equal_insns(const minsn_t &m, int eqflags) const
Compare instructions.
Definition: hexrays.hpp:10825
bool is_unknown_call(void) const
Is an unknown call? Unknown calls are calls without the argument list (mcallinfo_t).
Definition: hexrays.hpp:3655
const minsn_t * find_opcode(mcode_t mcode) const
Find a (sub)insruction with the specified opcode.
Definition: hexrays.hpp:3695
bool is_helper(const char *name) const
Is a helper call with the specified name? Helper calls usually have well-known function names (see We...
Definition: hexrays.hpp:10843
mcode_t opcode
instruction opcode
Definition: hexrays.hpp:3445
int iprops
combination of instruction property bits bits
Definition: hexrays.hpp:3446
Address of an operand (mop_l, mop_v, mop_S, mop_r)
Definition: hexrays.hpp:2961
Pair of operands.
Definition: hexrays.hpp:2952
mop_t lop
low operand
Definition: hexrays.hpp:2954
mop_t hop
high operand
Definition: hexrays.hpp:2955
A microinstruction operand.
Definition: hexrays.hpp:2426
bool is01(void) const
Are the possible values of the operand only 0 and 1? This function returns true for 0/1 constants,...
Definition: hexrays.hpp:10515
void _make_gvar(ea_t ea)
Create a global variable operand without erasing previous data.
Definition: hexrays.hpp:10479
member_t * get_stkvar(uval_t *p_off) const
Retrieve the referenced stack variable.
Definition: hexrays.hpp:2852
bool has_side_effects(bool include_ldx_and_divs=false) const
Has any side effects?
Definition: hexrays.hpp:5223
uint8 oprops
Operand properties.
Definition: hexrays.hpp:2433
int for_all_ops(mop_visitor_t &mv, const tinfo_t *type=nullptr, bool is_target=false)
Visit the operand and all its sub-operands.
Definition: hexrays.hpp:10545
bool is_constant(uint64 *out=nullptr, bool is_signed=true) const
Retrieve value of a constant integer operand.
Definition: hexrays.hpp:10557
bool is_zero_extended_from(int nbytes) const
Does the high part of the operand consist of zero bytes?
Definition: hexrays.hpp:10527
mopt_t t
Operand type.
Definition: hexrays.hpp:2430
void create_from_insn(const minsn_t *m)
Create operand from an instruction.
Definition: hexrays.hpp:10461
bool create_from_mlist(mba_t *mba, const mlist_t &lst, sval_t fullsize)
Create operand from mlist_t.
Definition: hexrays.hpp:10437
bool is_cc(void) const
Is a condition code?
Definition: hexrays.hpp:2716
void make_reg_pair(int loreg, int hireg, int halfsize)
Create pair of registers.
Definition: hexrays.hpp:10491
bool get_stkoff(sval_t *p_off) const
Get the referenced stack offset.
Definition: hexrays.hpp:10563
bool is_mob(int serial) const
Is a block reference to the specified block?
Definition: hexrays.hpp:2724
void _make_lvar(mba_t *mba, int idx, sval_t off=0)
Create a local variable operand.
Definition: hexrays.hpp:2604
bool make_low_half(int width)
Make the low part of the operand.
Definition: hexrays.hpp:10569
bool is_insn(void) const
Is a sub-instruction?
Definition: hexrays.hpp:2734
uint16 valnum
Value number.
Definition: hexrays.hpp:2445
bool may_use_aliased_memory(void) const
Is it possible for the operand to use aliased memory?
Definition: hexrays.hpp:10509
void _make_blkref(int blknum)
Create a block reference operand without erasing previous data.
Definition: hexrays.hpp:2649
int size
Operand size.
Definition: hexrays.hpp:2449
bool preserve_side_effects(mblock_t *blk, minsn_t *top, bool *moved_calls=nullptr)
Move subinstructions with side effects out of the operand.
Definition: hexrays.hpp:10605
bool equal_mops(const mop_t &rop, int eqflags) const
Compare operands.
Definition: hexrays.hpp:10533
bool change_size(int nsize, side_effect_t sideff=WITH_SIDEFF)
Change the operand size.
Definition: hexrays.hpp:10599
bool is_reg(mreg_t _r) const
Is the specified register?
Definition: hexrays.hpp:2710
const minsn_t * get_insn(mcode_t code) const
Get subinstruction of the operand.
Definition: hexrays.hpp:5237
bool make_fpnum(const void *bytes, size_t _size)
Create a floating point constant operand.
Definition: hexrays.hpp:10473
void _make_cases(mcases_t *_cases)
Create a 'switch cases' operand without erasing previous data.
Definition: hexrays.hpp:2687
bool is_arglist(void) const
Is a list of arguments?
Definition: hexrays.hpp:2714
void make_insn(minsn_t *ins)
Create a nested instruction.
Definition: hexrays.hpp:2643
void make_number(uint64 _value, int _size, ea_t _ea=BADADDR, int opnum=0)
Create an integer constant operand.
Definition: hexrays.hpp:10467
bool make_first_half(int width)
Make the first part of the operand.
Definition: hexrays.hpp:10581
bool is_sign_extended_from(int nbytes) const
Does the high part of the operand consist of the sign bytes?
Definition: hexrays.hpp:10521
bool make_high_half(int width)
Make the high part of the operand.
Definition: hexrays.hpp:10575
uint64 value(bool is_signed) const
Retrieve value of a constant integer operand.
Definition: hexrays.hpp:2814
bool is_glbaddr() const
Is address of a global memory cell?
Definition: hexrays.hpp:5247
void _make_reg(mreg_t reg)
Create a register operand without erasing previous data.
Definition: hexrays.hpp:2583
void _make_insn(minsn_t *ins)
Create a nested instruction without erasing previous data.
Definition: hexrays.hpp:5217
void _make_strlit(const char *str)
Create a constant string operand.
Definition: hexrays.hpp:2663
bool is_reg(mreg_t _r, int _size) const
Is the specified register of the specified size?
Definition: hexrays.hpp:2712
int for_all_scattered_submops(scif_visitor_t &sv) const
Visit all sub-operands of a scattered operand.
Definition: hexrays.hpp:10551
static bool is_bit_reg(mreg_t reg)
Is a bit register? This includes condition codes and eventually other bit registers.
Definition: hexrays.hpp:10503
bool create_from_ivlset(mba_t *mba, const ivlset_t &ivs, sval_t fullsize)
Create operand from ivlset_t.
Definition: hexrays.hpp:10443
void make_reg(mreg_t reg)
Create a register operand.
Definition: hexrays.hpp:2595
bool is_extended_from(int nbytes, bool is_signed) const
Does the high part of the operand consist of zero or sign bytes?
Definition: hexrays.hpp:2763
bool shift_mop(int offset)
Shift the operand.
Definition: hexrays.hpp:10593
void _make_stkvar(mba_t *mba, sval_t off)
Create a stack variable operand.
Definition: hexrays.hpp:2623
bool is_stkaddr() const
Is address of a stack variable?
Definition: hexrays.hpp:5257
void make_helper(const char *name)
Create a helper operand.
Definition: hexrays.hpp:10497
void create_from_vdloc(mba_t *mba, const vdloc_t &loc, int _size)
Create operand from vdloc_t.
Definition: hexrays.hpp:10449
bool is_scattered(void) const
Is a scattered operand?
Definition: hexrays.hpp:2726
void make_blkref(int blknum)
Create a global variable operand.
Definition: hexrays.hpp:2655
void _make_callinfo(mcallinfo_t *fi)
Create a call info operand without erasing previous data.
Definition: hexrays.hpp:2678
bool make_second_half(int width)
Make the second part of the operand.
Definition: hexrays.hpp:10587
bool is_kreg(void) const
Is a kernel register?
Definition: hexrays.hpp:5228
void create_from_scattered_vdloc(mba_t *mba, const char *name, tinfo_t type, const vdloc_t &loc)
Create operand from scattered vdloc_t.
Definition: hexrays.hpp:10455
void apply_ld_mcode(mcode_t mcode, ea_t ea, int newsize)
Apply a unary opcode to the operand.
Definition: hexrays.hpp:10611
void make_gvar(ea_t ea)
Create a global variable operand.
Definition: hexrays.hpp:10485
void _make_pair(mop_pair_t *_pair)
Create a pair operand without erasing previous data.
Definition: hexrays.hpp:2696
bool is_reg(void) const
Is a register operand? See also get_mreg_name()
Definition: hexrays.hpp:2708
Vector of colored strings.
Definition: hexrays.dox:64
Abstract class: User-defined call generator derived classes should implement method 'match'.
Definition: hexrays.hpp:1722
virtual bool match(codegen_t &cdg) override=0
return true if the filter object should be applied to given instruction
virtual merror_t apply(codegen_t &cdg) override
generate microcode for an instruction
Definition: hexrays.hpp:10020
void cleanup(void)
Cleanup the filter This function properly clears type information associated to this filter.
Definition: hexrays.hpp:10008
Iterator class for user_cmts_t.
Definition: hexrays.dox:33
User defined comments.
Definition: hexrays.dox:46
Iterator class for user_labels_t.
Definition: hexrays.dox:36
User defined label names.
Definition: hexrays.dox:51
Iterator class for user_numforms_t.
Definition: hexrays.dox:30
User defined number formats.
Definition: hexrays.dox:41
tinfo_t dummy_ptrtype(int ptrsize, bool isfp)
Generate a dummy pointer type.
Definition: hexrays.hpp:9809
bool is_break_consumer(ctype_t op)
Does a break statement influence the specified statement code?
Definition: hexrays.hpp:5652
operand_locator_t const & user_numforms_first(user_numforms_iterator_t p)
Get reference to the current map key.
Definition: hexrays.hpp:8487
void udcall_map_free(udcall_map_t *map)
Delete udcall_map_t instance.
Definition: hexrays.hpp:8792
#define CVAR_FLOAT
used in a fpu insn
Definition: hexrays.hpp:1178
int select_udt_by_offset(const qvector< tinfo_t > *udts, const ui_stroff_ops_t &ops, ui_stroff_applicator_t &applicator)
Select UDT.
Definition: hexrays.hpp:12390
#define MBA_PASSREGS
has mcallinfo_t::pass_regs
Definition: hexrays.hpp:4449
#define MBA2_ARGIDX_OK
may verify input argument list?
Definition: hexrays.hpp:4486
cursor_item_type_t
Type of the cursor item.
Definition: hexrays.hpp:6600
@ VDI_FUNC
the function itself (the very first line with the function prototype)
Definition: hexrays.hpp:6604
@ VDI_TAIL
cursor is at (beyond) the line end (commentable line)
Definition: hexrays.hpp:6605
@ VDI_LVAR
declaration of local variable
Definition: hexrays.hpp:6603
@ VDI_NONE
undefined
Definition: hexrays.hpp:6601
@ VDI_EXPR
c-tree item
Definition: hexrays.hpp:6602
boundaries_iterator_t boundaries_end(const boundaries_t *map)
Get iterator pointing to the end of boundaries_t.
Definition: hexrays.hpp:9400
#define MBL_PROP
needs 'propagation' pass
Definition: hexrays.hpp:3787
#define CVAR_THISARG
'this' argument of c++ member functions
Definition: hexrays.hpp:1182
user_cmts_iterator_t user_cmts_prev(user_cmts_iterator_t p)
Move to the previous element.
Definition: hexrays.hpp:8872
#define IPROP_OPTIONAL
optional instruction
Definition: hexrays.hpp:3457
size_t user_numforms_size(user_numforms_t *map)
Get size of user_numforms_t.
Definition: hexrays.hpp:8567
boundaries_iterator_t boundaries_find(const boundaries_t *map, const cinsn_t *&key)
Find the specified key in boundaries_t.
Definition: hexrays.hpp:9373
void user_cmts_clear(user_cmts_t *map)
Clear user_cmts_t.
Definition: hexrays.hpp:8887
const cmt_type_t CMT_FUNC
Function comment.
Definition: hexrays.hpp:7492
#define CHF_REPLACED
chain operands have been replaced?
Definition: hexrays.hpp:3295
#define CVAR_REGNAME
has a register name (like _RAX): if lvar is used by an m_ext instruction
Definition: hexrays.hpp:1185
#define CVAR_BYREF
the address of the variable was taken
Definition: hexrays.hpp:1192
memreg_index_t
< memory region types
Definition: hexrays.hpp:4313
@ MMIDX_SHADOW
stack: shadow arguments
Definition: hexrays.hpp:4317
@ MMIDX_GLBLOW
global memory: low part
Definition: hexrays.hpp:4314
@ MMIDX_GLBHIGH
global memory: high part
Definition: hexrays.hpp:4319
@ MMIDX_ARGS
stack: regular stack arguments
Definition: hexrays.hpp:4318
@ MMIDX_RETADDR
stack: return address
Definition: hexrays.hpp:4316
@ MMIDX_LVARS
stack: local variables
Definition: hexrays.hpp:4315
#define CVAR_NAME
has nice name?
Definition: hexrays.hpp:1169
bool is_unary(ctype_t op)
Is unary operator?
Definition: hexrays.hpp:5587
user_iflags_iterator_t user_iflags_insert(user_iflags_t *map, const citem_locator_t &key, const int32 &val)
Insert new (citem_locator_t, int32) pair into user_iflags_t.
Definition: hexrays.hpp:8946
bool get_type(uval_t id, tinfo_t *tif, type_source_t guess)
Get a global type.
Definition: hexrays.hpp:9839
const mopt_t mop_d
result of another instruction
Definition: hexrays.hpp:2244
const cmt_type_t CMT_BLOCK2
Posterior block comment.
Definition: hexrays.hpp:7490
#define MBA2_OVER_CHAINS
has overlapped chains?
Definition: hexrays.hpp:4482
const minsn_t * getb_reginsn(const minsn_t *ins)
Skip assertions backward.
Definition: hexrays.hpp:10903
void user_labels_clear(user_labels_t *map)
Clear user_labels_t.
Definition: hexrays.hpp:9214
bool get_member_type(const member_t *mptr, tinfo_t *type)
Get type of a structure field.
Definition: hexrays.hpp:9817
bool arglocs_overlap(const vdloc_t &loc1, size_t w1, const vdloc_t &loc2, size_t w2)
Do two arglocs overlap?
Definition: hexrays.hpp:9875
enum hexrays_event_t ENUM_SIZE(int)
Decompiler events.
Definition: hexrays.hpp:7231
merror_t
Definition: hexrays.hpp:480
@ MERR_ONLY32
only 32-bit functions can be decompiled for the current database
Definition: hexrays.hpp:506
@ MERR_LICENSE
no license available
Definition: hexrays.hpp:505
@ MERR_CANCELED
decompilation has been cancelled
Definition: hexrays.hpp:500
@ MERR_UNKTYPE
undefined type s (currently unused error code)
Definition: hexrays.hpp:496
@ MERR_BADFRAME
function frame is wrong
Definition: hexrays.hpp:495
@ MERR_BUSY
already decompiling a function
Definition: hexrays.hpp:508
@ MERR_HUGESTACK
stack frame is too big
Definition: hexrays.hpp:491
@ MERR_BADBLK
bad block found
Definition: hexrays.hpp:486
@ MERR_BADIDB
inconsistent database information
Definition: hexrays.hpp:497
@ MERR_CLOUD
cloud: s
Definition: hexrays.hpp:516
@ MERR_EXCEPTION
exception analysis failed
Definition: hexrays.hpp:490
@ MERR_BLOCK
no error, switch to new block
Definition: hexrays.hpp:482
@ MERR_FUNCSIZE
too big function
Definition: hexrays.hpp:511
@ MERR_PARTINIT
partially initialized variable s
Definition: hexrays.hpp:503
@ MERR_BADRANGES
bad input ranges
Definition: hexrays.hpp:512
@ MERR_DSLOT
bad instruction in the delay slot
Definition: hexrays.hpp:514
@ MERR_OK
ok
Definition: hexrays.hpp:481
@ MERR_INSN
cannot convert to microcode
Definition: hexrays.hpp:484
@ MERR_COMPLEX
too complex function
Definition: hexrays.hpp:504
@ MERR_BADARCH
current architecture is not supported
Definition: hexrays.hpp:513
@ MERR_ONLY64
only 64-bit functions can be decompiled for the current database
Definition: hexrays.hpp:507
@ MERR_RECDEPTH
max recursion depth reached during lvar allocation
Definition: hexrays.hpp:501
@ MERR_FARPTR
far memory model is supported only for pc
Definition: hexrays.hpp:509
@ MERR_STOP
no error, stop the analysis
Definition: hexrays.hpp:515
@ MERR_BADCALL
could not determine call arguments
Definition: hexrays.hpp:494
@ MERR_SIZEOF
wrong basic type sizes in compiler settings
Definition: hexrays.hpp:498
@ MERR_EXTERN
special segments cannot be decompiled
Definition: hexrays.hpp:510
@ MERR_BITNESS
16-bit functions cannot be decompiled
Definition: hexrays.hpp:493
@ MERR_LOOP
internal code: redo last loop (never reported)
Definition: hexrays.hpp:518
@ MERR_REDO
redecompilation has been requested
Definition: hexrays.hpp:499
@ MERR_PROLOG
prolog analysis failed
Definition: hexrays.hpp:488
@ MERR_LVARS
local variable allocation failed
Definition: hexrays.hpp:492
@ MERR_INTERR
internal error
Definition: hexrays.hpp:483
@ MERR_OVERLAP
variables would overlap: s
Definition: hexrays.hpp:502
@ MERR_BADSP
positive sp value has been found
Definition: hexrays.hpp:487
@ MERR_SWITCH
wrong switch idiom
Definition: hexrays.hpp:489
@ MERR_MEM
not enough memory
Definition: hexrays.hpp:485
#define CHF_OVER
overlapped chain
Definition: hexrays.hpp:3296
#define CVAR_SHARED
variable is mapped to several chains
Definition: hexrays.hpp:1197
user_cmts_iterator_t user_cmts_end(const user_cmts_t *map)
Get iterator pointing to the end of user_cmts_t.
Definition: hexrays.hpp:8855
#define IPROP_WAS_NORET
was noret icall
Definition: hexrays.hpp:3483
#define MBA_SHORT
use short display
Definition: hexrays.hpp:4468
void * hexdsp_t(int code,...)
Hex-Rays decompiler dispatcher.
Definition: hexrays.hpp:7224
THREAD_SAFE bool must_mcode_close_block(mcode_t mcode, bool including_calls)
Must an instruction with the given opcode be the last one in a block? Such opcodes are called closing...
Definition: hexrays.hpp:9671
size_t user_unions_size(user_unions_t *map)
Get size of user_unions_t.
Definition: hexrays.hpp:9112
#define CHF_FAKE
fake chain created by widen_chains()
Definition: hexrays.hpp:3297
#define GCO_USE
is source operand?
Definition: hexrays.hpp:5440
#define MBL_INCONST
inconsistent lists: we are building them
Definition: hexrays.hpp:3790
bool is_relational(ctype_t op)
Is comparison operator?
Definition: hexrays.hpp:5589
bool init_hexrays_plugin(int flags=0)
Check that your plugin is compatible with hex-rays decompiler.
Definition: hexrays.hpp:8464
const char * get_hexrays_version(void)
Get decompiler version.
Definition: hexrays.hpp:11327
#define EXFL_CPADONE
pointer arithmetic correction done
Definition: hexrays.hpp:6096
#define CVAR_INASM
variable is used in instructions translated into __asm {...}
Definition: hexrays.hpp:1193
bool set_type(uval_t id, const tinfo_t &tif, type_source_t source, bool force=false)
Set a global type.
Definition: hexrays.hpp:9845
void lvar_mapping_clear(lvar_mapping_t *map)
Clear lvar_mapping_t.
Definition: hexrays.hpp:8669
merror_t convert_to_user_call(const udcall_t &udc, codegen_t &cdg)
try to generate user-defined call for an instruction
Definition: hexrays.hpp:9995
item_preciser_t
Comment item preciser.
Definition: hexrays.hpp:5904
@ ITP_ASM
__asm-line
Definition: hexrays.hpp:5912
@ ITP_CASE
bit for switch cases
Definition: hexrays.hpp:5923
@ ITP_BLOCK2
closing block comment.
Definition: hexrays.hpp:5922
@ ITP_SEMI
semicolon
Definition: hexrays.hpp:5915
@ ITP_CURLY2
}
Definition: hexrays.hpp:5917
@ ITP_SIGN
if this bit is set too, then we have a negative case value
Definition: hexrays.hpp:5924
@ ITP_EMPTY
nothing
Definition: hexrays.hpp:5906
@ ITP_COLON
: (label)
Definition: hexrays.hpp:5919
@ ITP_ELSE
else-line
Definition: hexrays.hpp:5913
@ ITP_DO
do-line
Definition: hexrays.hpp:5914
@ ITP_CURLY1
{
Definition: hexrays.hpp:5916
@ ITP_ARG1
, (64 entries are reserved for 64 call arguments)
Definition: hexrays.hpp:5907
@ ITP_BRACE2
)
Definition: hexrays.hpp:5918
@ ITP_BLOCK1
opening block comment.
Definition: hexrays.hpp:5920
user_unions_iterator_t user_unions_prev(user_unions_iterator_t p)
Move to the previous element.
Definition: hexrays.hpp:9090
int mreg_t
Micro register.
Definition: hexrays.hpp:259
#define ANCHOR_ITP
item type preciser
Definition: hexrays.hpp:6587
#define hexapi
Public functions are marked with this keyword.
Definition: hexrays.hpp:224
bool is_bitop(ctype_t op)
Is bit related operator?
Definition: hexrays.hpp:5628
user_unions_iterator_t user_unions_next(user_unions_iterator_t p)
Move to the next element.
Definition: hexrays.hpp:9082
#define ULV_PRECISE_DEFEA
Use precise defea's for lvar locations.
Definition: hexrays.hpp:1505
#define IPROP_SPLIT4
into 4 bytes
Definition: hexrays.hpp:3475
cinsn_t * new_block(void)
Create a new block-statement.
Definition: hexrays.hpp:11791
user_numforms_iterator_t user_numforms_find(const user_numforms_t *map, const operand_locator_t &key)
Find the specified key in user_numforms_t.
Definition: hexrays.hpp:8501
void user_cmts_free(user_cmts_t *map)
Delete user_cmts_t instance.
Definition: hexrays.hpp:8901
#define CV_RESTART
restart enumeration at the top expr (apply_to_exprs)
Definition: hexrays.hpp:5742
udcall_map_iterator_t udcall_map_insert(udcall_map_t *map, const ea_t &key, const udcall_t &val)
Insert new (ea_t, udcall_t) pair into udcall_map_t.
Definition: hexrays.hpp:8728
#define CV_PRUNE
this bit is set by visit...() to prune the walk
Definition: hexrays.hpp:5739
const mopt_t mop_l
local variable
Definition: hexrays.hpp:2249
#define IPROP_PERSIST
persistent insn; they are not destroyed
Definition: hexrays.hpp:3458
user_iflags_iterator_t user_iflags_next(user_iflags_iterator_t p)
Move to the next element.
Definition: hexrays.hpp:8973
void user_iflags_clear(user_iflags_t *map)
Clear user_iflags_t.
Definition: hexrays.hpp:8996
#define LVINF_UNUSED
unused argument, corresponds to CVAR_UNUSED
Definition: hexrays.hpp:1444
bool has_cached_cfunc(ea_t ea)
Do we have a cached decompilation result for 'ea'?
Definition: hexrays.hpp:12123
udcall_map_iterator_t udcall_map_end(const udcall_map_t *map)
Get iterator pointing to the end of udcall_map_t.
Definition: hexrays.hpp:8746
bool is_type_correct(const type_t *ptr)
Verify a type string.
Definition: hexrays.hpp:9755
cexpr_t * lnot(cexpr_t *e)
Logically negate the specified expression.
Definition: hexrays.hpp:11785
#define NF_VALID
internal bit: stroff or enum is valid for enums: this bit is set immediately for stroffs: this bit is...
Definition: hexrays.hpp:790
#define ANCHOR_CITEM
c-tree item
Definition: hexrays.hpp:6585
int partial_type_num(const tinfo_t &type)
Calculate number of partial subtypes.
Definition: hexrays.hpp:9779
bool mark_cfunc_dirty(ea_t ea, bool close_views=false)
Flush the cached decompilation results.
Definition: hexrays.hpp:12111
eamap_iterator_t eamap_prev(eamap_iterator_t p)
Move to the previous element.
Definition: hexrays.hpp:9308
const cmt_type_t CMT_TAIL
Indented comment.
Definition: hexrays.hpp:7488
boundaries_iterator_t boundaries_begin(const boundaries_t *map)
Get iterator pointing to the beginning of boundaries_t.
Definition: hexrays.hpp:9391
bool is_additive(ctype_t op)
Is additive operator?
Definition: hexrays.hpp:5610
vdui_t * open_pseudocode(ea_t ea, int flags)
Open pseudocode window.
Definition: hexrays.hpp:11339
intvec_t & user_unions_second(user_unions_iterator_t p)
Get reference to the current map value.
Definition: hexrays.hpp:9039
int get_mreg_name(qstring *out, mreg_t reg, int width, void *ud=nullptr)
Get the microregister name.
Definition: hexrays.hpp:10334
rangeset_t & boundaries_second(boundaries_iterator_t p)
Get reference to the current map value.
Definition: hexrays.hpp:9366
#define MBA_THUNK
thunk function
Definition: hexrays.hpp:4450
cmt_retrieval_type_t
Comment retrieval type.
Definition: hexrays.hpp:5952
@ RETRIEVE_ALWAYS
Retrieve comment even if it has been used.
Definition: hexrays.hpp:5954
@ RETRIEVE_ONCE
Retrieve comment if it has not been used yet.
Definition: hexrays.hpp:5953
bool modify_user_lvar_info(ea_t func_ea, uint mli_flags, const lvar_saved_info_t &info)
Modify saved local variable settings of one variable.
Definition: hexrays.hpp:9965
size_t user_cmts_size(user_cmts_t *map)
Get size of user_cmts_t.
Definition: hexrays.hpp:8894
user_numforms_iterator_t user_numforms_begin(const user_numforms_t *map)
Get iterator pointing to the beginning of user_numforms_t.
Definition: hexrays.hpp:8519
void print_vdloc(qstring *vout, const vdloc_t &loc, int nbytes)
Print vdloc.
Definition: hexrays.hpp:9869
void user_cmts_erase(user_cmts_t *map, user_cmts_iterator_t p)
Erase current element from user_cmts_t.
Definition: hexrays.hpp:8880
eamap_iterator_t eamap_find(const eamap_t *map, const ea_t &key)
Find the specified key in eamap_t.
Definition: hexrays.hpp:9264
bool op_uses_z(ctype_t op)
Does operator use the 'z' field of cexpr_t?
Definition: hexrays.hpp:5583
#define CVAR_UTYPE
user-defined type
Definition: hexrays.hpp:1173
qvector< citem_t * > ctree_items_t
Vector of parents.
Definition: hexrays.hpp:5724
bool is_small_udt(const tinfo_t &tif)
Is a small structure or union?
Definition: hexrays.hpp:9761
ea_t const & user_unions_first(user_unions_iterator_t p)
Get reference to the current map key.
Definition: hexrays.hpp:9032
THREAD_SAFE bool is_inplace_def(const tinfo_t &type)
Is struct/union/enum definition (not declaration)?
Definition: hexrays.hpp:957
lvar_mapping_iterator_t lvar_mapping_end(const lvar_mapping_t *map)
Get iterator pointing to the end of lvar_mapping_t.
Definition: hexrays.hpp:8637
lvar_locator_t & lvar_mapping_second(lvar_mapping_iterator_t p)
Get reference to the current map value.
Definition: hexrays.hpp:8603
#define CHF_INITED
is chain initialized? (valid only after lvar allocation)
Definition: hexrays.hpp:3294
size_t udcall_map_size(udcall_map_t *map)
Get size of udcall_map_t.
Definition: hexrays.hpp:8785
void save_user_iflags(ea_t func_ea, const user_iflags_t *iflags)
Save user defined citem iflags into the database.
Definition: hexrays.hpp:11851
const mlist_t & get_temp_regs(void)
Get list of temporary registers.
Definition: hexrays.hpp:10310
bool accepts_small_udts(ctype_t op)
Is the operator allowed on small structure or union?
Definition: hexrays.hpp:5669
const minsn_t * getf_reginsn(const minsn_t *ins)
Skip assertions forward.
Definition: hexrays.hpp:10897
udcall_map_iterator_t udcall_map_begin(const udcall_map_t *map)
Get iterator pointing to the beginning of udcall_map_t.
Definition: hexrays.hpp:8737
#define MBA2_LVARS_RENAMED
accept empty names now?
Definition: hexrays.hpp:4481
const cmt_type_t CMT_LVAR
Local variable comment.
Definition: hexrays.hpp:7491
user_numforms_iterator_t user_numforms_prev(user_numforms_iterator_t p)
Move to the previous element.
Definition: hexrays.hpp:8545
#define MBA_CMNSTK
stkvars+stkargs should be considered as one area
Definition: hexrays.hpp:4451
#define CVAR_FORCED
variable was created by an explicit request otherwise we could reuse an existing var
Definition: hexrays.hpp:1183
#define IPROP_WILDMATCH
match multiple insns
Definition: hexrays.hpp:3459
cfuncptr_t decompile_func(func_t *pfn, hexrays_failure_t *hf, int decomp_flags=0)
Decompile a function.
Definition: hexrays.hpp:7096
void block_chains_free(block_chains_t *set)
Delete block_chains_t instance.
Definition: hexrays.hpp:9548
#define CVAR_UNUSED
user-defined __unused attribute meaningful only if: is_arg_var() && !mba->final_type
Definition: hexrays.hpp:1195
#define OPROP_IMPDONE
imported operand (a pointer) has been dereferenced
Definition: hexrays.hpp:2434
eamap_iterator_t eamap_next(eamap_iterator_t p)
Move to the next element.
Definition: hexrays.hpp:9300
#define GCO_REG
is register? otherwise a stack variable
Definition: hexrays.hpp:5439
udcall_map_iterator_t udcall_map_next(udcall_map_iterator_t p)
Move to the next element.
Definition: hexrays.hpp:8755
bool is_commutative(ctype_t op)
Is commutative operator?
Definition: hexrays.hpp:5597
udcall_map_iterator_t udcall_map_prev(udcall_map_iterator_t p)
Move to the previous element.
Definition: hexrays.hpp:8763
void user_numforms_erase(user_numforms_t *map, user_numforms_iterator_t p)
Erase current element from user_numforms_t.
Definition: hexrays.hpp:8553
void save_user_cmts(ea_t func_ea, const user_cmts_t *user_cmts)
Save user defined comments into the database.
Definition: hexrays.hpp:11839
std::map< lvar_locator_t, lvar_locator_t > lvar_mapping_t
Local variable mapping (is used to merge variables)
Definition: hexrays.hpp:1484
user_numforms_iterator_t user_numforms_next(user_numforms_iterator_t p)
Move to the next element.
Definition: hexrays.hpp:8537
eamap_iterator_t eamap_begin(const eamap_t *map)
Get iterator pointing to the beginning of eamap_t.
Definition: hexrays.hpp:9282
ea_t get_merror_desc(qstring *out, merror_t code, mba_t *mba)
Get textual description of an error code.
Definition: hexrays.hpp:9663
const mopt_t mop_b
micro basic block (mblock_t)
Definition: hexrays.hpp:2247
#define VDUI_VISIBLE
is visible?
Definition: hexrays.hpp:7503
#define LVINF_KEEP
preserve saved user settings regardless of vars for example, if a var loses all its user-defined attr...
Definition: hexrays.hpp:1433
block_chains_iterator_t block_chains_next(block_chains_iterator_t p)
Move to the next element.
Definition: hexrays.hpp:9511
const mopt_t mop_S
local stack variable (they exist until MMAT_LVARS)
Definition: hexrays.hpp:2245
int32 & user_iflags_second(user_iflags_iterator_t p)
Get reference to the current map value.
Definition: hexrays.hpp:8930
user_unions_t * user_unions_new()
Create a new user_unions_t instance.
Definition: hexrays.hpp:9126
size_t boundaries_size(boundaries_t *map)
Get size of boundaries_t.
Definition: hexrays.hpp:9439
void eamap_erase(eamap_t *map, eamap_iterator_t p)
Erase current element from eamap_t.
Definition: hexrays.hpp:9316
#define CVAR_MAPDST
other variables are mapped to this var
Definition: hexrays.hpp:1180
const mopt_t mop_sc
scattered
Definition: hexrays.hpp:2255
#define NF_NEGATE
The user asked to negate the constant.
Definition: hexrays.hpp:788
#define IPROP_CLNPOP
the purpose of the instruction is to clean stack (e.g.
Definition: hexrays.hpp:3462
#define FD_DEF
look for definition
Definition: hexrays.hpp:4126
const int NOSIZE
wrong or unexisting operand size
Definition: hexrays.hpp:2257
bool get_current_operand(gco_info_t *out)
Get the instruction operand under the cursor.
Definition: hexrays.hpp:11383
size_t eamap_size(eamap_t *map)
Get size of eamap_t.
Definition: hexrays.hpp:9330
void block_chains_clear(block_chains_t *set)
Clear block_chains_t.
Definition: hexrays.hpp:9534
input_device_t
Type of the input device.
Definition: hexrays.hpp:7439
@ USE_MOUSE
Mouse.
Definition: hexrays.hpp:7441
@ USE_KEYBOARD
Keyboard.
Definition: hexrays.hpp:7440
chain_t & block_chains_get(block_chains_iterator_t p)
Get reference to the current set value.
Definition: hexrays.hpp:9468
#define MBA_CALLS
callinfo has been built
Definition: hexrays.hpp:4457
bool op_uses_y(ctype_t op)
Does operator use the 'y' field of cexpr_t?
Definition: hexrays.hpp:5581
type_source_t
Type source (where the type information comes from)
Definition: hexrays.hpp:1037
allow_unused_labels_t
Unused label disposition.
Definition: hexrays.hpp:6671
@ ALLOW_UNUSED_LABELS
Unused labels are permitted.
Definition: hexrays.hpp:6673
@ FORBID_UNUSED_LABELS
Unused labels cause interr.
Definition: hexrays.hpp:6672
#define MBA_ASRPROP
assertion have been propagated
Definition: hexrays.hpp:4458
#define CVAR_USED
is used in the code?
Definition: hexrays.hpp:1167
user_labels_iterator_t user_labels_begin(const user_labels_t *map)
Get iterator pointing to the beginning of user_labels_t.
Definition: hexrays.hpp:9173
int const & user_labels_first(user_labels_iterator_t p)
Get reference to the current map key.
Definition: hexrays.hpp:9141
#define MBA_ASRTOK
assertions have been generated
Definition: hexrays.hpp:4456
#define ANCHOR_BLKCMT
block comment (for ctree items)
Definition: hexrays.hpp:6588
#define EXFL_CSTR
string literal
Definition: hexrays.hpp:6100
cexpr_t * dereference(cexpr_t *e, int ptrsize, bool is_flt=false)
Dereference a pointer.
Definition: hexrays.hpp:11821
#define IPROP_SPLIT1
into 1 byte
Definition: hexrays.hpp:3473
const mopt_t mop_z
none
Definition: hexrays.hpp:2240
boundaries_iterator_t boundaries_prev(boundaries_iterator_t p)
Move to the previous element.
Definition: hexrays.hpp:9417
#define ANCHOR_LVAR
declaration of local variable
Definition: hexrays.hpp:6586
lvar_mapping_iterator_t lvar_mapping_prev(lvar_mapping_iterator_t p)
Move to the previous element.
Definition: hexrays.hpp:8654
void clear_cached_cfuncs(void)
Flush all cached decompilation results.
Definition: hexrays.hpp:12117
const mopt_t mop_fn
floating point constant
Definition: hexrays.hpp:2253
bool is_bool_type(const tinfo_t &type)
Is a boolean type?
Definition: hexrays.hpp:9773
user_labels_iterator_t user_labels_find(const user_labels_t *map, const int &key)
Find the specified key in user_labels_t.
Definition: hexrays.hpp:9155
bool is_lvalue(ctype_t op)
Is Lvalue operator?
Definition: hexrays.hpp:5658
#define MBA_WINGR32
use wingraph32
Definition: hexrays.hpp:4473
#define MBA_SAVRST
save-restore analysis has been performed
Definition: hexrays.hpp:4459
#define EXFL_FPOP
floating point operation
Definition: hexrays.hpp:6098
bool is_nonbool_type(const tinfo_t &type)
Is definitely a non-boolean type?
Definition: hexrays.hpp:9767
bool parse_user_call(udcall_t *udc, const char *decl, bool silent)
Convert function type declaration into internal structure.
Definition: hexrays.hpp:9989
THREAD_SAFE bool is_mcode_propagatable(mcode_t mcode)
May opcode be propagated? Such opcodes can be used in sub-instructions (nested instructions) There is...
Definition: hexrays.hpp:9677
user_labels_iterator_t user_labels_insert(user_labels_t *map, const int &key, const qstring &val)
Insert new (int, qstring) pair into user_labels_t.
Definition: hexrays.hpp:9164
user_unions_iterator_t user_unions_end(const user_unions_t *map)
Get iterator pointing to the end of user_unions_t.
Definition: hexrays.hpp:9073
#define SHINS_VALNUM
display value numbers
Definition: hexrays.hpp:2399
cinsn_t *const & boundaries_first(boundaries_iterator_t p)
Get reference to the current map key.
Definition: hexrays.hpp:9359
user_cmts_iterator_t user_cmts_begin(const user_cmts_t *map)
Get iterator pointing to the beginning of user_cmts_t.
Definition: hexrays.hpp:8846
const cmt_type_t CMT_NONE
No comment is possible.
Definition: hexrays.hpp:7487
cexpr_t * make_num(uint64 n, cfunc_t *func=nullptr, ea_t ea=BADADDR, int opnum=0, type_sign_t sign=no_sign, int size=0)
Create a number expression.
Definition: hexrays.hpp:11809
#define MBA_RETREF
return type has been refined
Definition: hexrays.hpp:4460
block_chains_iterator_t block_chains_find(const block_chains_t *set, const chain_t &val)
Find the specified key in set block_chains_t.
Definition: hexrays.hpp:9475
#define IPROP_FARCALL
call of a far function using push cs/call sequence
Definition: hexrays.hpp:3465
#define MBA2_HAS_OUTLINES
calls to outlined code have been inlined
Definition: hexrays.hpp:4494
user_cmts_iterator_t user_cmts_insert(user_cmts_t *map, const treeloc_t &key, const citem_cmt_t &val)
Insert new (treeloc_t, citem_cmt_t) pair into user_cmts_t.
Definition: hexrays.hpp:8837
user_numforms_iterator_t user_numforms_insert(user_numforms_t *map, const operand_locator_t &key, const number_format_t &val)
Insert new (operand_locator_t, number_format_t) pair into user_numforms_t.
Definition: hexrays.hpp:8510
#define OPROP_FLOAT
possibly floating value
Definition: hexrays.hpp:2436
qstack< history_item_t > history_t
Navigation history.
Definition: hexrays.hpp:7482
void user_iflags_erase(user_iflags_t *map, user_iflags_iterator_t p)
Erase current element from user_iflags_t.
Definition: hexrays.hpp:8989
#define MBA_LVARS1
lvar real allocation has been performed
Definition: hexrays.hpp:4463
#define EXFL_LVALUE
expression is lvalue even if it doesn't look like it
Definition: hexrays.hpp:6097
const mopt_t mop_r
register (they exist until MMAT_LVARS)
Definition: hexrays.hpp:2241
cinsnptrvec_t & eamap_second(eamap_iterator_t p)
Get reference to the current map value.
Definition: hexrays.hpp:9257
void boundaries_free(boundaries_t *map)
Delete boundaries_t instance.
Definition: hexrays.hpp:9446
tinfo_t get_int_type_by_width_and_sign(int srcwidth, type_sign_t sign)
Create a type info by width and sign.
Definition: hexrays.hpp:9793
eamap_iterator_t eamap_end(const eamap_t *map)
Get iterator pointing to the end of eamap_t.
Definition: hexrays.hpp:9291
#define CVAR_OVER
overlapping variable
Definition: hexrays.hpp:1177
void udcall_map_clear(udcall_map_t *map)
Clear udcall_map_t.
Definition: hexrays.hpp:8778
#define CFS_LOCKED
cfunc is temporarily locked
Definition: hexrays.hpp:6891
user_cmts_iterator_t user_cmts_next(user_cmts_iterator_t p)
Move to the next element.
Definition: hexrays.hpp:8864
bool modify_user_lvars(ea_t entry_ea, user_lvar_modifier_t &mlv)
Modify saved local variable settings.
Definition: hexrays.hpp:9959
ea_t const & eamap_first(eamap_iterator_t p)
Get reference to the current map key.
Definition: hexrays.hpp:9250
const mopt_t mop_a
mop_addr_t: address of operand (mop_l, mop_v, mop_S, mop_r)
Definition: hexrays.hpp:2250
const cmt_type_t CMT_BLOCK1
Anterioir block comment.
Definition: hexrays.hpp:7489
const mopt_t mop_str
immediate string constant (user representation)
Definition: hexrays.hpp:2243
bool is_prepost(ctype_t op)
Is pre/post increment/decrement operator?
Definition: hexrays.hpp:5595
uint8 mopt_t
Instruction operand types.
Definition: hexrays.hpp:2238
void eamap_clear(eamap_t *map)
Clear eamap_t.
Definition: hexrays.hpp:9323
gctype_t
Kind of use-def and def-use chains.
Definition: hexrays.hpp:5000
@ GC_DIRTY_ALL
bitmask to represent all chains
Definition: hexrays.hpp:5005
@ GC_ASR
all the above and assertions
Definition: hexrays.hpp:5002
@ GC_END
number of chain types
Definition: hexrays.hpp:5004
@ GC_REGS_AND_STKVARS
registers and stkvars (restricted memory only)
Definition: hexrays.hpp:5001
@ GC_XDSU
only registers calculated with FULL_XDSU
Definition: hexrays.hpp:5003
user_iflags_t * restore_user_iflags(ea_t func_ea)
Restore user defined citem iflags from the database.
Definition: hexrays.hpp:11887
ctree_maturity_t
Ctree maturity level.
Definition: hexrays.hpp:5878
@ CMAT_CPA
corrected pointer arithmetic
Definition: hexrays.hpp:5884
@ CMAT_FINAL
ready-to-use
Definition: hexrays.hpp:5887
@ CMAT_CASTED
added necessary casts
Definition: hexrays.hpp:5886
@ CMAT_BUILT
just generated
Definition: hexrays.hpp:5880
@ CMAT_NICE
nicefied expressions
Definition: hexrays.hpp:5882
@ CMAT_TRANS2
applied second wave of transformations
Definition: hexrays.hpp:5883
@ CMAT_TRANS3
applied third wave of transformations
Definition: hexrays.hpp:5885
@ CMAT_TRANS1
applied first wave of transformations
Definition: hexrays.hpp:5881
@ CMAT_ZERO
does not exist
Definition: hexrays.hpp:5879
bool is_loop(ctype_t op)
Is loop statement code?
Definition: hexrays.hpp:5645
#define OPTI_COMBINSNS
may combine insns (only for optimize_insn)
Definition: hexrays.hpp:3590
type_sign_t get_op_signness(ctype_t op)
Get operator sign. Meaningful for sign-dependent operators, like cot_sdiv.
Definition: hexrays.hpp:11407
user_unions_t * restore_user_unions(ea_t func_ea)
Restore user defined union field selections from the database.
Definition: hexrays.hpp:11893
qvector< block_chains_t > block_chains_vec_t
Graph chains.
Definition: hexrays.hpp:3403
#define LVINF_FORCE
force allocation of a new variable.
Definition: hexrays.hpp:1439
#define MBA_NICE
apply transformations to c code
Definition: hexrays.hpp:4471
block_chains_iterator_t block_chains_insert(block_chains_t *set, const chain_t &val)
Insert new (chain_t) into set block_chains_t.
Definition: hexrays.hpp:9484
#define IPROP_INV_JX
inverted conditional jump
Definition: hexrays.hpp:3482
cfuncptr_t create_cfunc(mba_t *mba)
Create a new cfunc_t object.
Definition: hexrays.hpp:12105
#define OPROP_CCFLAGS
mop_n: a pc-relative value else: value of a condition code register (like mr_cc)
Definition: hexrays.hpp:2437
#define NF_NEGDONE
temporary internal bit: negation has been performed
Definition: hexrays.hpp:786
#define IPROP_SPLIT
the instruction has been split:
Definition: hexrays.hpp:3472
#define CHF_PASSTHRU
pass-thru chain, must use the input variable to the block
Definition: hexrays.hpp:3298
ctype_t negated_relation(ctype_t op)
Negate a comparison operator. For example, cot_sge becomes cot_slt.
Definition: hexrays.hpp:11395
#define EXFL_UNDEF
expression uses undefined value
Definition: hexrays.hpp:6102
#define IPROP_UNMERGED
'goto' instruction was transformed info 'call'
Definition: hexrays.hpp:3492
#define MBA_LVARS0
lvar pre-allocation has been performed
Definition: hexrays.hpp:4462
user_numforms_iterator_t user_numforms_end(const user_numforms_t *map)
Get iterator pointing to the end of user_numforms_t.
Definition: hexrays.hpp:8528
int mreg2reg(mreg_t reg, int width)
Map a microregister to a processor register.
Definition: hexrays.hpp:10328
const mopt_t mop_p
operand pair
Definition: hexrays.hpp:2254
#define CVAR_FAKE
fake variable (return var or va_list)
Definition: hexrays.hpp:1176
size_t user_iflags_size(user_iflags_t *map)
Get size of user_iflags_t.
Definition: hexrays.hpp:9003
mreg_t reg2mreg(int reg)
Map a processor register to a microregister.
Definition: hexrays.hpp:10322
#define LVINF_NOMAP
forbid automatic mapping of the variable
Definition: hexrays.hpp:1443
#define MBA_PATTERN
microcode pattern, callinfo is present
Definition: hexrays.hpp:4445
#define MBA_LOADED
loaded gdl, no instructions (debugging)
Definition: hexrays.hpp:4446
ctype_t swapped_relation(ctype_t op)
Swap a comparison operator. For example, cot_sge becomes cot_sle.
Definition: hexrays.hpp:11401
int cmt_type_t
Comment types.
Definition: hexrays.hpp:7485
THREAD_SAFE bool is_ptr_or_array(type_t t)
Is a pointer or array type?
Definition: hexrays.hpp:945
use_curly_t
Should curly braces be printed?
Definition: hexrays.hpp:6331
@ USE_CURLY_BRACES
print curly braces without any checks
Definition: hexrays.hpp:6334
@ CALC_CURLY_BRACES
print curly braces if necessary
Definition: hexrays.hpp:6332
@ NO_CURLY_BRACES
don't print curly braces
Definition: hexrays.hpp:6333
udcall_map_iterator_t udcall_map_find(const udcall_map_t *map, const ea_t &key)
Find the specified key in udcall_map_t.
Definition: hexrays.hpp:8719
void user_numforms_clear(user_numforms_t *map)
Clear user_numforms_t.
Definition: hexrays.hpp:8560
ctype_t
Ctree item code.
Definition: hexrays.hpp:5479
@ cot_asgxor
x ^= y
Definition: hexrays.hpp:5484
@ cot_call
x(...)
Definition: hexrays.hpp:5537
@ cot_ule
x <= y unsigned
Definition: hexrays.hpp:5507
@ cot_asgsdiv
x /= y signed
Definition: hexrays.hpp:5492
@ cit_break
break-statement
Definition: hexrays.hpp:5559
@ cot_cast
(type)x
Definition: hexrays.hpp:5528
@ cot_sgt
x > y signed or fpu (see EXFL_FPOP)
Definition: hexrays.hpp:5508
@ cot_sdiv
x / y signed
Definition: hexrays.hpp:5518
@ cit_do
do-statement
Definition: hexrays.hpp:5557
@ cot_insn
instruction in expression, internal representation only
Definition: hexrays.hpp:5546
@ cot_lor
x || y
Definition: hexrays.hpp:5497
@ cot_tern
x ? y : z
Definition: hexrays.hpp:5496
@ cot_asgbor
x |= y
Definition: hexrays.hpp:5483
@ cit_block
block-statement: { ... }
Definition: hexrays.hpp:5552
@ cit_continue
continue-statement
Definition: hexrays.hpp:5560
@ cot_lnot
!x
Definition: hexrays.hpp:5529
@ cot_asgshl
x <<= y
Definition: hexrays.hpp:5491
@ cot_ptr
*x, access size in 'ptrsize'
Definition: hexrays.hpp:5531
@ cot_preinc
++x
Definition: hexrays.hpp:5535
@ cot_shl
x << y
Definition: hexrays.hpp:5514
@ cot_obj
obj_ea
Definition: hexrays.hpp:5544
@ cot_neg
-x
Definition: hexrays.hpp:5527
@ cot_xor
x ^ y
Definition: hexrays.hpp:5500
@ cot_add
x + y
Definition: hexrays.hpp:5515
@ cot_sshr
x >> y signed
Definition: hexrays.hpp:5512
@ cot_asg
x = y
Definition: hexrays.hpp:5482
@ cot_type
arbitrary type
Definition: hexrays.hpp:5549
@ cot_sub
x - y
Definition: hexrays.hpp:5516
@ cot_slt
x < y signed or fpu (see EXFL_FPOP)
Definition: hexrays.hpp:5510
@ cot_mul
x * y
Definition: hexrays.hpp:5517
@ cot_udiv
x / y unsigned
Definition: hexrays.hpp:5519
@ cot_asgsshr
x >>= y signed
Definition: hexrays.hpp:5489
@ cot_eq
x == y int or fpu (see EXFL_FPOP)
Definition: hexrays.hpp:5502
@ cit_return
return-statement
Definition: hexrays.hpp:5561
@ cot_asgadd
x += y
Definition: hexrays.hpp:5486
@ cot_ref
&x
Definition: hexrays.hpp:5532
@ cot_ne
x != y int or fpu (see EXFL_FPOP)
Definition: hexrays.hpp:5503
@ cit_empty
instruction types start here
Definition: hexrays.hpp:5551
@ cit_asm
asm-statement
Definition: hexrays.hpp:5563
@ cot_predec
–x
Definition: hexrays.hpp:5536
@ cot_asgmul
x *= y
Definition: hexrays.hpp:5488
@ cot_helper
arbitrary name
Definition: hexrays.hpp:5548
@ cot_fneg
-x fp
Definition: hexrays.hpp:5526
@ cot_ult
x < y unsigned
Definition: hexrays.hpp:5511
@ cot_uge
x >= y unsigned
Definition: hexrays.hpp:5505
@ cot_fadd
x + y fp
Definition: hexrays.hpp:5522
@ cot_asgushr
x >>= y unsigned
Definition: hexrays.hpp:5490
@ cot_fnum
fpc
Definition: hexrays.hpp:5542
@ cot_postdec
x–
Definition: hexrays.hpp:5534
@ cot_memref
x.m
Definition: hexrays.hpp:5539
@ cot_postinc
x++
Definition: hexrays.hpp:5533
@ cot_sizeof
sizeof(x)
Definition: hexrays.hpp:5547
@ cot_sle
x <= y signed or fpu (see EXFL_FPOP)
Definition: hexrays.hpp:5506
@ cot_ushr
x >> y unsigned
Definition: hexrays.hpp:5513
@ cot_fdiv
x / y fp
Definition: hexrays.hpp:5525
@ cit_while
while-statement
Definition: hexrays.hpp:5556
@ cot_fsub
x - y fp
Definition: hexrays.hpp:5523
@ cot_str
string constant (user representation)
Definition: hexrays.hpp:5543
@ cot_var
v
Definition: hexrays.hpp:5545
@ cot_sge
x >= y signed or fpu (see EXFL_FPOP)
Definition: hexrays.hpp:5504
@ cit_goto
goto-statement
Definition: hexrays.hpp:5562
@ cit_switch
switch-statement
Definition: hexrays.hpp:5558
@ cot_asgband
x &= y
Definition: hexrays.hpp:5485
@ cot_asgsmod
x %= y signed
Definition: hexrays.hpp:5494
@ cot_num
n
Definition: hexrays.hpp:5541
@ cot_band
x & y
Definition: hexrays.hpp:5501
@ cot_bnot
~x
Definition: hexrays.hpp:5530
@ cot_comma
x, y
Definition: hexrays.hpp:5481
@ cot_asgsub
x -= y
Definition: hexrays.hpp:5487
@ cit_if
if-statement
Definition: hexrays.hpp:5554
@ cot_smod
x % y signed
Definition: hexrays.hpp:5520
@ cot_bor
x | y
Definition: hexrays.hpp:5499
@ cot_umod
x % y unsigned
Definition: hexrays.hpp:5521
@ cot_memptr
x->m, access size in 'ptrsize'
Definition: hexrays.hpp:5540
@ cot_asgumod
x %= y unsigned
Definition: hexrays.hpp:5495
@ cot_ugt
x > y unsigned
Definition: hexrays.hpp:5509
@ cot_asgudiv
x /= y unsigned
Definition: hexrays.hpp:5493
@ cot_idx
x[y]
Definition: hexrays.hpp:5538
@ cot_fmul
x * y fp
Definition: hexrays.hpp:5524
@ cit_expr
expression-statement: expr;
Definition: hexrays.hpp:5553
@ cot_land
x && y
Definition: hexrays.hpp:5498
@ cit_for
for-statement
Definition: hexrays.hpp:5555
lvar_mapping_iterator_t lvar_mapping_next(lvar_mapping_iterator_t p)
Move to the next element.
Definition: hexrays.hpp:8646
bool restore_user_lvar_settings(lvar_uservec_t *lvinf, ea_t func_ea)
Restore user defined local variable settings in the database.
Definition: hexrays.hpp:9947
funcrole_t
Function roles.
Definition: hexrays.hpp:3033
@ ROLE_3WAYCMP1
3-way compare helper, returns 0/1/2
Definition: hexrays.hpp:3067
@ ROLE_VA_COPY
va_copy() function
Definition: hexrays.hpp:3058
@ ROLE_UNK
unknown function role
Definition: hexrays.hpp:3034
@ ROLE_VA_ARG
va_arg() macro
Definition: hexrays.hpp:3057
@ ROLE_BITTEST
[lock] bt
Definition: hexrays.hpp:3053
@ ROLE_BUG
BUG() helper macro: never returns, causes exception.
Definition: hexrays.hpp:3044
@ ROLE_SSE_CMP4
e.g. _mm_cmpgt_ss
Definition: hexrays.hpp:3073
@ ROLE_EMPTY
empty, does not do anything (maybe spoils regs)
Definition: hexrays.hpp:3035
@ ROLE_MEMSET64
memset64(void *dst, uint64 value, size_t count);
Definition: hexrays.hpp:3038
@ ROLE_ALLOCA
alloca() function
Definition: hexrays.hpp:3045
@ ROLE_WMEMCPY
wchar_t *wmemcpy(wchar_t *dst, const wchar_t *src, size_t n)
Definition: hexrays.hpp:3068
@ ROLE_FASTFAIL
__fastfail()
Definition: hexrays.hpp:3049
@ ROLE_SATURATED_MUL
saturated_mul
Definition: hexrays.hpp:3052
@ ROLE_BITTESTANDSET
[lock] bts
Definition: hexrays.hpp:3054
@ ROLE_WCSCPY
wchar_t *wcscpy(wchar_t *dst, const wchar_t *src);
Definition: hexrays.hpp:3070
@ ROLE_SSE_CMP8
e.g. _mm_cmpgt_sd
Definition: hexrays.hpp:3074
@ ROLE_STRCAT
strcat(char *dst, const char *src);
Definition: hexrays.hpp:3042
@ ROLE_TAIL
char *tail(const char *str);
Definition: hexrays.hpp:3043
@ ROLE_CFSUB3
carry flag after subtract with carry
Definition: hexrays.hpp:3063
@ ROLE_READFLAGS
__readeflags, __readcallersflags
Definition: hexrays.hpp:3050
@ ROLE_MEMCPY
memcpy(void *dst, const void *src, size_t count);
Definition: hexrays.hpp:3039
@ ROLE_OFSUB3
overflow flag after subtract with carry
Definition: hexrays.hpp:3064
@ ROLE_PRESENT
present() function (used in patterns)
Definition: hexrays.hpp:3047
@ ROLE_BITTESTANDCOMPLEMENT
[lock] btc
Definition: hexrays.hpp:3056
@ ROLE_ABS
integer absolute value
Definition: hexrays.hpp:3065
@ ROLE_VA_START
va_start() function
Definition: hexrays.hpp:3059
@ ROLE_STRLEN
strlen(const char *src);
Definition: hexrays.hpp:3041
@ ROLE_STRCPY
strcpy(char *dst, const char *src);
Definition: hexrays.hpp:3040
@ ROLE_WCSLEN
size_t wcslen(const wchar_t *s)
Definition: hexrays.hpp:3071
@ ROLE_ROR
rotate right
Definition: hexrays.hpp:3062
@ ROLE_MEMSET
memset(void *dst, uchar value, size_t count);
Definition: hexrays.hpp:3036
@ ROLE_IS_MUL_OK
is_mul_ok
Definition: hexrays.hpp:3051
@ ROLE_VA_END
va_end() function
Definition: hexrays.hpp:3060
@ ROLE_WMEMSET
wchar_t *wmemset(wchar_t *dst, wchar_t wc, size_t n)
Definition: hexrays.hpp:3069
@ ROLE_CONTAINING_RECORD
CONTAINING_RECORD() macro.
Definition: hexrays.hpp:3048
@ ROLE_BITTESTANDRESET
[lock] btr
Definition: hexrays.hpp:3055
@ ROLE_MEMSET32
memset32(void *dst, uint32 value, size_t count);
Definition: hexrays.hpp:3037
@ ROLE_BSWAP
bswap() function (any size)
Definition: hexrays.hpp:3046
@ ROLE_ROL
rotate left
Definition: hexrays.hpp:3061
@ ROLE_WCSCAT
wchar_t *wcscat(wchar_t *dst, const wchar_t *src)
Definition: hexrays.hpp:3072
@ ROLE_3WAYCMP0
3-way compare helper, returns -1/0/1
Definition: hexrays.hpp:3066
bool remove_optblock_handler(optblock_t *opt)
Remove a block level custom optimizer.
Definition: hexrays.hpp:10358
#define MBA_GLBOPT
microcode has been optimized globally
Definition: hexrays.hpp:4461
bool checkout_hexrays_license(bool silent)
Check out a floating decompiler license.
Definition: hexrays.hpp:11333
#define MBA2_IS_DTR
is destructor?
Definition: hexrays.hpp:4485
void save_user_labels(ea_t func_ea, const user_labels_t *user_labels)
Save user defined labels into the database.
Definition: hexrays.hpp:11827
user_labels_t * user_labels_new()
Create a new user_labels_t instance.
Definition: hexrays.hpp:9235
user_labels_iterator_t user_labels_end(const user_labels_t *map)
Get iterator pointing to the end of user_labels_t.
Definition: hexrays.hpp:9182
#define MBA_REFINE
may refine return value size
Definition: hexrays.hpp:4472
bool close_pseudocode(TWidget *f)
Close pseudocode window.
Definition: hexrays.hpp:11345
#define EXFL_VFTABLE
is ptr to vftable (used for cot_memptr, cot_memref)
Definition: hexrays.hpp:6104
#define CV_PARENTS
maintain parent information
Definition: hexrays.hpp:5740
bool install_hexrays_callback(hexrays_cb_t *callback, void *ud)
Install handler for decompiler events.
Definition: hexrays.hpp:12143
user_iflags_t * user_iflags_new()
Create a new user_iflags_t instance.
Definition: hexrays.hpp:9017
#define MBA2_CODE16_BIT
the code16 bit removed
Definition: hexrays.hpp:4492
void boundaries_clear(boundaries_t *map)
Clear boundaries_t.
Definition: hexrays.hpp:9432
#define IPROP_COMBINED
insn has been modified because of a partial reference
Definition: hexrays.hpp:3477
const mopt_t mop_n
immediate number constant
Definition: hexrays.hpp:2242
#define MBA_INSGDL
display instruction in graphs
Definition: hexrays.hpp:4470
user_numforms_t * user_numforms_new()
Create a new user_numforms_t instance.
Definition: hexrays.hpp:8581
user_unions_iterator_t user_unions_find(const user_unions_t *map, const ea_t &key)
Find the specified key in user_unions_t.
Definition: hexrays.hpp:9046
hexcall_t
API call numbers.
Definition: hexrays.hpp:7860
#define MBA2_STACK_RETVAL
the return value is on the stack
Definition: hexrays.hpp:4493
boundaries_t * boundaries_new()
Create a new boundaries_t instance.
Definition: hexrays.hpp:9453
#define MBA_CHVARS
can verify chain varnums
Definition: hexrays.hpp:4465
side_effect_t
How to handle side effect of change_size() Sometimes we need to create a temporary operand and change...
Definition: hexrays.hpp:2410
@ ONLY_SIDEFF
only handle side effects
Definition: hexrays.hpp:2415
@ ANY_REGSIZE
any register size is permitted
Definition: hexrays.hpp:2416
@ NO_SIDEFF
change operand size but ignore side effects if you decide to keep the changed operand,...
Definition: hexrays.hpp:2411
@ ANY_FPSIZE
any size of floating operand is permitted
Definition: hexrays.hpp:2417
@ WITH_SIDEFF
change operand size and handle side effects
Definition: hexrays.hpp:2414
int remove_hexrays_callback(hexrays_cb_t *callback, void *ud)
Uninstall handler for decompiler events.
Definition: hexrays.hpp:12149
bool is_assignment(ctype_t op)
Is assignment operator?
Definition: hexrays.hpp:5591
void save_user_numforms(ea_t func_ea, const user_numforms_t *numforms)
Save user defined number formats into the database.
Definition: hexrays.hpp:11845
void user_numforms_free(user_numforms_t *map)
Delete user_numforms_t instance.
Definition: hexrays.hpp:8574
user_unions_iterator_t user_unions_begin(const user_unions_t *map)
Get iterator pointing to the beginning of user_unions_t.
Definition: hexrays.hpp:9064
#define IPROP_MBARRIER
this instruction acts as a memory barrier (instructions accessing memory may not be reordered past it...
Definition: hexrays.hpp:3490
void install_optblock_handler(optblock_t *opt)
Install a block level custom optimizer.
Definition: hexrays.hpp:10352
cexpr_t * make_ref(cexpr_t *e)
Create a reference.
Definition: hexrays.hpp:11815
boundaries_iterator_t boundaries_next(boundaries_iterator_t p)
Move to the next element.
Definition: hexrays.hpp:9409
void user_unions_erase(user_unions_t *map, user_unions_iterator_t p)
Erase current element from user_unions_t.
Definition: hexrays.hpp:9098
number_format_t & user_numforms_second(user_numforms_iterator_t p)
Get reference to the current map value.
Definition: hexrays.hpp:8494
void user_unions_free(user_unions_t *map)
Delete user_unions_t instance.
Definition: hexrays.hpp:9119
#define NF_BINVDONE
temporary internal bit: inverting bits is done
Definition: hexrays.hpp:787
bool is_logical(ctype_t op)
Is logical operator?
Definition: hexrays.hpp:5637
bool install_microcode_filter(microcode_filter_t *filter, bool install=true)
register/unregister non-standard microcode generator
Definition: hexrays.hpp:10001
lvar_locator_t const & lvar_mapping_first(lvar_mapping_iterator_t p)
Get reference to the current map key.
Definition: hexrays.hpp:8596
citem_cmt_t & user_cmts_second(user_cmts_iterator_t p)
Get reference to the current map value.
Definition: hexrays.hpp:8821
user_iflags_iterator_t user_iflags_find(const user_iflags_t *map, const citem_locator_t &key)
Find the specified key in user_iflags_t.
Definition: hexrays.hpp:8937
#define MBA_COLGDL
display graph after each reduction
Definition: hexrays.hpp:4469
tinfo_t create_typedef(const char *name)
Create a reference to a named type.
Definition: hexrays.hpp:9831
#define IPROP_TAILCALL
tail call
Definition: hexrays.hpp:3466
const mopt_t mop_f
list of arguments
Definition: hexrays.hpp:2248
eamap_iterator_t eamap_insert(eamap_t *map, const ea_t &key, const cinsnptrvec_t &val)
Insert new (ea_t, cinsnptrvec_t) pair into eamap_t.
Definition: hexrays.hpp:9273
cfuncptr_t decompile_snippet(const rangevec_t &ranges, hexrays_failure_t *hf, int decomp_flags=0)
Decompile a snippet.
Definition: hexrays.hpp:7113
void lvar_mapping_free(lvar_mapping_t *map)
Delete lvar_mapping_t instance.
Definition: hexrays.hpp:8683
#define MBA_NUMADDR
display definition addresses for numbers
Definition: hexrays.hpp:4474
size_t block_chains_size(block_chains_t *set)
Get size of block_chains_t.
Definition: hexrays.hpp:9541
#define MBL_LIST
use/def lists are ready (not dirty)
Definition: hexrays.hpp:3789
#define OPTI_MINSTKREF
may update minstkref
Definition: hexrays.hpp:3589
ea_t const & udcall_map_first(udcall_map_iterator_t p)
Get reference to the current map key.
Definition: hexrays.hpp:8705
void user_labels_free(user_labels_t *map)
Delete user_labels_t instance.
Definition: hexrays.hpp:9228
#define CVAR_RESULT
function result variable
Definition: hexrays.hpp:1174
size_t lvar_mapping_size(lvar_mapping_t *map)
Get size of lvar_mapping_t.
Definition: hexrays.hpp:8676
#define MBA_DELPAIRS
pairs have been deleted once
Definition: hexrays.hpp:4464
#define MBA2_IS_CTR
is constructor?
Definition: hexrays.hpp:4484
void install_optinsn_handler(optinsn_t *opt)
Install an instruction level custom optimizer.
Definition: hexrays.hpp:10340
void user_iflags_free(user_iflags_t *map)
Delete user_iflags_t instance.
Definition: hexrays.hpp:9010
bool rename_lvar(ea_t func_ea, const char *oldname, const char *newname)
Rename a local variable.
Definition: hexrays.hpp:1625
#define MBA2_ARGIDX_SORTED
args finally sorted according to ABI (e.g.
Definition: hexrays.hpp:4490
#define CV_POST
call the leave...() functions
Definition: hexrays.hpp:5741
user_iflags_iterator_t user_iflags_begin(const user_iflags_t *map)
Get iterator pointing to the beginning of user_iflags_t.
Definition: hexrays.hpp:8955
void user_labels_erase(user_labels_t *map, user_labels_iterator_t p)
Erase current element from user_labels_t.
Definition: hexrays.hpp:9207
lvar_mapping_iterator_t lvar_mapping_find(const lvar_mapping_t *map, const lvar_locator_t &key)
Find the specified key in lvar_mapping_t.
Definition: hexrays.hpp:8610
lvar_mapping_iterator_t lvar_mapping_begin(const lvar_mapping_t *map)
Get iterator pointing to the beginning of lvar_mapping_t.
Definition: hexrays.hpp:8628
user_numforms_t * restore_user_numforms(ea_t func_ea)
Restore user defined number formats from the database.
Definition: hexrays.hpp:11881
eamap_t * eamap_new()
Create a new eamap_t instance.
Definition: hexrays.hpp:9344
block_chains_iterator_t block_chains_end(const block_chains_t *set)
Get iterator pointing to the end of block_chains_t.
Definition: hexrays.hpp:9502
#define IPROP_DONT_COMB
may not combine this instruction with others
Definition: hexrays.hpp:3489
#define CVAR_ARG
function argument
Definition: hexrays.hpp:1175
#define CVAR_TYPE
the type is defined?
Definition: hexrays.hpp:1168
#define SHINS_NUMADDR
display definition addresses for numbers
Definition: hexrays.hpp:2398
#define CVAR_AUTOMAP
variable was automatically mapped
Definition: hexrays.hpp:1191
lvar_mapping_iterator_t lvar_mapping_insert(lvar_mapping_t *map, const lvar_locator_t &key, const lvar_locator_t &val)
Insert new (lvar_locator_t, lvar_locator_t) pair into lvar_mapping_t.
Definition: hexrays.hpp:8619
#define OPROP_UDEFVAL
uses undefined value
Definition: hexrays.hpp:2439
void save_user_unions(ea_t func_ea, const user_unions_t *unions)
Save user defined union field selections into the database.
Definition: hexrays.hpp:11857
#define EXFL_PARTIAL
type of the expression is considered partial
Definition: hexrays.hpp:6101
#define EXFL_JUMPOUT
jump out-of-function
Definition: hexrays.hpp:6103
#define IPROP_SPLIT2
into 2 bytes
Definition: hexrays.hpp:3474
bool op_uses_x(ctype_t op)
Does operator use the 'x' field of cexpr_t?
Definition: hexrays.hpp:5579
const char * dstr(const tinfo_t *tif)
Print the specified type info.
Definition: hexrays.hpp:9749
citem_locator_t const & user_iflags_first(user_iflags_iterator_t p)
Get reference to the current map key.
Definition: hexrays.hpp:8923
#define IPROP_SPLIT8
into 8 bytes
Definition: hexrays.hpp:3476
#define MBL_DMT64
needs "demote 64bits"
Definition: hexrays.hpp:3785
#define NF_BITNOT
The user asked to invert bits of the constant.
Definition: hexrays.hpp:789
#define FD_USE
look for use
Definition: hexrays.hpp:4125
user_unions_iterator_t user_unions_insert(user_unions_t *map, const ea_t &key, const intvec_t &val)
Insert new (ea_t, intvec_t) pair into user_unions_t.
Definition: hexrays.hpp:9055
tinfo_t get_unk_type(int size)
Create a partial type info by width.
Definition: hexrays.hpp:9801
bool locate_lvar(lvar_locator_t *out, ea_t func_ea, const char *varname)
Find a variable by name.
Definition: hexrays.hpp:9971
user_cmts_t * user_cmts_new()
Create a new user_cmts_t instance.
Definition: hexrays.hpp:8908
#define SHINS_SHORT
do not display use-def chains and other attrs
Definition: hexrays.hpp:2400
#define VDUI_VALID
is valid?
Definition: hexrays.hpp:7504
qvector< cinsn_t * > cinsnptrvec_t
Vector of pointers to statements.
Definition: hexrays.hpp:6411
#define CVAR_PARTIAL
variable type is partialy defined
Definition: hexrays.hpp:1181
#define MBA2_VALRNG_DONE
calculated valranges?
Definition: hexrays.hpp:4483
const mopt_t mop_c
mcases
Definition: hexrays.hpp:2252
udcall_t & udcall_map_second(udcall_map_iterator_t p)
Get reference to the current map value.
Definition: hexrays.hpp:8712
block_chains_t * block_chains_new()
Create a new block_chains_t instance.
Definition: hexrays.hpp:9555
void term_hexrays_plugin()
Stop working with hex-rays decompiler.
Definition: hexrays.hpp:8472
mblock_type_t
Basic block types.
Definition: hexrays.hpp:3748
@ BLT_NONE
unknown block type
Definition: hexrays.hpp:3749
@ BLT_XTRN
external block (out of function address)
Definition: hexrays.hpp:3755
@ BLT_STOP
stops execution regularly (must be the last block)
Definition: hexrays.hpp:3750
@ BLT_2WAY
passes execution to two blocks (conditional jump)
Definition: hexrays.hpp:3753
@ BLT_0WAY
does not have successors (tail is a noret function)
Definition: hexrays.hpp:3751
@ BLT_1WAY
passes execution to one block (regular or goto block)
Definition: hexrays.hpp:3752
@ BLT_NWAY
passes execution to many blocks (switch idiom)
Definition: hexrays.hpp:3754
#define CVAR_MREG
corresponding mregs were replaced?
Definition: hexrays.hpp:1170
cfuncptr_t decompile(const mba_ranges_t &mbr, hexrays_failure_t *hf, int decomp_flags=0)
Decompile a snippet or a function.
Definition: hexrays.hpp:12093
ctype_t asgop_revert(ctype_t cop)
Convert assignment operator into plain operator.
Definition: hexrays.hpp:11419
size_t user_labels_size(user_labels_t *map)
Get size of user_labels_t.
Definition: hexrays.hpp:9221
THREAD_SAFE bool is_paf(type_t t)
Is a pointer, array, or function type?
Definition: hexrays.hpp:951
tinfo_t make_pointer(const tinfo_t &type)
Create a pointer type.
Definition: hexrays.hpp:9823
#define IPROP_FPINSN
floating point insn
Definition: hexrays.hpp:3464
block_chains_iterator_t block_chains_begin(const block_chains_t *set)
Get iterator pointing to the beginning of block_chains_t.
Definition: hexrays.hpp:9493
#define CVAR_NOWD
width is unknown
Definition: hexrays.hpp:1171
bool decompile_many(const char *outfile, const eavec_t *funcaddrs, int flags)
Batch decompilation.
Definition: hexrays.hpp:11357
#define IPROP_EXTSTX
this is m_ext propagated into m_stx
Definition: hexrays.hpp:3478
void close_hexrays_waitbox(void)
Close the waitbox displayed by the decompiler.
Definition: hexrays.hpp:12087
void boundaries_erase(boundaries_t *map, boundaries_iterator_t p)
Erase current element from boundaries_t.
Definition: hexrays.hpp:9425
boundaries_iterator_t boundaries_insert(boundaries_t *map, const cinsn_t *&key, const rangeset_t &val)
Insert new (cinsn_t *, rangeset_t) pair into boundaries_t.
Definition: hexrays.hpp:9382
user_cmts_iterator_t user_cmts_find(const user_cmts_t *map, const treeloc_t &key)
Find the specified key in user_cmts_t.
Definition: hexrays.hpp:8828
#define CVAR_SPOILED
internal flag, do not use: spoiled var
Definition: hexrays.hpp:1179
#define IPROP_MULTI_MOV
the minsn was generated as part of insn that moves multiple registers (example: STM on ARM may transf...
Definition: hexrays.hpp:3484
#define IPROP_IGNLOWSRC
low part of the instruction source operand has been created artificially (this bit is used only for '...
Definition: hexrays.hpp:3479
vdui_t * get_widget_vdui(TWidget *f)
Get the vdui_t instance associated to the TWidget.
Definition: hexrays.hpp:11351
const mopt_t mop_v
global variable
Definition: hexrays.hpp:2246
user_iflags_iterator_t user_iflags_end(const user_iflags_t *map)
Get iterator pointing to the end of user_iflags_t.
Definition: hexrays.hpp:8964
#define MBA2_LVARNAMES_OK
may verify lvar_names?
Definition: hexrays.hpp:4480
#define CVAR_DUMMY
dummy argument (added to fill a hole in the argument list)
Definition: hexrays.hpp:1188
#define CVAR_NOTARG
variable cannot be an input argument
Definition: hexrays.hpp:1190
user_labels_iterator_t user_labels_prev(user_labels_iterator_t p)
Move to the previous element.
Definition: hexrays.hpp:9199
mba_t * gen_microcode(const mba_ranges_t &mbr, hexrays_failure_t *hf, const mlist_t *retlist=nullptr, int decomp_flags=0, mba_maturity_t reqmat=MMAT_GLBOPT3)
Generate microcode of an arbitrary code snippet.
Definition: hexrays.hpp:12099
user_iflags_iterator_t user_iflags_prev(user_iflags_iterator_t p)
Move to the previous element.
Definition: hexrays.hpp:8981
bool is_multiplicative(ctype_t op)
Is multiplicative operator?
Definition: hexrays.hpp:5618
#define MBA_PRCDEFS
use precise defeas for chain-allocated lvars
Definition: hexrays.hpp:4443
void udcall_map_erase(udcall_map_t *map, udcall_map_iterator_t p)
Erase current element from udcall_map_t.
Definition: hexrays.hpp:8771
#define CVAR_NOPTR
variable cannot be a pointer (user choice)
Definition: hexrays.hpp:1187
mba_maturity_t
Microcode maturity levels.
Definition: hexrays.hpp:4298
@ MMAT_LOCOPT
local optimization of each basic block is complete.
Definition: hexrays.hpp:4302
@ MMAT_LVARS
allocated local variables
Definition: hexrays.hpp:4308
@ MMAT_CALLS
detected call arguments
Definition: hexrays.hpp:4304
@ MMAT_GLBOPT1
performed the first pass of global optimization
Definition: hexrays.hpp:4305
@ MMAT_PREOPTIMIZED
preoptimized pass is complete
Definition: hexrays.hpp:4301
@ MMAT_ZERO
microcode does not exist
Definition: hexrays.hpp:4299
@ MMAT_GLBOPT3
completed all global optimization. microcode is fixed now.
Definition: hexrays.hpp:4307
@ MMAT_GLBOPT2
most global optimization passes are done
Definition: hexrays.hpp:4306
@ MMAT_GENERATED
generated microcode
Definition: hexrays.hpp:4300
void save_user_lvar_settings(ea_t func_ea, const lvar_uservec_t &lvinf)
Save user defined local variable settings into the database.
Definition: hexrays.hpp:9953
ctype_t asgop(ctype_t cop)
Convert plain operator into assignment operator. For example, cot_add returns cot_asgadd.
Definition: hexrays.hpp:11413
bool restore_user_defined_calls(udcall_map_t *udcalls, ea_t func_ea)
Restore user defined function calls from the database.
Definition: hexrays.hpp:9977
bool remove_optinsn_handler(optinsn_t *opt)
Remove an instruction level custom optimizer.
Definition: hexrays.hpp:10346
void eamap_free(eamap_t *map)
Delete eamap_t instance.
Definition: hexrays.hpp:9337
warnid_t
Warning ids.
Definition: hexrays.hpp:4211
@ WARN_OPT_VALRNG2
52 mask 0xX is shortened because s <= 0xX"
Definition: hexrays.hpp:4265
@ WARN_GUESSED_TYPE
9 using guessed type s;
Definition: hexrays.hpp:4221
@ WARN_BAD_STROFF
33 user specified stroff has not been processed: s
Definition: hexrays.hpp:4245
@ WARN_OPT_USELESS_JCND
54 simplified comparisons for 's': s became s
Definition: hexrays.hpp:4268
@ WARN_FIXED_MACRO
29 fixed broken macro-insn
Definition: hexrays.hpp:4241
@ WARN_ODD_INPUT_REG
15 odd input register s
Definition: hexrays.hpp:4227
@ WARN_ILL_FUNCTYPE
2 invalid function type has been ignored
Definition: hexrays.hpp:4214
@ WARN_ILL_PURGED
1 odd caller purged bytes d, correcting
Definition: hexrays.hpp:4213
@ WARN_UNINITED_REG
28 reference to an uninitialized register has been removed: s
Definition: hexrays.hpp:4240
@ WARN_ODD_ADDR_USE
16 odd use of a variable address
Definition: hexrays.hpp:4228
@ WARN_CBUILD_LOOPS
13 too many cbuild loops
Definition: hexrays.hpp:4225
@ WARN_BAD_VARSIZE
34 inconsistent variable size for 's'
Definition: hexrays.hpp:4246
@ WARN_VARARG_MANY
5 too many varargs, some ignored
Definition: hexrays.hpp:4217
@ WARN_MAX
may be used in notes as a placeholder when the warning id is not available
Definition: hexrays.hpp:4269
@ WARN_UNBALANCED_STACK
51 unbalanced stack, ignored a potential tail call
Definition: hexrays.hpp:4263
@ WARN_FRAG_LVAR
26 fragmented variable at s may be wrong
Definition: hexrays.hpp:4238
@ WARN_BAD_PURGED
12 inconsistent function type and number of purged bytes
Definition: hexrays.hpp:4224
@ WARN_UNSUPP_REG
35 unsupported processor register 's'
Definition: hexrays.hpp:4247
@ WARN_VARARG_REGS
0 cannot handle register arguments in vararg function, discarded them
Definition: hexrays.hpp:4212
@ WARN_MISSED_SWITCH
39 wrong markup of switch jump, skipped it
Definition: hexrays.hpp:4251
@ WARN_UNDEF_LVAR
42 variable 's' is possibly undefined
Definition: hexrays.hpp:4254
@ WARN_RET_LOCREF
47 returning address of temporary local variable 's'
Definition: hexrays.hpp:4259
@ WARN_BAD_RETVAR
25 wrong return variable
Definition: hexrays.hpp:4237
@ WARN_CR_NOFIELD
31 CONTAINING_RECORD: no field 's' in struct 's' at d
Definition: hexrays.hpp:4243
@ WARN_BAD_CALL_SP
38 bad sp value at call
Definition: hexrays.hpp:4250
@ WARN_WRITE_CONST
24 write access to const memory at a has been detected
Definition: hexrays.hpp:4236
@ WARN_WIDEN_CHAINS
11 failed to widen chains
Definition: hexrays.hpp:4223
@ WARN_ILL_FPU_STACK
18 inconsistent fpu stack
Definition: hexrays.hpp:4230
@ WARN_SELFREF_PROP
19 self-referencing variable has been detected
Definition: hexrays.hpp:4231
@ WARN_WRONG_VA_OFF
30 wrong offset of va_list variable
Definition: hexrays.hpp:4242
@ WARN_BAD_STKPNT
41 wrong sp change point
Definition: hexrays.hpp:4253
@ WARN_OPT_VALRNG
46 conditional instruction was optimized away because s
Definition: hexrays.hpp:4258
@ WARN_BAD_SHADOW
45 ignored the value written to the shadow area of the succeeding call
Definition: hexrays.hpp:4257
@ WARN_NO_SAVE_REST
14 could not find valid save-restore pair for s
Definition: hexrays.hpp:4226
@ WARN_BAD_INSN
49 bad instruction
Definition: hexrays.hpp:4261
@ WARN_ILL_ELLIPSIS
8 erroneously detected ellipsis type has been ignored
Definition: hexrays.hpp:4220
@ WARN_EXP_LINVAR
10 failed to expand a linear variable
Definition: hexrays.hpp:4222
@ WARN_VARARG_NOSTK
4 call vararg without local stack
Definition: hexrays.hpp:4216
@ WARN_MUST_RET_FP
17 function return type is incorrect (must be floating point)
Definition: hexrays.hpp:4229
@ WARN_JUMPOUT
43 control flows out of bounds
Definition: hexrays.hpp:4255
@ WARN_BAD_FIELD_TYPE
23 incorrect structure member type for s::s, ignored
Definition: hexrays.hpp:4235
@ WARN_WOULD_OVERLAP
20 variables would overlap: s
Definition: hexrays.hpp:4232
@ WARN_VARARG_TCAL
3 cannot handle tail call to vararg
Definition: hexrays.hpp:4215
@ WARN_ODD_ABI
50 encountered odd instruction for the current ABI
Definition: hexrays.hpp:4262
@ WARN_HUGE_STKOFF
27 exceedingly huge offset into the stack frame
Definition: hexrays.hpp:4239
@ WARN_ADDR_OUTARGS
6 cannot handle address arithmetics in outgoing argument area of stack frame – unused
Definition: hexrays.hpp:4218
@ WARN_MAX_ARGS
22 too many input arguments, some ignored
Definition: hexrays.hpp:4234
@ WARN_ARRAY_INARG
21 array has been used for an input argument
Definition: hexrays.hpp:4233
@ WARN_UNALIGNED_ARG
36 unaligned function argument 's'
Definition: hexrays.hpp:4248
@ WARN_CR_BADOFF
32 CONTAINING_RECORD: too small offset d for struct 's'
Definition: hexrays.hpp:4244
@ WARN_BAD_SP
40 positive sp value a has been found
Definition: hexrays.hpp:4252
@ WARN_OPT_VALRNG3
53 masking with 0XX was optimized away because s <= 0xX
Definition: hexrays.hpp:4267
@ WARN_BAD_VALRNG
44 values range analysis failed
Definition: hexrays.hpp:4256
@ WARN_DEP_UNK_CALLS
7 found interdependent unknown calls
Definition: hexrays.hpp:4219
@ WARN_BAD_STD_TYPE
37 corrupted or unexisting local type 's'
Definition: hexrays.hpp:4249
@ WARN_BAD_MAPDST
48 too short map destination 's' for variable 's'
Definition: hexrays.hpp:4260
treeloc_t const & user_cmts_first(user_cmts_iterator_t p)
Get reference to the current map key.
Definition: hexrays.hpp:8814
#define MLI_NAME
apply lvar name
Definition: hexrays.hpp:1595
void block_chains_erase(block_chains_t *set, block_chains_iterator_t p)
Erase current element from block_chains_t.
Definition: hexrays.hpp:9527
#define IPROP_ASSERT
assertion: usually mov #val, op.
Definition: hexrays.hpp:3467
user_labels_t * restore_user_labels(ea_t func_ea)
Restore user defined labels from the database.
Definition: hexrays.hpp:11863
block_chains_iterator_t block_chains_prev(block_chains_iterator_t p)
Move to the previous element.
Definition: hexrays.hpp:9519
user_cmts_t * restore_user_cmts(ea_t func_ea)
Restore user defined comments from the database.
Definition: hexrays.hpp:11875
const cmt_type_t CMT_ALL
All comments.
Definition: hexrays.hpp:7493
#define CVAR_UNAME
user-defined name
Definition: hexrays.hpp:1172
#define MBA_VALNUM
display value numbers
Definition: hexrays.hpp:4475
#define LVINF_NOPTR
variable type should not be a pointer
Definition: hexrays.hpp:1442
void user_unions_clear(user_unions_t *map)
Clear user_unions_t.
Definition: hexrays.hpp:9105
#define MBA_RETFP
function returns floating point value
Definition: hexrays.hpp:4447
const mopt_t mop_h
helper function
Definition: hexrays.hpp:2251
void lvar_mapping_erase(lvar_mapping_t *map, lvar_mapping_iterator_t p)
Erase current element from lvar_mapping_t.
Definition: hexrays.hpp:8662
#define OPROP_LOWADDR
a low address offset
Definition: hexrays.hpp:2440
bool is_binary(ctype_t op)
Is binary operator?
Definition: hexrays.hpp:5585
#define GCO_DEF
is destination operand?
Definition: hexrays.hpp:5441
#define CHF_TERM
terminating chain; the variable does not survive across the block
Definition: hexrays.hpp:3299
#define OPROP_UDT
a struct or union
Definition: hexrays.hpp:2435
ivlset_tpl< ivl_t, uval_t > uval_ivl_ivlset_t
Set of address intervals.
Definition: hexrays.hpp:1965
tinfo_t get_float_type(int width)
Get a type of a floating point value with the specified width.
Definition: hexrays.hpp:9785
lvar_mapping_t * lvar_mapping_new()
Create a new lvar_mapping_t instance.
Definition: hexrays.hpp:8690
bool is_kreg(mreg_t r)
Is a kernel register? Kernel registers are temporary registers that can be used freely.
Definition: hexrays.hpp:10316
udcall_map_t * udcall_map_new()
Create a new udcall_map_t instance.
Definition: hexrays.hpp:8799
void send_database(const hexrays_failure_t &err, bool silent)
Send the database to Hex-Rays.
Definition: hexrays.hpp:11371
#define CV_INSNS
visit only statements, prune all expressions do not use before the final ctree maturity because expre...
Definition: hexrays.hpp:5743
void save_user_defined_calls(ea_t func_ea, const udcall_map_t &udcalls)
Save user defined local function calls into the database.
Definition: hexrays.hpp:9983
ssize_t hexrays_cb_t(void *ud, hexrays_event_t event, va_list va)
Handler of decompiler events.
Definition: hexrays.hpp:7413
#define IPROP_DONT_PROP
may not propagate
Definition: hexrays.hpp:3488
user_labels_iterator_t user_labels_next(user_labels_iterator_t p)
Move to the next element.
Definition: hexrays.hpp:9191
qstring & user_labels_second(user_labels_iterator_t p)
Get reference to the current map value.
Definition: hexrays.hpp:9148
Function argument.
Definition: hexrays.hpp:6520
tinfo_t formal_type
formal parameter type (if known)
Definition: hexrays.hpp:6522
bool is_vararg
is a vararg (matches ...)
Definition: hexrays.hpp:6521
Function argument list.
Definition: hexrays.hpp:6538
tinfo_t functype
function object type
Definition: hexrays.hpp:6539
int flags
call flags
Definition: hexrays.hpp:6540
asm statement
Definition: hexrays.hpp:6401
Compound statement (curly braces)
Definition: hexrays.hpp:6514
Switch case. Usually cinsn_t is a block.
Definition: hexrays.hpp:6553
uint64vec_t values
List of case values.
Definition: hexrays.hpp:6554
Vector of switch cases.
Definition: hexrays.hpp:6565
Do-loop.
Definition: hexrays.hpp:6380
Statement with an expression.
Definition: hexrays.hpp:6323
cexpr_t expr
Expression of the statement.
Definition: hexrays.hpp:6324
Ctree item: expression.
Definition: hexrays.hpp:6056
type_sign_t get_type_sign(void) const
Get expression sign.
Definition: hexrays.hpp:6207
int ptrsize
memory access size (used for cot_ptr, cot_memptr)
Definition: hexrays.hpp:6083
uint32 exflags
Expression attributes
Definition: hexrays.hpp:6092
bool contains_comma(int times=1) const
Does the expression contain a comma operator?
Definition: hexrays.hpp:6187
bool contains_insn_or_label(void) const
Does the expression contain an embedded statement operator or a label?
Definition: hexrays.hpp:6191
bool like_boolean(void) const
Does the expression look like a boolean expression? In other words, its possible values are only 0 an...
bool is_value_used(const citem_t *parent) const
Does the PARENT need the expression value.
void replace_by(cexpr_t *r)
Replace the expression.
Definition: hexrays.hpp:11523
bool is_zero_const(void) const
Check if the expression is a zero.
Definition: hexrays.hpp:6259
bool is_call_arg_of(const citem_t *parent) const
Is call argument?
Definition: hexrays.hpp:6205
fnumber_t * fpc
used for cot_fnum
Definition: hexrays.hpp:6060
carglist_t * a
argument list (used for cot_call)
Definition: hexrays.hpp:6076
bool requires_lvalue(const cexpr_t *child) const
Check if the expression requires an lvalue.
Definition: hexrays.hpp:11585
bool cpadone(void) const
Pointer arithmetic correction done for this expression?
Definition: hexrays.hpp:6108
void print1(qstring *vout, const cfunc_t *func) const
Print expression into one line.
Definition: hexrays.hpp:11541
bool is_type_signed(void) const
Is expression signed?
Definition: hexrays.hpp:6211
const cexpr_t * find_op(ctype_t _op) const
Find the child with the specified operator.
Definition: hexrays.hpp:6288
bool is_nice_cond(void) const
Is nice condition?.
Definition: hexrays.hpp:6199
char * string
utf8 string constant, user representation (used for cot_str)
Definition: hexrays.hpp:6089
cinsn_t * insn
an embedded statement, they are prohibited at the final maturity stage (CMAT_FINAL)
Definition: hexrays.hpp:6086
bool is_const_value(uint64 _v) const
Check if the expression is a number with the specified value.
Definition: hexrays.hpp:6239
void calc_type(bool recursive)
Calculate the type of the expression.
Definition: hexrays.hpp:11547
cnumber_t * n
used for cot_num
Definition: hexrays.hpp:6059
bool equal_effect(const cexpr_t &r) const
Compare two expressions.
Definition: hexrays.hpp:11553
ea_t obj_ea
used for cot_obj
Definition: hexrays.hpp:6066
cexpr_t * y
the second operand of the expression
Definition: hexrays.hpp:6075
bool is_call_object_of(const citem_t *parent) const
Is call object?
Definition: hexrays.hpp:6202
const cexpr_t * theother(const cexpr_t *what) const
Get the other operand.
Definition: hexrays.hpp:6310
bool is_nice_expr(void) const
Is nice expression? Nice expressions do not contain comma operators, embedded statements,...
Definition: hexrays.hpp:6196
bit_bound_t get_high_nbit_bound(void) const
Get max number of bits that can really be used by the expression.
Definition: hexrays.hpp:11571
bool is_type_unsigned(void) const
Is expression unsigned?
Definition: hexrays.hpp:6209
bool is_child_of(const citem_t *parent) const
Verify if the specified item is our parent.
Definition: hexrays.hpp:11559
bool contains_insn(int times=1) const
Does the expression contain an embedded statement operator?
Definition: hexrays.hpp:6189
const cexpr_t * find_num_op(void) const
Find the operand with a numeric value.
Definition: hexrays.hpp:6302
char * helper
helper name (used for cot_helper)
Definition: hexrays.hpp:6088
var_ref_t v
used for cot_var
Definition: hexrays.hpp:6065
cexpr_t * get_ptr_or_array(void)
Find pointer or array child.
Definition: hexrays.hpp:6279
void put_number(cfunc_t *func, uint64 value, int nbytes, type_sign_t sign=no_sign)
Assign a number to the expression.
Definition: hexrays.hpp:11535
bool maybe_ptr(void) const
May the expression be a pointer?
Definition: hexrays.hpp:11597
cexpr_t * z
the third operand of the expression
Definition: hexrays.hpp:6082
int get_low_nbit_bound() const
Get min number of bits that are certainly required to represent the expression.
Definition: hexrays.hpp:11579
bool is_non_negative_const(void) const
Check if the expression is a non-negative number.
Definition: hexrays.hpp:6249
uint64 numval(void) const
Get numeric value of the expression.
Definition: hexrays.hpp:6233
bool contains_operator(ctype_t needed_op, int times=1) const
Check if the expression contains the specified operator.
Definition: hexrays.hpp:11565
const cexpr_t * find_ptr_or_array(bool remove_eqsize_casts) const
Find the pointer operand.
uint32 m
member offset (used for cot_memptr, cot_memref) for unions, the member number
Definition: hexrays.hpp:6077
bool is_negative_const(void) const
Check if the expression is a negative number.
Definition: hexrays.hpp:6244
bool has_side_effects(void) const
Check if the expression has side effects.
Definition: hexrays.hpp:11591
cexpr_t * x
the first operand of the expression
Definition: hexrays.hpp:6072
bool contains_comma_or_insn_or_label(int maxcommas=1) const
Does the expression contain a comma operator or an embedded statement operator or a label?
Definition: hexrays.hpp:6193
tinfo_t type
expression type. must be carefully maintained
Definition: hexrays.hpp:6091
bool get_1num_op(cexpr_t **o1, cexpr_t **o2)
Get pointers to operands.
Definition: hexrays.hpp:7185
bool is_non_zero_const(void) const
Check if the expression is a non-zero number.
Definition: hexrays.hpp:6254
int refwidth
how many bytes are accessed? (-1: none)
Definition: hexrays.hpp:6068
void cleanup(void)
Cleanup the expression.
Definition: hexrays.hpp:11529
bool get_const_value(uint64 *out) const
Get expression value.
Definition: hexrays.hpp:6265
bool is_aliasable(void) const
Check if the expression if aliasable.
For-loop.
Definition: hexrays.hpp:6366
cexpr_t init
Initialization expression.
Definition: hexrays.hpp:6367
cexpr_t step
Step expression.
Definition: hexrays.hpp:6368
Class to traverse the whole function.
Definition: hexrays.hpp:5858
cfunc_t * func
Pointer to current function.
Definition: hexrays.hpp:5859
bool calc_rvalue_type(tinfo_t *target, const cexpr_t *e)
Calculate rvalue type.
Definition: hexrays.hpp:11475
Decompiled function. Decompilation result is kept here.
Definition: hexrays.hpp:6868
void set_user_union_selection(ea_t ea, const intvec_t &path)
Set a union field selection.
Definition: hexrays.hpp:11997
user_cmts_t * user_cmts
user-defined comments.
Definition: hexrays.hpp:6877
user_unions_t * user_unions
user-defined union field selections.
Definition: hexrays.hpp:6880
const char * get_user_cmt(const treeloc_t &loc, cmt_retrieval_type_t rt) const
Retrieve a user defined comment.
Definition: hexrays.hpp:11955
strvec_t sv
decompilation output: function text. use get_pseudocode
Definition: hexrays.hpp:6894
void print_func(vc_printer_t &vp) const
Print function text.
Definition: hexrays.hpp:11917
void build_c_tree(void)
Generate the function body.
Definition: hexrays.hpp:11899
boundaries_t & get_boundaries(void)
Get pointer to map of instruction boundaries.
Definition: hexrays.hpp:12051
bool get_line_item(const char *line, int x, bool is_ctree_line, ctree_item_t *phead, ctree_item_t *pitem, ctree_item_t *ptail)
Get ctree item for the specified cursor position.
Definition: hexrays.hpp:12033
user_iflags_t * user_iflags
user-defined item flags ctree item iflags bits
Definition: hexrays.hpp:6879
bool has_orphan_cmts(void) const
Check if there are orphan comments.
Definition: hexrays.hpp:11979
void set_user_iflags(const citem_locator_t &loc, int32 iflags)
Set citem iflags.
Definition: hexrays.hpp:11973
void save_user_labels(void) const
Save user-defined labels into the database.
Definition: hexrays.hpp:12003
int hdrlines
number of lines in the declaration area
Definition: hexrays.hpp:6895
void save_user_cmts(void) const
Save user-defined comments into the database.
Definition: hexrays.hpp:12009
void print_dcl(qstring *vout) const
Print function prototype.
Definition: hexrays.hpp:11911
eamap_t * eamap
ea->insn map. use get_eamap
Definition: hexrays.hpp:6892
user_numforms_t * numforms
user-defined number formats.
Definition: hexrays.hpp:6878
ctree_maturity_t maturity
maturity level
Definition: hexrays.hpp:6873
void save_user_numforms(void) const
Save user-defined number formats into the database.
Definition: hexrays.hpp:12015
intvec_t & argidx
list of arguments (indexes into vars)
Definition: hexrays.hpp:6872
eamap_t & get_eamap(void)
Get pointer to ea->insn map.
Definition: hexrays.hpp:12045
boundaries_t * boundaries
map of instruction boundaries. use get_boundaries
Definition: hexrays.hpp:6893
int statebits
current cfunc_t state.
Definition: hexrays.hpp:6886
int del_orphan_cmts(void)
Delete all orphan comments.
Definition: hexrays.hpp:11985
const strvec_t & get_pseudocode(void)
Get pointer to decompilation output: the pseudocode.
Definition: hexrays.hpp:12057
citem_t * find_label(int label)
Find the label.
Definition: hexrays.hpp:11943
user_labels_t * user_labels
user-defined labels.
Definition: hexrays.hpp:6876
bool get_user_union_selection(ea_t ea, intvec_t *path)
Retrieve a user defined union field selection.
Definition: hexrays.hpp:11991
sval_t get_stkoff_delta(void)
Get stack offset delta.
Definition: hexrays.hpp:11935
void save_user_iflags(void) const
Save user-defined iflags into the database.
Definition: hexrays.hpp:12021
ctree_items_t treeitems
vector of ctree items
Definition: hexrays.hpp:6896
hexwarns_t & get_warnings(void)
Get information about decompilation warnings.
Definition: hexrays.hpp:12039
mba_t * mba
underlying microcode
Definition: hexrays.hpp:6870
void set_user_cmt(const treeloc_t &loc, const char *cmt)
Set a user defined comment.
Definition: hexrays.hpp:11961
lvars_t * get_lvars(void)
Get vector of local variables.
Definition: hexrays.hpp:11929
ea_t entry_ea
function entry address
Definition: hexrays.hpp:6869
cinsn_t body
function body, must be a block
Definition: hexrays.hpp:6871
void verify(allow_unused_labels_t aul, bool even_without_debugger) const
Verify the ctree.
Definition: hexrays.hpp:11905
void refresh_func_ctext(void)
Refresh ctext after a ctree modification.
Definition: hexrays.hpp:12063
bool get_func_type(tinfo_t *type) const
Get the function type.
Definition: hexrays.hpp:11923
void remove_unused_labels(void)
Remove unused labels.
Definition: hexrays.hpp:11949
int32 get_user_iflags(const citem_locator_t &loc) const
Retrieve citem iflags.
Definition: hexrays.hpp:11967
void save_user_unions(void) const
Save user-defined union field selections into the database.
Definition: hexrays.hpp:12027
Goto statement.
Definition: hexrays.hpp:6392
int label_num
Target label number.
Definition: hexrays.hpp:6393
Chain visitor class.
Definition: hexrays.hpp:3394
block_chains_t * parent
parent of the current chain
Definition: hexrays.hpp:3395
If statement.
Definition: hexrays.hpp:6339
cinsn_t * ielse
Else-branch of the if-statement. May be nullptr.
Definition: hexrays.hpp:6341
cinsn_t * ithen
Then-branch of the if-statement.
Definition: hexrays.hpp:6340
Ctree item: statement.
Definition: hexrays.hpp:6416
cdo_t * cdo
details of do-statement
Definition: hexrays.hpp:6424
bool contains_free_continue(void) const
Check if the statement has free continue statements.
Definition: hexrays.hpp:6505
cgoto_t * cgoto
details of goto-statement
Definition: hexrays.hpp:6427
cif_t * cif
details of if-statement
Definition: hexrays.hpp:6421
cexpr_t * cexpr
details of expression-statement
Definition: hexrays.hpp:6420
void print1(qstring *vout, const cfunc_t *func) const
Print the statement into one line.
Definition: hexrays.hpp:11699
cif_t & create_if(cexpr_t *cnd)
Create a new if-statement.
Definition: hexrays.hpp:11687
cfor_t * cfor
details of for-statement
Definition: hexrays.hpp:6422
cswitch_t * cswitch
details of switch-statement
Definition: hexrays.hpp:6425
void print(int indent, vc_printer_t &vp, use_curly_t use_curly=CALC_CURLY_BRACES) const
Print the statement into many lines.
Definition: hexrays.hpp:11693
bool collect_free_continues(cinsnptrvec_t *continues)
Collect free continue statements.
Definition: hexrays.hpp:11723
bool contains_free_break(void) const
Check if the statement has free break statements.
Definition: hexrays.hpp:6503
void replace_by(cinsn_t *r)
Replace the statement.
Definition: hexrays.hpp:11669
void cleanup(void)
Cleanup the statement.
Definition: hexrays.hpp:11675
bool collect_free_breaks(cinsnptrvec_t *breaks)
Collect free break statements.
Definition: hexrays.hpp:11717
bool contains_insn(ctype_t type, int times=1) const
Check if the statement contains a statement of the specified type.
Definition: hexrays.hpp:11711
cinsn_t & new_insn(ea_t insn_ea)
Create a new statement.
Definition: hexrays.hpp:11681
cwhile_t * cwhile
details of while-statement
Definition: hexrays.hpp:6423
creturn_t * creturn
details of return-statement
Definition: hexrays.hpp:6426
cblock_t * cblock
details of block-statement
Definition: hexrays.hpp:6419
casm_t * casm
details of asm-statement
Definition: hexrays.hpp:6428
bool is_ordinary_flow(void) const
Check if the statement passes execution to the next statement.
Definition: hexrays.hpp:11705
void zero(void)
Overwrite with zeroes without cleaning memory or deleting children.
Definition: hexrays.hpp:6450
Ctree item comment.
Definition: hexrays.hpp:5960
bool used
the comment has been retrieved?
Definition: hexrays.hpp:5961
Generic ctree item locator.
Definition: hexrays.hpp:5972
ea_t ea
citem address
Definition: hexrays.hpp:5973
ctype_t op
citem operation
Definition: hexrays.hpp:5974
Basic ctree item.
Definition: hexrays.hpp:6012
bool contains_expr(const cexpr_t *e) const
Does the item contain an expression?
Definition: hexrays.hpp:11487
ctype_t op
item type
Definition: hexrays.hpp:6014
bool is_expr(void) const
Is an expression?
Definition: hexrays.hpp:6031
void print1(qstring *vout, const cfunc_t *func) const
Print item into one line.
Definition: hexrays.hpp:7174
int label_num
label number.
Definition: hexrays.hpp:6015
bool contains_label(void) const
Does the item contain a label?
Definition: hexrays.hpp:11493
void swap(citem_t &r)
Swap two citem_t.
Definition: hexrays.hpp:6024
const citem_t * find_parent_of(const citem_t *sitem) const
Find parent of the specified item.
Definition: hexrays.hpp:11499
ea_t ea
address that corresponds to the item. may be BADADDR
Definition: hexrays.hpp:6013
Base class for loop statements.
Definition: hexrays.hpp:6353
An immediate number.
Definition: hexrays.hpp:5682
uint64 value(const tinfo_t &type) const
Get value.
Definition: hexrays.hpp:11431
void print(qstring *vout, const tinfo_t &type, const citem_t *parent=nullptr, bool *nice_stroff=nullptr) const
Get text representation.
Definition: hexrays.hpp:11425
void assign(uint64 v, int nbytes, type_sign_t sign)
Assign new value.
Definition: hexrays.hpp:11439
uint64 _value
its value
Definition: hexrays.hpp:5683
number_format_t nf
how to represent it
Definition: hexrays.hpp:5684
Return statement.
Definition: hexrays.hpp:6386
Switch statement.
Definition: hexrays.hpp:6572
cnumber_t mvnf
Maximal switch value and number format.
Definition: hexrays.hpp:6573
ccases_t cases
Switch cases: values and instructions.
Definition: hexrays.hpp:6574
Cursor position in the output text (pseudocode).
Definition: hexrays.hpp:7448
bool in_ctree(int hdrlines) const
Is the cursor in the variable/type declaration area?
Definition: hexrays.hpp:7454
int lnnum
Line number.
Definition: hexrays.hpp:7449
int y
y coordinate of the cursor within the window
Definition: hexrays.hpp:7451
int x
x coordinate of the cursor within the window
Definition: hexrays.hpp:7450
DECLARE_COMPARISONS(ctext_position_t)
Comparison operators.
Definition: hexrays.hpp:7456
Invisible COLOR_ADDR tags in the output text are used to refer to ctree items and variables.
Definition: hexrays.hpp:6581
Cursor item.
Definition: hexrays.hpp:6611
lvar_t * l
VDI_LVAR: Local variable.
Definition: hexrays.hpp:6618
cinsn_t * i
VDI_EXPR: Statement.
Definition: hexrays.hpp:6617
int get_label_num(int gln_flags) const
Get label number of the current item.
Definition: hexrays.hpp:11779
bool is_citem(void) const
Is the current item is a ctree item?
Definition: hexrays.hpp:6664
cursor_item_type_t citype
Item type.
Definition: hexrays.hpp:6612
cfunc_t * f
VDI_FUNC: Function.
Definition: hexrays.hpp:6619
treeloc_t loc
VDI_TAIL: Line tail.
Definition: hexrays.hpp:6620
cexpr_t * e
VDI_EXPR: Expression.
Definition: hexrays.hpp:6616
lvar_t * get_lvar(void) const
Get pointer to local variable.
Definition: hexrays.hpp:11765
ea_t get_ea(void) const
Get address of the current item.
Definition: hexrays.hpp:11771
member_t * get_memptr(struc_t **p_sptr=nullptr) const
Get pointer to structure member.
Definition: hexrays.hpp:11759
A helper ctree traversal class that maintains parent information.
Definition: hexrays.hpp:5838
bool recalc_parent_types(void)
Recalculate type of parent nodes.
Definition: hexrays.hpp:11469
cblock_t * get_block()
Get pointer to the parent block of the currently visited item.
Definition: hexrays.hpp:7215
A generic helper class that is used for ctree traversal.
Definition: hexrays.hpp:5733
virtual int visit_expr(cexpr_t *)
Visit an expression.
Definition: hexrays.hpp:5815
virtual int leave_expr(cexpr_t *)
Visit an expression after having visited its children.
Definition: hexrays.hpp:5831
virtual int visit_insn(cinsn_t *)
Visit a statement.
Definition: hexrays.hpp:5807
parents_t parents
Vector of parents of the current item.
Definition: hexrays.hpp:5769
ctree_visitor_t(int _flags)
Constructor.
Definition: hexrays.hpp:5774
cexpr_t * parent_expr(void)
Get parent of the current item as an expression.
Definition: hexrays.hpp:5794
void clr_prune(void)
Do not prune children. This is an internal function, no need to call it.
Definition: hexrays.hpp:5763
int apply_to(citem_t *item, citem_t *parent)
Traverse ctree.
Definition: hexrays.hpp:11457
void prune_now(void)
Prune children.
Definition: hexrays.hpp:5761
bool is_postorder(void) const
Should the leave...() functions be called?
Definition: hexrays.hpp:5756
bool only_insns(void) const
Should all expressions be automatically pruned?
Definition: hexrays.hpp:5758
bool must_restart(void) const
Should the traversal restart?
Definition: hexrays.hpp:5754
void set_restart(void)
Restart the travesal. Meaningful only in apply_to_exprs()
Definition: hexrays.hpp:5765
cinsn_t * parent_insn(void)
Get parent of the current item as a statement.
Definition: hexrays.hpp:5796
bool must_prune(void) const
Should the traversal skip the children of the current item?
Definition: hexrays.hpp:5752
bool maintain_parents(void) const
Should the parent information by maintained?
Definition: hexrays.hpp:5750
int cv_flags
Ctree visitor property bits
Definition: hexrays.hpp:5734
virtual int leave_insn(cinsn_t *)
Visit a statement after having visited its children.
Definition: hexrays.hpp:5823
void clr_restart(void)
Do not restart. This is an internal function, no need to call it.
Definition: hexrays.hpp:5767
int apply_to_exprs(citem_t *item, citem_t *parent)
Traverse only expressions.
Definition: hexrays.hpp:11463
While-loop.
Definition: hexrays.hpp:6374
Helper class to convert binary data structures into text and put into a file.
Definition: hexrays.hpp:876
FILE * fp
Output file pointer.
Definition: hexrays.hpp:877
Floating point constant.
Definition: hexrays.hpp:2381
fpvalue_t fnum
Internal representation of the number.
Definition: hexrays.hpp:2382
int nbytes
Original size of the constant in bytes.
Definition: hexrays.hpp:2383
Result of get_current_operand()
Definition: hexrays.hpp:5429
int regnum
if register, the register id
Definition: hexrays.hpp:5434
vivl_t cvt_to_ivl() const
Convert operand info to VIVL.
Definition: hexrays.hpp:5456
qstring name
register or stkvar name
Definition: hexrays.hpp:5430
bool append_to_list(mlist_t *list, const mba_t *mba) const
Append operand info to LIST.
Definition: hexrays.hpp:11377
sval_t stkoff
if stkvar, stack offset
Definition: hexrays.hpp:5433
int size
operand size
Definition: hexrays.hpp:5436
Exception object: decompiler failure information.
Definition: hexrays.hpp:5385
qstring str
string information
Definition: hexrays.hpp:5388
merror_t code
Microcode error codes
Definition: hexrays.hpp:5386
ea_t errea
associated address
Definition: hexrays.hpp:5387
Warning instances.
Definition: hexrays.hpp:4275
ea_t ea
Address where the warning occurred.
Definition: hexrays.hpp:4276
qstring text
Fully formatted text of the warning.
Definition: hexrays.hpp:4278
warnid_t id
Warning id.
Definition: hexrays.hpp:4277
Navigation history item.
Definition: hexrays.hpp:7472
ea_t end
BADADDR-decompile function; otherwise end of the range.
Definition: hexrays.hpp:7474
ea_t ea
The entry address of the decompiled function.
Definition: hexrays.hpp:7473
Local variable locator.
Definition: hexrays.hpp:1119
bool is_reg1(void) const
Is variable located on one register?
Definition: hexrays.hpp:1137
bool is_scattered(void) const
Is variable scattered?
Definition: hexrays.hpp:1145
mreg_t get_reg1(void) const
Get the register number of the variable.
Definition: hexrays.hpp:1147
bool is_reg2(void) const
Is variable located on two registers?
Definition: hexrays.hpp:1139
ea_t defea
Definition address.
Definition: hexrays.hpp:1121
mreg_t get_reg2(void) const
Get the number of the second register (works only for ALOC_REG2 lvars)
Definition: hexrays.hpp:1149
bool is_reg_var(void) const
Is variable located on register(s)?
Definition: hexrays.hpp:1141
vdloc_t location
Variable location.
Definition: hexrays.hpp:1120
sval_t get_stkoff(void) const
Get offset of the varialbe in the stack frame.
Definition: hexrays.hpp:1132
const scattered_aloc_t & get_scattered(void) const
Get information about scattered variable.
Definition: hexrays.hpp:1151
bool is_stk_var(void) const
Is variable located on the stack?
Definition: hexrays.hpp:1143
Reference to a local variable. Used by mop_l.
Definition: hexrays.hpp:2262
int idx
index into mba->vars
Definition: hexrays.hpp:2272
mba_t *const mba
Pointer to the parent mba_t object.
Definition: hexrays.hpp:2270
sval_t off
offset from the beginning of the variable
Definition: hexrays.hpp:2271
lvar_t & var(void) const
Retrieve the referenced variable.
Definition: hexrays.hpp:10371
Saved user settings for local variables: name, type, comment.
Definition: hexrays.hpp:1423
ssize_t size
Type size (if not initialized then -1)
Definition: hexrays.hpp:1428
qstring cmt
Comment.
Definition: hexrays.hpp:1427
tinfo_t type
Type.
Definition: hexrays.hpp:1426
int flags
saved user lvar info property bits
Definition: hexrays.hpp:1429
lvar_locator_t ll
Variable locator.
Definition: hexrays.hpp:1424
qstring name
Name.
Definition: hexrays.hpp:1425
All user-defined information about local variables.
Definition: hexrays.hpp:1488
int ulv_flags
Various flags. Possible values are from lvar_uservec_t property bits.
Definition: hexrays.hpp:1501
uval_t stkoff_delta
Delta to add to IDA stack offset to calculate Hex-Rays stack offsets.
Definition: hexrays.hpp:1498
lvar_mapping_t lmaps
Local variable mapping (used for merging variables)
Definition: hexrays.hpp:1494
lvar_saved_infos_t lvvec
User-specified names, types, comments for lvars.
Definition: hexrays.hpp:1491
lvar_saved_info_t * find_info(const lvar_locator_t &vloc)
find saved user settings for given var
Definition: hexrays.hpp:1532
void keep_info(const lvar_t &v)
Preserve user settings for given var.
Definition: hexrays.hpp:1543
Vector of local variables.
Definition: hexrays.hpp:1392
int find_stkvar(sval_t spoff, int width)
Find stack variable at the specified location.
Definition: hexrays.hpp:9929
lvar_t * find(const lvar_locator_t &ll)
Find variable at the specified location.
Definition: hexrays.hpp:9935
int find_lvar(const vdloc_t &location, int width, int defblk=-1) const
Find variable at the specified location.
Definition: hexrays.hpp:9941
int find_input_lvar(const vdloc_t &argloc, int _size)
Find input variable at the specified location.
Definition: hexrays.hpp:1397
Item iterator for mba_ranges_t.
Definition: hexrays.hpp:4358
Chunk iterator for mba_ranges_t.
Definition: hexrays.hpp:4406
Ranges to decompile. Either a function or an explicit vector of ranges.
Definition: hexrays.hpp:4325
rangevec_t ranges
snippet mode: ranges to decompile.
Definition: hexrays.hpp:4327
func_t * pfn
function to decompile. if not null, then function mode.
Definition: hexrays.hpp:4326
Generic microcode generator class.
Definition: hexrays.hpp:1699
virtual merror_t apply(codegen_t &cdg)=0
generate microcode for an instruction
virtual bool match(codegen_t &cdg)=0
check if the filter object is to be applied
Micro instruction visitor.
Definition: hexrays.hpp:2191
An integer constant.
Definition: hexrays.hpp:2355
Micro operand visitor.
Definition: hexrays.hpp:2204
bool prune
Should skip sub-operands of the current operand? visit_mop() may set 'prune=true' for that.
Definition: hexrays.hpp:2212
Number representation.
Definition: hexrays.hpp:778
qstring type_name
for stroffs: structure for offsetof() for enums: enum name
Definition: hexrays.hpp:796
number_format_t(int _opnum=0)
Contructor.
Definition: hexrays.hpp:799
char opnum
operand number: 0..UA_MAXOP
Definition: hexrays.hpp:780
int get_radix(void) const
Get number radix.
Definition: hexrays.hpp:803
char props
properties: combination of NF_ bits (Number format property bits)
Definition: hexrays.hpp:781
flags_t flags
ida flags, which describe number radix, enum, etc
Definition: hexrays.hpp:779
bool is_fixed(void) const
Is number representation fixed? Fixed representation cannot be modified by the decompiler.
Definition: hexrays.hpp:806
bool is_enum(void) const
Is a symbolic constant?
Definition: hexrays.hpp:814
char org_nbytes
original number size in bytes
Definition: hexrays.hpp:795
uchar serial
for enums: constant serial number
Definition: hexrays.hpp:794
bool is_dec(void) const
Is a decimal number?
Definition: hexrays.hpp:810
bool is_hex(void) const
Is a hexadecimal number?
Definition: hexrays.hpp:808
bool needs_to_be_inverted(void) const
Does the number need to be negated or bitwise negated? Returns true if the user requested a negation ...
Definition: hexrays.hpp:823
bool is_numop(void) const
Is a number?
Definition: hexrays.hpp:820
bool is_stroff(void) const
Is a structure field offset?
Definition: hexrays.hpp:818
bool is_oct(void) const
Is a octal number?
Definition: hexrays.hpp:812
bool is_char(void) const
Is a character constant?
Definition: hexrays.hpp:816
The context info used by visitors.
Definition: hexrays.hpp:2173
Operand locator.
Definition: hexrays.hpp:762
ea_t ea
address of the original processor instruction
Definition: hexrays.hpp:767
int opnum
operand number in the instruction
Definition: hexrays.hpp:768
User defined callback to optimize microcode blocks.
Definition: hexrays.hpp:2124
virtual int func(mblock_t *blk)=0
Optimize a block.
User defined callback to optimize individual microcode instructions.
Definition: hexrays.hpp:2093
virtual int func(mblock_t *blk, minsn_t *ins, int optflags)=0
Optimize an instruction.
Helper class to convert cfunc_t into a text string.
Definition: hexrays.hpp:892
bool with_tags
Generate output with color tags.
Definition: hexrays.hpp:893
qstring & s
Reference to the output string.
Definition: hexrays.hpp:894
qstring_printer_t(const cfunc_t *f, qstring &_s, bool tags)
Constructor.
Definition: hexrays.hpp:896
Chunk iterator of arbitrary rangevec items.
Definition: hexrays.hpp:4396
Item iterator of arbitrary rangevec items.
Definition: hexrays.hpp:4347
Scattered operand info. Used for mop_sc.
Definition: hexrays.hpp:2321
tinfo_t type
Scattered operands always have type info assigned to them because without it we won't be able to mani...
Definition: hexrays.hpp:2336
mba_t * mba
Pointer to the parent mba_t object.
Definition: hexrays.hpp:2327
qstring name
Usually scattered operands are created from a function prototype, which has the name information.
Definition: hexrays.hpp:2332
Scattered mop: visit each of the scattered locations as a separate mop.
Definition: hexrays.hpp:2219
Reference to a stack variable. Used for mop_S.
Definition: hexrays.hpp:2294
sval_t off
Offset to the stack variable from the bottom of the stack frame.
Definition: hexrays.hpp:2303
mba_t *const mba
Pointer to the parent mba_t object.
Definition: hexrays.hpp:2298
member_t * get_stkvar(uval_t *p_off=nullptr) const
Retrieve the referenced stack variable.
Definition: hexrays.hpp:10383
Ctree location. Used to denote comment locations.
Definition: hexrays.hpp:5930
User-defined function calls.
Definition: hexrays.hpp:1640
Callback to apply the selection.
Definition: hexrays.hpp:7822
virtual bool apply(size_t opnum, const intvec_t &path, const tinfo_t &top_tif, const char *spath)=0
Select UDT for the operands using "Select offsets" widget.
Definition: hexrays.hpp:7807
uval_t offset
operand offset, will be used when calculating the UDT path
Definition: hexrays.hpp:7809
qstring text
any text for the column "Operand" of widget
Definition: hexrays.hpp:7808
Helper class to modify saved local variable settings.
Definition: hexrays.hpp:1568
virtual bool modify_lvars(lvar_uservec_t *lvinf)=0
Modify lvar settings.
Reference to a local variable.
Definition: hexrays.hpp:5715
int idx
index into lvars_t
Definition: hexrays.hpp:5717
mba_t * mba
pointer to the underlying micro array
Definition: hexrays.hpp:5716
Helper class to convert cfunc_t into text.
Definition: hexrays.hpp:864
char lastchar
internal: last printed character
Definition: hexrays.hpp:866
virtual bool oneliner(void) const newapi
Are we generating one-line text representation?
Definition: hexrays.hpp:871
const cfunc_t * func
cfunc_t to generate text for
Definition: hexrays.hpp:865
vc_printer_t(const cfunc_t *f)
Constructor.
Definition: hexrays.hpp:868
Exception object: decompiler exception.
Definition: hexrays.hpp:5398
Exception object: decompiler internal error.
Definition: hexrays.hpp:5413
Base helper class to convert binary data structures into text.
Definition: hexrays.hpp:847
int hdrlines
number of header lines (prototype+typedef+lvars) valid at the end of print process
Definition: hexrays.hpp:849
Information about the pseudocode window.
Definition: hexrays.hpp:7498
bool rename_label(int label)
Rename a label.
Definition: hexrays.hpp:12300
TWidget * ct
pseudocode view
Definition: hexrays.hpp:7523
bool set_strmem_type(struc_t *sptr, member_t *mptr)
Set structure field type.
Definition: hexrays.hpp:12276
merror_t last_code
result of the last user action. See Microcode error codes
Definition: hexrays.hpp:7528
bool collapse_lvars(bool hide)
Collapse/uncollapse local variable declarations.
Definition: hexrays.hpp:12378
bool set_lvar_cmt(lvar_t *v, const char *cmt)
Set local variable comment.
Definition: hexrays.hpp:12252
bool set_global_type(ea_t ea)
Set global item type.
Definition: hexrays.hpp:12288
bool invert_bits(void)
Bitwise negate a number.
Definition: hexrays.hpp:12366
bool refresh_cpos(input_device_t idv)
Refresh the current position.
Definition: hexrays.hpp:12198
bool set_lvar_type(lvar_t *v, const tinfo_t &type)
Set local variable type.
Definition: hexrays.hpp:12234
void refresh_ctext(bool activate=true)
Refresh pseudocode window.
Definition: hexrays.hpp:12168
ctree_item_t head
First ctree item on the current line (for block comments)
Definition: hexrays.hpp:7532
bool map_lvar(lvar_t *from, lvar_t *to)
Map a local variable to another.
Definition: hexrays.hpp:12270
bool rename_strmem(struc_t *sptr, member_t *mptr)
Rename structure field.
Definition: hexrays.hpp:12282
bool ui_map_lvar(lvar_t *v)
Map a local variable to another.
Definition: hexrays.hpp:12258
bool visible(void) const
Is the pseudocode window visible? if not, it might be invisible or destroyed.
Definition: hexrays.hpp:7509
void refresh_view(bool redo_mba)
Refresh pseudocode window.
Definition: hexrays.hpp:12162
bool set_noptr_lvar(lvar_t *v)
Inform that local variable should have a non-pointer type This function permanently sets a correspond...
Definition: hexrays.hpp:12240
bool ui_set_lvar_type(lvar_t *v)
Set local variable type.
Definition: hexrays.hpp:12228
bool in_ctree(void) const
Is the current item a statement?
Definition: hexrays.hpp:7565
bool ui_rename_lvar(lvar_t *v)
Rename local variable.
Definition: hexrays.hpp:12210
ctree_item_t item
Current ctree item.
Definition: hexrays.hpp:7533
bool set_num_enum(void)
Convert number to symbolic constant.
Definition: hexrays.hpp:12348
ctext_position_t cpos
Current ctext position.
Definition: hexrays.hpp:7531
int get_current_label(void)
Get current label.
Definition: hexrays.hpp:12186
bool locked(void) const
Does the pseudocode window contain valid code? We lock windows before modifying them,...
Definition: hexrays.hpp:7517
bool edit_cmt(const treeloc_t &loc)
Edit an indented comment.
Definition: hexrays.hpp:12324
int view_idx
pseudocode window index (0..)
Definition: hexrays.hpp:7522
bool set_num_radix(int base)
Change number base.
Definition: hexrays.hpp:12342
bool del_orphan_cmts(void)
Delete all orphan comments.
Definition: hexrays.hpp:12336
bool ctree_to_disasm(void)
Jump to disassembly.
Definition: hexrays.hpp:12312
bool invert_sign(void)
Negate a number.
Definition: hexrays.hpp:12360
void switch_to(cfuncptr_t f, bool activate)
Display the specified pseudocode.
Definition: hexrays.hpp:12174
bool set_num_stroff(void)
Convert number to structure field offset.
Definition: hexrays.hpp:12354
void clear(void)
Clear the pseudocode window.
Definition: hexrays.hpp:12192
bool collapse_item(bool hide)
Collapse/uncollapse item.
Definition: hexrays.hpp:12372
mba_t * mba
pointer to underlying microcode
Definition: hexrays.hpp:7526
bool jump_enter(input_device_t idv, int omflags)
Process the Enter key.
Definition: hexrays.hpp:12306
bool split_item(bool split)
Split/unsplit item.
Definition: hexrays.hpp:12384
cfuncptr_t cfunc
pointer to function object
Definition: hexrays.hpp:7527
bool valid(void) const
Does the pseudocode window contain valid code? It can become invalid if the function type gets change...
Definition: hexrays.hpp:7512
bool rename_global(ea_t ea)
Rename global item.
Definition: hexrays.hpp:12294
bool rename_lvar(lvar_t *v, const char *name, bool is_user_name)
Rename local variable.
Definition: hexrays.hpp:12216
int flags
Properties of pseudocode window
Definition: hexrays.hpp:7499
cmt_type_t calc_cmt_type(size_t lnnum, cmt_type_t cmttype) const
Check if the specified line can have a comment.
Definition: hexrays.hpp:12318
bool get_current_item(input_device_t idv)
Get current item.
Definition: hexrays.hpp:12204
bool ui_set_call_type(const cexpr_t *e)
Set type of a function call This function displays a dialog box and allows the user to change the typ...
Definition: hexrays.hpp:12222
bool ui_edit_lvar_cmt(lvar_t *v)
Set local variable comment.
Definition: hexrays.hpp:12246
ctree_item_t tail
Tail ctree item on the current line (for indented comments)
Definition: hexrays.hpp:7534
bool edit_func_cmt(void)
Edit a function comment.
Definition: hexrays.hpp:12330
cnumber_t * get_number(void)
Get current number.
Definition: hexrays.hpp:12180
bool ui_unmap_lvar(lvar_t *v)
Unmap a local variable.
Definition: hexrays.hpp:12264
Value interval (register or stack range)
Definition: hexrays.hpp:3221
uval_t intersect(const vivl_t &r)
Intersect value intervals the same type.
Definition: hexrays.hpp:10691
bool overlap(const vivl_t &r) const
Do two value intervals overlap?
Definition: hexrays.hpp:3246
bool contains(const voff_t &voff2) const
Does our value interval contain the specified value offset?
Definition: hexrays.hpp:3259
int size
Interval size in bytes.
Definition: hexrays.hpp:3222
bool includes(const vivl_t &r) const
Does our value interval include another?
Definition: hexrays.hpp:3252
bool extend_to_cover(const vivl_t &r)
Extend a value interval using another value interval of the same type.
Definition: hexrays.hpp:10685
Value offset (microregister number or stack offset)
Definition: hexrays.hpp:3184
sval_t off
register number or stack offset
Definition: hexrays.hpp:3185
mopt_t type
mop_r - register, mop_S - stack, mop_z - undefined
Definition: hexrays.hpp:3186