Latest available version: IDA and decompilers v8.4.240320sp1 see all releases
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-2024 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 * Facilities for debugging decompiler plugins:
217 * Many decompiler objects have a member function named dstr().
218 * These functions create a text representation of the object and return
219 * a pointer to it. They are very convenient to use in a debugger instead of
220 * inspecting class fields manually. The mba_t object does not have the
221 * dstr() function because its text representation very long. Instead, we
222 * provide the mba_t::dump_mba() and mba_t::dump() functions.
223 *
224 * To ensure that your plugin manipulates the microcode in a correct way,
225 * please call mba_t::verify() before returning control to the decompiler.
226 *
227 */
228
229#ifdef __NT__
230#pragma warning(push)
231#pragma warning(disable:4062) // enumerator 'x' in switch of enum 'y' is not handled
232#pragma warning(disable:4265) // virtual functions without virtual destructor
233#endif
234
235#define hexapi ///< Public functions are marked with this keyword
236
237// Lint suppressions:
238//lint -sem(mop_t::_make_cases, custodial(1))
239//lint -sem(mop_t::_make_pair, custodial(1))
240//lint -sem(mop_t::_make_callinfo, custodial(1))
241//lint -sem(mop_t::_make_insn, custodial(1))
242//lint -sem(mop_t::make_insn, custodial(1))
243
244// Microcode level forward definitions:
245class mop_t; // microinstruction operand
246class mop_pair_t; // pair of operands. example, :(edx.4,eax.4).8
247class mop_addr_t; // address of an operand. example: &global_var
248class mcallinfo_t; // function call info. example: <cdecl:"int x" #10.4>.8
249class mcases_t; // jump table cases. example: {0 => 12, 1 => 13}
250class minsn_t; // microinstruction
251class mblock_t; // basic block
252class mba_t; // array of blocks, represents microcode for a function
253class codegen_t; // helper class to generate the initial microcode
254class mbl_graph_t; // control graph of microcode
255struct vdui_t; // widget representing the pseudocode window
256struct hexrays_failure_t; // decompilation failure object, is thrown by exceptions
257struct mba_stats_t; // statistics about decompilation of a function
258struct mlist_t; // list of memory and register locations
259struct voff_t; // value offset (microregister number or stack offset)
260typedef std::set<voff_t> voff_set_t;
261struct vivl_t; // value interval (register or stack range)
262typedef int mreg_t; ///< Micro register
263
264// Ctree level forward definitions:
265struct cfunc_t; // result of decompilation, the highest level object
266struct citem_t; // base class for cexpr_t and cinsn_t
267struct cexpr_t; // C expression
268struct cinsn_t; // C statement
269struct cblock_t; // C statement block (sequence of statements)
270struct cswitch_t; // C switch statement
271struct carg_t; // call argument
272struct carglist_t; // vector of call arguments
273
274typedef std::set<ea_t> easet_t;
275typedef std::set<minsn_t *> minsn_ptr_set_t;
276typedef std::set<qstring> strings_t;
277typedef qvector<minsn_t*> minsnptrs_t;
278typedef qvector<mop_t*> mopptrs_t;
279typedef qvector<mop_t> mopvec_t;
280typedef qvector<uint64> uint64vec_t;
281typedef qvector<mreg_t> mregvec_t;
282typedef qrefcnt_t<cfunc_t> cfuncptr_t;
283
284// Function frames must be smaller than this value, otherwise
285// the decompiler will bail out with MERR_HUGESTACK
286#define MAX_SUPPORTED_STACK_SIZE 0x100000 // 1MB
287
288//-------------------------------------------------------------------------
289// Original version of macro DEFINE_MEMORY_ALLOCATION_FUNCS
290// (uses decompiler-specific memory allocation functions)
291#define HEXRAYS_PLACEMENT_DELETE void operator delete(void *, void *) {}
292#define HEXRAYS_MEMORY_ALLOCATION_FUNCS() \
293 void *operator new (size_t _s) { return hexrays_alloc(_s); } \
294 void *operator new[](size_t _s) { return hexrays_alloc(_s); } \
295 void *operator new(size_t /*size*/, void *_v) { return _v; } \
296 void operator delete (void *_blk) { hexrays_free(_blk); } \
297 void operator delete[](void *_blk) { hexrays_free(_blk); } \
298 HEXRAYS_PLACEMENT_DELETE
299
300void *hexapi hexrays_alloc(size_t size);
301void hexapi hexrays_free(void *ptr);
302
303typedef uint64 uvlr_t;
304typedef int64 svlr_t;
305enum { MAX_VLR_SIZE = sizeof(uvlr_t) };
306const uvlr_t MAX_VALUE = uvlr_t(-1);
307const svlr_t MAX_SVALUE = svlr_t(uvlr_t(-1) >> 1);
308const svlr_t MIN_SVALUE = ~MAX_SVALUE;
309
310enum cmpop_t
311{ // the order of comparisons is the same as in microcode opcodes
312 CMP_NZ,
313 CMP_Z,
314 CMP_AE,
315 CMP_B,
316 CMP_A,
317 CMP_BE,
318 CMP_GT,
319 CMP_GE,
320 CMP_LT,
321 CMP_LE,
322};
323
324//-------------------------------------------------------------------------
325// value-range class to keep possible operand value(s).
327{
328protected:
329 int flags;
330#define VLR_TYPE 0x0F // valrng_t type
331#define VLR_NONE 0x00 // no values
332#define VLR_ALL 0x01 // all values
333#define VLR_IVLS 0x02 // union of disjoint intervals
334#define VLR_RANGE 0x03 // strided range
335#define VLR_SRANGE 0x04 // strided range with signed bound
336#define VLR_BITS 0x05 // known bits
337#define VLR_SECT 0x06 // intersection of sub-ranges
338 // each sub-range should be simple or union
339#define VLR_UNION 0x07 // union of sub-ranges
340 // each sub-range should be simple or
341 // intersection
342#define VLR_UNK 0x08 // unknown value (like 'null' in SQL)
343 int size; // operand size: 1..8 bytes
344 // all values must fall within the size
345 union
346 {
347 struct // VLR_RANGE/VLR_SRANGE
348 { // values that are between VALUE and LIMIT
349 // and conform to: value+stride*N
350 uvlr_t value; // initial value
351 uvlr_t limit; // final value
352 // we adjust LIMIT to be on the STRIDE lattice
353 svlr_t stride; // stride between values
354 };
355 struct // VLR_BITS
356 {
357 uvlr_t zeroes; // bits known to be clear
358 uvlr_t ones; // bits known to be set
359 };
360 char reserved[sizeof(qvector<int>)];
361 // VLR_IVLS/VLR_SECT/VLR_UNION
362 };
363 void hexapi clear();
364 void hexapi copy(const valrng_t &r);
365 valrng_t &hexapi assign(const valrng_t &r);
366
367public:
368 explicit valrng_t(int size_ = MAX_VLR_SIZE)
369 : flags(VLR_NONE), size(size_), value(0), limit(0), stride(0) {}
370 valrng_t(const valrng_t &r) { copy(r); }
371 ~valrng_t() { clear(); }
372 valrng_t &operator=(const valrng_t &r) { return assign(r); }
373 void swap(valrng_t &r) { qswap(*this, r); }
374 DECLARE_COMPARISONS(valrng_t);
375 DEFINE_MEMORY_ALLOCATION_FUNCS()
376
377 void set_none() { clear(); }
378 void set_all() { clear(); flags = VLR_ALL; }
379 void set_unk() { clear(); flags = VLR_UNK; }
380 void hexapi set_eq(uvlr_t v);
381 void hexapi set_cmp(cmpop_t cmp, uvlr_t _value);
382
383 // reduce size
384 // it takes the low part of size NEW_SIZE
385 // it returns "true" if size is changed successfully.
386 // e.g.: valrng_t vr(2); vr.set_eq(0x1234);
387 // vr.reduce_size(1);
388 // uvlr_t v; vr.cvt_to_single_value(&v);
389 // assert(v == 0x34);
390 bool hexapi reduce_size(int new_size);
391
392 // Perform intersection or union or inversion.
393 // \return did we change something in THIS?
394 bool hexapi intersect_with(const valrng_t &r);
395 bool hexapi unite_with(const valrng_t &r);
396 void hexapi inverse(); // works for VLR_IVLS only
397
398 bool empty() const { return flags == VLR_NONE; }
399 bool all_values() const { return flags == VLR_ALL; }
400 bool is_unknown() const { return flags == VLR_UNK; }
401 bool hexapi has(uvlr_t v) const;
402
403 void hexapi print(qstring *vout) const;
404 const char *hexapi dstr() const;
405
406 bool hexapi cvt_to_single_value(uvlr_t *v) const;
407 bool hexapi cvt_to_cmp(cmpop_t *cmp, uvlr_t *val, bool strict) const;
408
409 int get_size() const { return size; }
410 static uvlr_t max_value(int size_)
411 {
412 return size_ == MAX_VLR_SIZE
413 ? MAX_VALUE
414 : (uvlr_t(1) << (size_ * 8)) - 1;
415 }
416 static uvlr_t min_svalue(int size_)
417 {
418 return size_ == MAX_VLR_SIZE
419 ? MIN_SVALUE
420 : (uvlr_t(1) << (size_ * 8 - 1));
421 }
422 static uvlr_t max_svalue(int size_)
423 {
424 return size_ == MAX_VLR_SIZE
425 ? MAX_SVALUE
426 : (uvlr_t(1) << (size_ * 8 - 1)) - 1;
427 }
428 uvlr_t max_value() const { return max_value(size); }
429 uvlr_t min_svalue() const { return min_svalue(size); }
430 uvlr_t max_svalue() const { return max_svalue(size); }
431};
432DECLARE_TYPE_AS_MOVABLE(valrng_t);
433
434//-------------------------------------------------------------------------
435// Are we looking for 'must access' or 'may access' information?
436// 'must access' means that the code will always access the specified location(s)
437// 'may access' means that the code may in some cases access the specified location(s)
438// Example: ldx cs.2, r0.4, r1.4
439// MUST_ACCESS: r0.4 and r1.4, usually displayed as r0.8 because r0 and r1 are adjacent
440// MAY_ACCESS: r0.4 and r1.4, and all aliasable memory, because
441// ldx may access any part of the aliasable memory
442typedef int maymust_t;
443const maymust_t
444 // One of the following two bits should be specified:
445 MUST_ACCESS = 0x00, // access information we can count on
446 MAY_ACCESS = 0x01, // access information we should take into account
447 // Optionally combined with the following bits:
448 MAYMUST_ACCESS_MASK = 0x01,
449
450 ONE_ACCESS_TYPE = 0x20, // for find_first_use():
451 // use only the specified maymust access type
452 // (by default it inverts the access type for def-lists)
453 INCLUDE_SPOILED_REGS = 0x40, // for build_def_list() with MUST_ACCESS:
454 // include spoiled registers in the list
455 EXCLUDE_PASS_REGS = 0x80, // for build_def_list() with MAY_ACCESS:
456 // exclude pass_regs from the list
457 FULL_XDSU = 0x100, // for build_def_list():
458 // if xds/xdu source and targets are the same
459 // treat it as if xdsu redefines the entire destination
460 WITH_ASSERTS = 0x200, // for find_first_use():
461 // do not ignore assertions
462 EXCLUDE_VOLATILE = 0x400, // for build_def_list():
463 // exclude volatile memory from the list
464 INCLUDE_UNUSED_SRC = 0x800, // for build_use_list():
465 // do not exclude unused source bytes for m_and/m_or insns
466 INCLUDE_DEAD_RETREGS = 0x1000, // for build_def_list():
467 // include dead returned registers in the list
468 INCLUDE_RESTRICTED = 0x2000,// for MAY_ACCESS: include restricted memory
469 CALL_SPOILS_ONLY_ARGS = 0x4000;// for build_def_list() & MAY_ACCESS:
470 // do not include global memory into the
471 // spoiled list of a call
472
473inline THREAD_SAFE bool is_may_access(maymust_t maymust)
474{
475 return (maymust & MAYMUST_ACCESS_MASK) != MUST_ACCESS;
476}
477
478//-------------------------------------------------------------------------
479/// \defgroup MERR_ Microcode error codes
480///@{
482{
483 MERR_OK = 0, ///< ok
484 MERR_BLOCK = 1, ///< no error, switch to new block
485 MERR_INTERR = -1, ///< internal error
486 MERR_INSN = -2, ///< cannot convert to microcode
487 MERR_MEM = -3, ///< not enough memory
488 MERR_BADBLK = -4, ///< bad block found
489 MERR_BADSP = -5, ///< positive sp value has been found
490 MERR_PROLOG = -6, ///< prolog analysis failed
491 MERR_SWITCH = -7, ///< wrong switch idiom
492 MERR_EXCEPTION = -8, ///< exception analysis failed
493 MERR_HUGESTACK = -9, ///< stack frame is too big
494 MERR_LVARS = -10, ///< local variable allocation failed
495 MERR_BITNESS = -11, ///< 16-bit functions cannot be decompiled
496 MERR_BADCALL = -12, ///< could not determine call arguments
497 MERR_BADFRAME = -13, ///< function frame is wrong
498 MERR_UNKTYPE = -14, ///< undefined type %s (currently unused error code)
499 MERR_BADIDB = -15, ///< inconsistent database information
500 MERR_SIZEOF = -16, ///< wrong basic type sizes in compiler settings
501 MERR_REDO = -17, ///< redecompilation has been requested
502 MERR_CANCELED = -18, ///< decompilation has been cancelled
503 MERR_RECDEPTH = -19, ///< max recursion depth reached during lvar allocation
504 MERR_OVERLAP = -20, ///< variables would overlap: %s
505 MERR_PARTINIT = -21, ///< partially initialized variable %s
506 MERR_COMPLEX = -22, ///< too complex function
507 MERR_LICENSE = -23, ///< no license available
508 MERR_ONLY32 = -24, ///< only 32-bit functions can be decompiled for the current database
509 MERR_ONLY64 = -25, ///< only 64-bit functions can be decompiled for the current database
510 MERR_BUSY = -26, ///< already decompiling a function
511 MERR_FARPTR = -27, ///< far memory model is supported only for pc
512 MERR_EXTERN = -28, ///< special segments cannot be decompiled
513 MERR_FUNCSIZE = -29, ///< too big function
514 MERR_BADRANGES = -30, ///< bad input ranges
515 MERR_BADARCH = -31, ///< current architecture is not supported
516 MERR_DSLOT = -32, ///< bad instruction in the delay slot
517 MERR_STOP = -33, ///< no error, stop the analysis
518 MERR_CLOUD = -34, ///< cloud: %s
519 MERR_MAX_ERR = 34,
520 MERR_LOOP = -35, ///< internal code: redo last loop (never reported)
521};
522///@}
523
524/// Get textual description of an error code
525/// \param out the output buffer for the error description
526/// \param code \ref MERR_
527/// \param mba the microcode array
528/// \return the error address
529
530ea_t hexapi get_merror_desc(qstring *out, merror_t code, mba_t *mba);
531
532//-------------------------------------------------------------------------
533// List of microinstruction opcodes.
534// The order of setX and jX insns is important, it is used in the code.
535
536// Instructions marked with *F may have the FPINSN bit set and operate on fp values
537// Instructions marked with +F must have the FPINSN bit set. They always operate on fp values
538// Other instructions do not operate on fp values.
539
540enum mcode_t
541{
542 m_nop = 0x00, // nop // no operation
543 m_stx = 0x01, // stx l, {r=sel, d=off} // store register to memory *F
544 m_ldx = 0x02, // ldx {l=sel,r=off}, d // load register from memory *F
545 m_ldc = 0x03, // ldc l=const, d // load constant
546 m_mov = 0x04, // mov l, d // move *F
547 m_neg = 0x05, // neg l, d // negate
548 m_lnot = 0x06, // lnot l, d // logical not
549 m_bnot = 0x07, // bnot l, d // bitwise not
550 m_xds = 0x08, // xds l, d // extend (signed)
551 m_xdu = 0x09, // xdu l, d // extend (unsigned)
552 m_low = 0x0A, // low l, d // take low part
553 m_high = 0x0B, // high l, d // take high part
554 m_add = 0x0C, // add l, r, d // l + r -> dst
555 m_sub = 0x0D, // sub l, r, d // l - r -> dst
556 m_mul = 0x0E, // mul l, r, d // l * r -> dst
557 m_udiv = 0x0F, // udiv l, r, d // l / r -> dst
558 m_sdiv = 0x10, // sdiv l, r, d // l / r -> dst
559 m_umod = 0x11, // umod l, r, d // l % r -> dst
560 m_smod = 0x12, // smod l, r, d // l % r -> dst
561 m_or = 0x13, // or l, r, d // bitwise or
562 m_and = 0x14, // and l, r, d // bitwise and
563 m_xor = 0x15, // xor l, r, d // bitwise xor
564 m_shl = 0x16, // shl l, r, d // shift logical left
565 m_shr = 0x17, // shr l, r, d // shift logical right
566 m_sar = 0x18, // sar l, r, d // shift arithmetic right
567 m_cfadd = 0x19, // cfadd l, r, d=carry // calculate carry bit of (l+r)
568 m_ofadd = 0x1A, // ofadd l, r, d=overf // calculate overflow bit of (l+r)
569 m_cfshl = 0x1B, // cfshl l, r, d=carry // calculate carry bit of (l<<r)
570 m_cfshr = 0x1C, // cfshr l, r, d=carry // calculate carry bit of (l>>r)
571 m_sets = 0x1D, // sets l, d=byte SF=1 Sign
572 m_seto = 0x1E, // seto l, r, d=byte OF=1 Overflow of (l-r)
573 m_setp = 0x1F, // setp l, r, d=byte PF=1 Unordered/Parity *F
574 m_setnz = 0x20, // setnz l, r, d=byte ZF=0 Not Equal *F
575 m_setz = 0x21, // setz l, r, d=byte ZF=1 Equal *F
576 m_setae = 0x22, // setae l, r, d=byte CF=0 Unsigned Above or Equal *F
577 m_setb = 0x23, // setb l, r, d=byte CF=1 Unsigned Below *F
578 m_seta = 0x24, // seta l, r, d=byte CF=0 & ZF=0 Unsigned Above *F
579 m_setbe = 0x25, // setbe l, r, d=byte CF=1 | ZF=1 Unsigned Below or Equal *F
580 m_setg = 0x26, // setg l, r, d=byte SF=OF & ZF=0 Signed Greater
581 m_setge = 0x27, // setge l, r, d=byte SF=OF Signed Greater or Equal
582 m_setl = 0x28, // setl l, r, d=byte SF!=OF Signed Less
583 m_setle = 0x29, // setle l, r, d=byte SF!=OF | ZF=1 Signed Less or Equal
584 m_jcnd = 0x2A, // jcnd l, d // d is mop_v or mop_b
585 m_jnz = 0x2B, // jnz l, r, d // ZF=0 Not Equal *F
586 m_jz = 0x2C, // jz l, r, d // ZF=1 Equal *F
587 m_jae = 0x2D, // jae l, r, d // CF=0 Unsigned Above or Equal *F
588 m_jb = 0x2E, // jb l, r, d // CF=1 Unsigned Below *F
589 m_ja = 0x2F, // ja l, r, d // CF=0 & ZF=0 Unsigned Above *F
590 m_jbe = 0x30, // jbe l, r, d // CF=1 | ZF=1 Unsigned Below or Equal *F
591 m_jg = 0x31, // jg l, r, d // SF=OF & ZF=0 Signed Greater
592 m_jge = 0x32, // jge l, r, d // SF=OF Signed Greater or Equal
593 m_jl = 0x33, // jl l, r, d // SF!=OF Signed Less
594 m_jle = 0x34, // jle l, r, d // SF!=OF | ZF=1 Signed Less or Equal
595 m_jtbl = 0x35, // jtbl l, r=mcases // Table jump
596 m_ijmp = 0x36, // ijmp {r=sel, d=off} // indirect unconditional jump
597 m_goto = 0x37, // goto l // l is mop_v or mop_b
598 m_call = 0x38, // call l d // l is mop_v or mop_b or mop_h
599 m_icall = 0x39, // icall {l=sel, r=off} d // indirect call
600 m_ret = 0x3A, // ret
601 m_push = 0x3B, // push l
602 m_pop = 0x3C, // pop d
603 m_und = 0x3D, // und d // undefine
604 m_ext = 0x3E, // ext in1, in2, out1 // external insn, not microcode *F
605 m_f2i = 0x3F, // f2i l, d int(l) => d; convert fp -> integer +F
606 m_f2u = 0x40, // f2u l, d uint(l)=> d; convert fp -> uinteger +F
607 m_i2f = 0x41, // i2f l, d fp(l) => d; convert integer -> fp +F
608 m_u2f = 0x42, // i2f l, d fp(l) => d; convert uinteger -> fp +F
609 m_f2f = 0x43, // f2f l, d l => d; change fp precision +F
610 m_fneg = 0x44, // fneg l, d -l => d; change sign +F
611 m_fadd = 0x45, // fadd l, r, d l + r => d; add +F
612 m_fsub = 0x46, // fsub l, r, d l - r => d; subtract +F
613 m_fmul = 0x47, // fmul l, r, d l * r => d; multiply +F
614 m_fdiv = 0x48, // fdiv l, r, d l / r => d; divide +F
615#define m_max 0x49 // first unused opcode
616};
617
618/// Must an instruction with the given opcode be the last one in a block?
619/// Such opcodes are called closing opcodes.
620/// \param mcode instruction opcode
621/// \param including_calls should m_call/m_icall be considered as the closing opcodes?
622/// If this function returns true, the opcode cannot appear in the middle
623/// of a block. Calls are a special case: unknown calls (\ref is_unknown_call)
624/// are considered as closing opcodes.
625
626THREAD_SAFE bool hexapi must_mcode_close_block(mcode_t mcode, bool including_calls);
627
628
629/// May opcode be propagated?
630/// Such opcodes can be used in sub-instructions (nested instructions)
631/// There is a handful of non-propagatable opcodes, like jumps, ret, nop, etc
632/// All other regular opcodes are propagatable and may appear in a nested
633/// instruction.
634
635THREAD_SAFE bool hexapi is_mcode_propagatable(mcode_t mcode);
636
637
638// Is add or sub instruction?
639inline THREAD_SAFE bool is_mcode_addsub(mcode_t mcode) { return mcode == m_add || mcode == m_sub; }
640// Is xds or xdu instruction? We use 'xdsu' as a shortcut for 'xds or xdu'
641inline THREAD_SAFE bool is_mcode_xdsu(mcode_t mcode) { return mcode == m_xds || mcode == m_xdu; }
642// Is a 'set' instruction? (an instruction that sets a condition code)
643inline THREAD_SAFE bool is_mcode_set(mcode_t mcode) { return mcode >= m_sets && mcode <= m_setle; }
644// Is a 1-operand 'set' instruction? Only 'sets' is in this group
645inline THREAD_SAFE bool is_mcode_set1(mcode_t mcode) { return mcode == m_sets; }
646// Is a 1-operand conditional jump instruction? Only 'jcnd' is in this group
647inline THREAD_SAFE bool is_mcode_j1(mcode_t mcode) { return mcode == m_jcnd; }
648// Is a conditional jump?
649inline THREAD_SAFE bool is_mcode_jcond(mcode_t mcode) { return mcode >= m_jcnd && mcode <= m_jle; }
650// Is a 'set' instruction that can be converted into a conditional jump?
651inline THREAD_SAFE bool is_mcode_convertible_to_jmp(mcode_t mcode) { return mcode >= m_setnz && mcode <= m_setle; }
652// Is a conditional jump instruction that can be converted into a 'set'?
653inline THREAD_SAFE bool is_mcode_convertible_to_set(mcode_t mcode) { return mcode >= m_jnz && mcode <= m_jle; }
654// Is a call instruction? (direct or indirect)
655inline THREAD_SAFE bool is_mcode_call(mcode_t mcode) { return mcode == m_call || mcode == m_icall; }
656// Must be an FPU instruction?
657inline THREAD_SAFE bool is_mcode_fpu(mcode_t mcode) { return mcode >= m_f2i; }
658// Is a commutative instruction?
659inline THREAD_SAFE bool is_mcode_commutative(mcode_t mcode)
660{
661 return mcode == m_add
662 || mcode == m_mul
663 || mcode == m_or
664 || mcode == m_and
665 || mcode == m_xor
666 || mcode == m_setz
667 || mcode == m_setnz
668 || mcode == m_cfadd
669 || mcode == m_ofadd;
670}
671// Is a shift instruction?
672inline THREAD_SAFE bool is_mcode_shift(mcode_t mcode)
673{
674 return mcode == m_shl
675 || mcode == m_shr
676 || mcode == m_sar;
677}
678// Is a kind of div or mod instruction?
679inline THREAD_SAFE bool is_mcode_divmod(mcode_t op)
680{
681 return op == m_udiv || op == m_sdiv || op == m_umod || op == m_smod;
682}
683// Is an instruction with the selector/offset pair?
684inline THREAD_SAFE bool has_mcode_seloff(mcode_t op)
685{
686 return op == m_ldx || op == m_stx || op == m_icall || op == m_ijmp;
687}
688
689// Convert setX opcode into corresponding jX opcode
690// This function relies on the order of setX and jX opcodes!
691inline THREAD_SAFE mcode_t set2jcnd(mcode_t code)
692{
693 return mcode_t(code - m_setnz + m_jnz);
694}
695
696// Convert setX opcode into corresponding jX opcode
697// This function relies on the order of setX and jX opcodes!
698inline THREAD_SAFE mcode_t jcnd2set(mcode_t code)
699{
700 return mcode_t(code + m_setnz - m_jnz);
701}
702
703// Negate a conditional opcode.
704// Conditional jumps can be negated, example: jle -> jg
705// 'Set' instruction can be negated, example: seta -> setbe
706// If the opcode cannot be negated, return m_nop
707THREAD_SAFE mcode_t hexapi negate_mcode_relation(mcode_t code);
708
709
710// Swap a conditional opcode.
711// Only conditional jumps and set instructions can be swapped.
712// The returned opcode the one required for swapped operands.
713// Example "x > y" is the same as "y < x", therefore swap(m_jg) is m_jl.
714// If the opcode cannot be swapped, return m_nop
715
716THREAD_SAFE mcode_t hexapi swap_mcode_relation(mcode_t code);
717
718// Return the opcode that performs signed operation.
719// Examples: jae -> jge; udiv -> sdiv
720// If the opcode cannot be transformed into signed form, simply return it.
721
722THREAD_SAFE mcode_t hexapi get_signed_mcode(mcode_t code);
723
724
725// Return the opcode that performs unsigned operation.
726// Examples: jl -> jb; xds -> xdu
727// If the opcode cannot be transformed into unsigned form, simply return it.
728
729THREAD_SAFE mcode_t hexapi get_unsigned_mcode(mcode_t code);
730
731// Does the opcode perform a signed operation?
732inline THREAD_SAFE bool is_signed_mcode(mcode_t code) { return get_unsigned_mcode(code) != code; }
733// Does the opcode perform a unsigned operation?
734inline THREAD_SAFE bool is_unsigned_mcode(mcode_t code) { return get_signed_mcode(code) != code; }
735
736
737// Does the 'd' operand gets modified by the instruction?
738// Example: "add l,r,d" modifies d, while instructions
739// like jcnd, ijmp, stx does not modify it.
740// Note: this function returns 'true' for m_ext but it may be wrong.
741// Use minsn_t::modifies_d() if you have minsn_t.
742
743THREAD_SAFE bool hexapi mcode_modifies_d(mcode_t mcode);
744
745
746// Processor condition codes are mapped to the first microregisters
747// The order is important, see mop_t::is_cc()
748const mreg_t mr_none = mreg_t(-1);
749const mreg_t mr_cf = mreg_t(0); // carry bit
750const mreg_t mr_zf = mreg_t(1); // zero bit
751const mreg_t mr_sf = mreg_t(2); // sign bit
752const mreg_t mr_of = mreg_t(3); // overflow bit
753const mreg_t mr_pf = mreg_t(4); // parity bit
754const int cc_count = mr_pf - mr_cf + 1; // number of condition code registers
755const mreg_t mr_cc = mreg_t(5); // synthetic condition code, used internally
756const mreg_t mr_first = mreg_t(8); // the first processor specific register
757
758//-------------------------------------------------------------------------
759/// Operand locator.
760/// It is used to denote a particular operand in the ctree, for example,
761/// when the user right clicks on a constant and requests to represent it, say,
762/// as a hexadecimal number.
764{
765private:
766 // forbid the default constructor, force the user to initialize objects of this class.
768public:
769 ea_t ea; ///< address of the original processor instruction
770 int opnum; ///< operand number in the instruction
771 operand_locator_t(ea_t _ea, int _opnum) : ea(_ea), opnum(_opnum) {}
772 DECLARE_COMPARISONS(operand_locator_t);
773 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
774};
775
776//-------------------------------------------------------------------------
777/// Number representation.
778/// This structure holds information about a number format.
780{
781 flags_t flags32 = 0; ///< low 32bit of flags (for compatibility)
782 char opnum; ///< operand number: 0..UA_MAXOP
783 char props = 0; ///< properties: combination of NF_ bits (\ref NF_)
784/// \defgroup NF_ Number format property bits
785/// Used in number_format_t::props
786///@{
787#define NF_FIXED 0x01 ///< number format has been defined by the user
788#define NF_NEGDONE 0x02 ///< temporary internal bit: negation has been performed
789#define NF_BINVDONE 0x04 ///< temporary internal bit: inverting bits is done
790#define NF_NEGATE 0x08 ///< The user asked to negate the constant
791#define NF_BITNOT 0x10 ///< The user asked to invert bits of the constant
792#define NF_VALID 0x20 ///< internal bit: stroff or enum is valid
793 ///< for enums: this bit is set immediately
794 ///< for stroffs: this bit is set at the end of decompilation
795///@}
796 uchar serial = 0; ///< for enums: constant serial number
797 char org_nbytes = 0; ///< original number size in bytes
798 qstring type_name; ///< for stroffs: structure for offsetof()\n
799 ///< for enums: enum name
800 flags64_t flags = 0; ///< ida flags, which describe number radix, enum, etc
801 /// Contructor
802 number_format_t(int _opnum=0) : opnum(char(_opnum)) {}
803 /// Get number radix
804 /// \return 2,8,10, or 16
805 int get_radix() const { return ::get_radix(flags, opnum); }
806 /// Is number representation fixed?
807 /// Fixed representation cannot be modified by the decompiler
808 bool is_fixed() const { return props != 0; }
809 /// Is a hexadecimal number?
810 bool is_hex() const { return ::is_numop(flags, opnum) && get_radix() == 16; }
811 /// Is a decimal number?
812 bool is_dec() const { return ::is_numop(flags, opnum) && get_radix() == 10; }
813 /// Is a octal number?
814 bool is_oct() const { return ::is_numop(flags, opnum) && get_radix() == 8; }
815 /// Is a symbolic constant?
816 bool is_enum() const { return ::is_enum(flags, opnum); }
817 /// Is a character constant?
818 bool is_char() const { return ::is_char(flags, opnum); }
819 /// Is a structure field offset?
820 bool is_stroff() const { return ::is_stroff(flags, opnum); }
821 /// Is a number?
822 bool is_numop() const { return !is_enum() && !is_char() && !is_stroff(); }
823 /// Does the number need to be negated or bitwise negated?
824 /// Returns true if the user requested a negation but it is not done yet
826 {
827 return (props & (NF_NEGATE|NF_BITNOT)) != 0 // the user requested it
828 && (props & (NF_NEGDONE|NF_BINVDONE)) == 0; // not done yet
829 }
830 // symbolic constants and struct offsets cannot easily change
831 // their sign or size without a cast. only simple numbers can do that.
832 // for example, by modifying the expression type we can convert:
833 // 10u -> 10
834 // but replacing the type of a symbol constant would lead to an inconsistency.
835 bool has_unmutable_type() const
836 {
837 return (props & NF_VALID) != 0 && (is_stroff() || is_enum());
838 }
839 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
840};
841
842// Number formats are attached to (ea,opnum) pairs
843typedef std::map<operand_locator_t, number_format_t> user_numforms_t;
844
845//-------------------------------------------------------------------------
846/// Base helper class to convert binary data structures into text.
847/// Other classes are derived from this class.
849{
850 qstring tmpbuf;
851 int hdrlines = 0; ///< number of header lines (prototype+typedef+lvars)
852 ///< valid at the end of print process
853 /// Print.
854 /// This function is called to generate a portion of the output text.
855 /// The output text may contain color codes.
856 /// \return the number of printed characters
857 /// \param indent number of spaces to generate as prefix
858 /// \param format printf-style format specifier
859 /// \return length of printed string
860 AS_PRINTF(3, 4) virtual int hexapi print(int indent, const char *format, ...);
861 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
862};
863
864/// Helper class to convert cfunc_t into text.
866{
867 const cfunc_t *func; ///< cfunc_t to generate text for
868 char lastchar = 0; ///< internal: last printed character
869 /// Constructor
870 vc_printer_t(const cfunc_t *f) : func(f) {}
871 /// Are we generating one-line text representation?
872 /// \return \c true if the output will occupy one line without line breaks
873 virtual bool idaapi oneliner() const newapi { return false; }
874};
875
876/// Helper class to convert binary data structures into text and put into a file.
878{
879 FILE *fp; ///< Output file pointer
880 /// Print.
881 /// This function is called to generate a portion of the output text.
882 /// The output text may contain color codes.
883 /// \return the number of printed characters
884 /// \param indent number of spaces to generate as prefix
885 /// \param format printf-style format specifier
886 /// \return length of printed string
887 AS_PRINTF(3, 4) int hexapi print(int indent, const char *format, ...) override;
888 /// Constructor
889 file_printer_t(FILE *_fp) : fp(_fp) {}
890};
891
892/// Helper class to convert cfunc_t into a text string
894{
895 bool with_tags; ///< Generate output with color tags
896 qstring &s; ///< Reference to the output string
897 /// Constructor
898 qstring_printer_t(const cfunc_t *f, qstring &_s, bool tags)
899 : vc_printer_t(f), with_tags(tags), s(_s) {}
900 /// Print.
901 /// This function is called to generate a portion of the output text.
902 /// The output text may contain color codes.
903 /// \return the number of printed characters
904 /// \param indent number of spaces to generate as prefix
905 /// \param format printf-style format specifier
906 /// \return length of the printed string
907 AS_PRINTF(3, 4) int hexapi print(int indent, const char *format, ...) override;
908};
909
910//-------------------------------------------------------------------------
911/// \defgroup type Type string related declarations
912/// Type related functions and class.
913///@{
914
915/// Print the specified type info.
916/// This function can be used from a debugger by typing "tif->dstr()"
917
918const char *hexapi dstr(const tinfo_t *tif);
919
920
921/// Verify a type string.
922/// \return true if type string is correct
923
924bool hexapi is_type_correct(const type_t *ptr);
925
926
927/// Is a small structure or union?
928/// \return true if the type is a small UDT (user defined type).
929/// Small UDTs fit into a register (or pair or registers) as a rule.
930
931bool hexapi is_small_udt(const tinfo_t &tif);
932
933
934/// Is definitely a non-boolean type?
935/// \return true if the type is a non-boolean type (non bool and well defined)
936
937bool hexapi is_nonbool_type(const tinfo_t &type);
938
939
940/// Is a boolean type?
941/// \return true if the type is a boolean type
942
943bool hexapi is_bool_type(const tinfo_t &type);
944
945
946/// Is a pointer or array type?
947inline THREAD_SAFE bool is_ptr_or_array(type_t t)
948{
949 return is_type_ptr(t) || is_type_array(t);
950}
951
952/// Is a pointer, array, or function type?
953inline THREAD_SAFE bool is_paf(type_t t)
954{
955 return is_ptr_or_array(t) || is_type_func(t);
956}
957
958/// Is struct/union/enum definition (not declaration)?
959inline THREAD_SAFE bool is_inplace_def(const tinfo_t &type)
960{
961 return type.is_decl_complex() && !type.is_typeref();
962}
963
964/// Calculate number of partial subtypes.
965/// \return number of partial subtypes. The bigger is this number, the uglier is the type.
966
967int hexapi partial_type_num(const tinfo_t &type);
968
969
970/// Get a type of a floating point value with the specified width
971/// \returns type info object
972/// \param width width of the desired type
973
974tinfo_t hexapi get_float_type(int width);
975
976
977/// Create a type info by width and sign.
978/// Returns a simple type (examples: int, short) with the given width and sign.
979/// \param srcwidth size of the type in bytes
980/// \param sign sign of the type
981
982tinfo_t hexapi get_int_type_by_width_and_sign(int srcwidth, type_sign_t sign);
983
984
985/// Create a partial type info by width.
986/// Returns a partially defined type (examples: _DWORD, _BYTE) with the given width.
987/// \param size size of the type in bytes
988
989tinfo_t hexapi get_unk_type(int size);
990
991
992/// Generate a dummy pointer type
993/// \param ptrsize size of pointed object
994/// \param isfp is floating point object?
995
996tinfo_t hexapi dummy_ptrtype(int ptrsize, bool isfp);
997
998
999/// Get type of a structure field.
1000/// This function performs validity checks of the field type. Wrong types are rejected.
1001/// \param mptr structure field
1002/// \param type pointer to the variable where the type is returned. This parameter can be nullptr.
1003/// \return false if failed
1004
1005bool hexapi get_member_type(const member_t *mptr, tinfo_t *type);
1006
1007
1008/// Create a pointer type.
1009/// This function performs the following conversion: "type" -> "type*"
1010/// \param type object type.
1011/// \return "type*". for example, if 'char' is passed as the argument,
1012// the function will return 'char *'
1013
1014tinfo_t hexapi make_pointer(const tinfo_t &type);
1015
1016
1017/// Create a reference to a named type.
1018/// \param name type name
1019/// \return type which refers to the specified name. For example, if name is "DWORD",
1020/// the type info which refers to "DWORD" is created.
1021
1022tinfo_t hexapi create_typedef(const char *name);
1023
1024
1025/// Create a reference to an ordinal type.
1026/// \param n ordinal number of the type
1027/// \return type which refers to the specified ordinal. For example, if n is 1,
1028/// the type info which refers to ordinal type 1 is created.
1029
1030inline tinfo_t create_typedef(int n)
1031{
1032 tinfo_t tif;
1033 tif.create_typedef(nullptr, n);
1034 return tif;
1035}
1036
1037/// Type source (where the type information comes from)
1039{
1040 GUESSED_NONE, // not guessed, specified by the user
1041 GUESSED_WEAK, // not guessed, comes from idb
1042 GUESSED_FUNC, // guessed as a function
1043 GUESSED_DATA, // guessed as a data item
1044 TS_NOELL = 0x8000000, // can be used in set_type() to avoid merging into ellipsis
1045 TS_SHRINK = 0x4000000, // can be used in set_type() to prefer smaller arguments
1046 TS_DONTREF = 0x2000000, // do not mark type as referenced (referenced_types)
1047 TS_MASK = 0xE000000, // all high bits
1048};
1049
1050
1051/// Get a global type.
1052/// Global types are types of addressable objects and struct/union/enum types
1053/// \param id address or id of the object
1054/// \param tif buffer for the answer
1055/// \param guess what kind of types to consider
1056/// \return success
1057
1058bool hexapi get_type(uval_t id, tinfo_t *tif, type_source_t guess);
1059
1060
1061/// Set a global type.
1062/// \param id address or id of the object
1063/// \param tif new type info
1064/// \param source where the type comes from
1065/// \param force true means to set the type as is, false means to merge the
1066/// new type with the possibly existing old type info.
1067/// \return success
1068
1069bool hexapi set_type(uval_t id, const tinfo_t &tif, type_source_t source, bool force=false);
1070
1071///@}
1072
1073//-------------------------------------------------------------------------
1074// We use our own class to store argument and variable locations.
1075// It is called vdloc_t that stands for 'vd location'.
1076// 'vd' is the internal name of the decompiler, it stands for 'visual decompiler'.
1077// The main differences between vdloc and argloc_t:
1078// ALOC_REG1: the offset is always 0, so it is not used. the register number
1079// uses the whole ~VLOC_MASK field.
1080// ALOCK_STKOFF: stack offsets are always positive because they are based on
1081// the lowest value of sp in the function.
1082class vdloc_t : public argloc_t
1083{
1084 int regoff(); // inaccessible & undefined: regoff() should not be used
1085public:
1086 // Get the register number.
1087 // This function works only for ALOC_REG1 and ALOC_REG2 location types.
1088 // It uses all available bits for register number for ALOC_REG1
1089 int reg1() const { return atype() == ALOC_REG2 ? argloc_t::reg1() : get_reginfo(); }
1090
1091 // Set vdloc to point to the specified register without cleaning it up.
1092 // This is a dangerous function, use set_reg1() instead unless you understand
1093 // what it means to cleanup an argloc.
1094 void _set_reg1(int r1) { argloc_t::_set_reg1(r1, r1>>16); }
1095
1096 // Set vdloc to point to the specified register.
1097 void set_reg1(int r1) { cleanup_argloc(this); _set_reg1(r1); }
1098
1099 // Use member functions of argloc_t for other location types.
1100
1101 // Return textual representation.
1102 // Note: this and all other dstr() functions can be used from a debugger.
1103 // It is much easier than to inspect the memory contents byte by byte.
1104 const char *hexapi dstr(int width=0) const;
1105 DECLARE_COMPARISONS(vdloc_t);
1106 bool hexapi is_aliasable(const mba_t *mb, int size) const;
1107};
1108
1109/// Print vdloc.
1110/// Since vdloc does not always carry the size info, we pass it as NBYTES..
1111void hexapi print_vdloc(qstring *vout, const vdloc_t &loc, int nbytes);
1112
1113//-------------------------------------------------------------------------
1114/// Do two arglocs overlap?
1115bool hexapi arglocs_overlap(const vdloc_t &loc1, size_t w1, const vdloc_t &loc2, size_t w2);
1116
1117/// Local variable locator.
1118/// Local variables are located using definition ea and location.
1119/// Each variable must have a unique locator, this is how we tell them apart.
1121{
1122 vdloc_t location; ///< Variable location.
1123 ea_t defea = BADADDR; ///< Definition address. Usually, this is the address
1124 ///< of the instruction that initializes the variable.
1125 ///< In some cases it can be a fictional address.
1126
1127 lvar_locator_t() {}
1128 lvar_locator_t(const vdloc_t &loc, ea_t ea) : location(loc), defea(ea) {}
1129 /// Get offset of the varialbe in the stack frame.
1130 /// \return a non-negative value for stack variables. The value is
1131 /// an offset from the bottom of the stack frame in terms of
1132 /// vd-offsets.
1133 /// negative values mean error (not a stack variable)
1134 sval_t get_stkoff() const
1135 {
1136 return location.is_stkoff() ? location.stkoff() : -1;
1137 }
1138 /// Is variable located on one register?
1139 bool is_reg1() const { return location.is_reg1(); }
1140 /// Is variable located on two registers?
1141 bool is_reg2() const { return location.is_reg2(); }
1142 /// Is variable located on register(s)?
1143 bool is_reg_var() const { return location.is_reg(); }
1144 /// Is variable located on the stack?
1145 bool is_stk_var() const { return location.is_stkoff(); }
1146 /// Is variable scattered?
1147 bool is_scattered() const { return location.is_scattered(); }
1148 /// Get the register number of the variable
1149 mreg_t get_reg1() const { return location.reg1(); }
1150 /// Get the number of the second register (works only for ALOC_REG2 lvars)
1151 mreg_t get_reg2() const { return location.reg2(); }
1152 /// Get information about scattered variable
1153 const scattered_aloc_t &get_scattered() const { return location.scattered(); }
1154 scattered_aloc_t &get_scattered() { return location.scattered(); }
1155 DECLARE_COMPARISONS(lvar_locator_t);
1156 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
1157 // Debugging: get textual representation of a lvar locator.
1158 const char *hexapi dstr() const;
1159};
1160
1161/// Definition of a local variable (register or stack) #var #lvar
1163{
1164 friend class mba_t;
1165 int flags; ///< \ref CVAR_
1166/// \defgroup CVAR_ Local variable property bits
1167/// Used in lvar_t::flags
1168///@{
1169#define CVAR_USED 0x00000001 ///< is used in the code?
1170#define CVAR_TYPE 0x00000002 ///< the type is defined?
1171#define CVAR_NAME 0x00000004 ///< has nice name?
1172#define CVAR_MREG 0x00000008 ///< corresponding mregs were replaced?
1173#define CVAR_NOWD 0x00000010 ///< width is unknown
1174#define CVAR_UNAME 0x00000020 ///< user-defined name
1175#define CVAR_UTYPE 0x00000040 ///< user-defined type
1176#define CVAR_RESULT 0x00000080 ///< function result variable
1177#define CVAR_ARG 0x00000100 ///< function argument
1178#define CVAR_FAKE 0x00000200 ///< fake variable (return var or va_list)
1179#define CVAR_OVER 0x00000400 ///< overlapping variable
1180#define CVAR_FLOAT 0x00000800 ///< used in a fpu insn
1181#define CVAR_SPOILED 0x00001000 ///< internal flag, do not use: spoiled var
1182#define CVAR_MAPDST 0x00002000 ///< other variables are mapped to this var
1183#define CVAR_PARTIAL 0x00004000 ///< variable type is partialy defined
1184#define CVAR_THISARG 0x00008000 ///< 'this' argument of c++ member functions
1185#define CVAR_SPLIT 0x00010000 ///< variable was created by an explicit request
1186 ///< otherwise we could reuse an existing var
1187#define CVAR_REGNAME 0x00020000 ///< has a register name (like _RAX): if lvar
1188 ///< is used by an m_ext instruction
1189#define CVAR_NOPTR 0x00040000 ///< variable cannot be a pointer (user choice)
1190#define CVAR_DUMMY 0x00080000 ///< dummy argument (added to fill a hole in
1191 ///< the argument list)
1192#define CVAR_NOTARG 0x00100000 ///< variable cannot be an input argument
1193#define CVAR_AUTOMAP 0x00200000 ///< variable was automatically mapped
1194#define CVAR_BYREF 0x00400000 ///< the address of the variable was taken
1195#define CVAR_INASM 0x00800000 ///< variable is used in instructions translated
1196 ///< into __asm {...}
1197#define CVAR_UNUSED 0x01000000 ///< user-defined __unused attribute
1198 ///< meaningful only if: is_arg_var() && !mba->final_type
1199#define CVAR_SHARED 0x02000000 ///< variable is mapped to several chains
1200///@}
1201
1202public:
1203 qstring name; ///< variable name.
1204 ///< use mba_t::set_nice_lvar_name() and
1205 ///< mba_t::set_user_lvar_name() to modify it
1206 qstring cmt; ///< variable comment string
1207 tinfo_t tif; ///< variable type
1208 int width = 0; ///< variable size in bytes
1209 int defblk = -1; ///< first block defining the variable.
1210 ///< 0 for args, -1 if unknown
1211 uint64 divisor = 0; ///< max known divisor of the variable
1212
1213 lvar_t() : flags(CVAR_USED) {}
1214 lvar_t(const qstring &n, const vdloc_t &l, ea_t e, const tinfo_t &t, int w, int db)
1215 : lvar_locator_t(l, e), flags(CVAR_USED), name(n), tif(t), width(w), defblk(db)
1216 {
1217 }
1218 // Debugging: get textual representation of a local variable.
1219 const char *hexapi dstr() const;
1220
1221 /// Is the variable used in the code?
1222 bool used() const { return (flags & CVAR_USED) != 0; }
1223 /// Has the variable a type?
1224 bool typed() const { return (flags & CVAR_TYPE) != 0; }
1225 /// Have corresponding microregs been replaced by references to this variable?
1226 bool mreg_done() const { return (flags & CVAR_MREG) != 0; }
1227 /// Does the variable have a nice name?
1228 bool has_nice_name() const { return (flags & CVAR_NAME) != 0; }
1229 /// Do we know the width of the variable?
1230 bool is_unknown_width() const { return (flags & CVAR_NOWD) != 0; }
1231 /// Has any user-defined information?
1232 bool has_user_info() const
1233 {
1234 return (flags & (CVAR_UNAME|CVAR_UTYPE|CVAR_NOPTR|CVAR_UNUSED)) != 0
1235 || !cmt.empty();
1236 }
1237 /// Has user-defined name?
1238 bool has_user_name() const { return (flags & CVAR_UNAME) != 0; }
1239 /// Has user-defined type?
1240 bool has_user_type() const { return (flags & CVAR_UTYPE) != 0; }
1241 /// Is the function result?
1242 bool is_result_var() const { return (flags & CVAR_RESULT) != 0; }
1243 /// Is the function argument?
1244 bool is_arg_var() const { return (flags & CVAR_ARG) != 0; }
1245 /// Is the promoted function argument?
1246 bool hexapi is_promoted_arg() const;
1247 /// Is fake return variable?
1248 bool is_fake_var() const { return (flags & CVAR_FAKE) != 0; }
1249 /// Is overlapped variable?
1250 bool is_overlapped_var() const { return (flags & CVAR_OVER) != 0; }
1251 /// Used by a fpu insn?
1252 bool is_floating_var() const { return (flags & CVAR_FLOAT) != 0; }
1253 /// Is spoiled var? (meaningful only during lvar allocation)
1254 bool is_spoiled_var() const { return (flags & CVAR_SPOILED) != 0; }
1255 /// Variable type should be handled as a partial one
1256 bool is_partialy_typed() const { return (flags & CVAR_PARTIAL) != 0; }
1257 /// Variable type should not be a pointer
1258 bool is_noptr_var() const { return (flags & CVAR_NOPTR) != 0; }
1259 /// Other variable(s) map to this var?
1260 bool is_mapdst_var() const { return (flags & CVAR_MAPDST) != 0; }
1261 /// Is 'this' argument of a C++ member function?
1262 bool is_thisarg() const { return (flags & CVAR_THISARG) != 0; }
1263 /// Is a split variable?
1264 bool is_split_var() const { return (flags & CVAR_SPLIT) != 0; }
1265 /// Has a register name? (like _RAX)
1266 bool has_regname() const { return (flags & CVAR_REGNAME) != 0; }
1267 /// Is variable used in an instruction translated into __asm?
1268 bool in_asm() const { return (flags & CVAR_INASM) != 0; }
1269 /// Is a dummy argument (added to fill a hole in the argument list)
1270 bool is_dummy_arg() const { return (flags & CVAR_DUMMY) != 0; }
1271 /// Is a local variable? (local variable cannot be an input argument)
1272 bool is_notarg() const { return (flags & CVAR_NOTARG) != 0; }
1273 /// Was the variable automatically mapped to another variable?
1274 bool is_automapped() const { return (flags & CVAR_AUTOMAP) != 0; }
1275 /// Was the address of the variable taken?
1276 bool is_used_byref() const { return (flags & CVAR_BYREF) != 0; }
1277 /// Was declared as __unused by the user? See CVAR_UNUSED
1278 bool is_decl_unused() const { return (flags & CVAR_UNUSED) != 0; }
1279 /// Is lvar mapped to several chains
1280 bool is_shared() const { return (flags & CVAR_SHARED) != 0; }
1281 void set_used() { flags |= CVAR_USED; }
1282 void clear_used() { flags &= ~CVAR_USED; }
1283 void set_typed() { flags |= CVAR_TYPE; clr_noptr_var(); }
1284 void set_non_typed() { flags &= ~CVAR_TYPE; }
1285 void clr_user_info() { flags &= ~(CVAR_UNAME|CVAR_UTYPE|CVAR_NOPTR); }
1286 void set_user_name() { flags |= CVAR_NAME|CVAR_UNAME; }
1287 void set_user_type() { flags |= CVAR_TYPE|CVAR_UTYPE; }
1288 void clr_user_type() { flags &= ~CVAR_UTYPE; }
1289 void clr_user_name() { flags &= ~CVAR_UNAME; }
1290 void set_mreg_done() { flags |= CVAR_MREG; }
1291 void clr_mreg_done() { flags &= ~CVAR_MREG; }
1292 void set_unknown_width() { flags |= CVAR_NOWD; }
1293 void clr_unknown_width() { flags &= ~CVAR_NOWD; }
1294 void set_arg_var() { flags |= CVAR_ARG; }
1295 void clr_arg_var() { flags &= ~(CVAR_ARG|CVAR_THISARG); }
1296 void set_fake_var() { flags |= CVAR_FAKE; }
1297 void clr_fake_var() { flags &= ~CVAR_FAKE; }
1298 void set_overlapped_var() { flags |= CVAR_OVER; }
1299 void clr_overlapped_var() { flags &= ~CVAR_OVER; }
1300 void set_floating_var() { flags |= CVAR_FLOAT; }
1301 void clr_floating_var() { flags &= ~CVAR_FLOAT; }
1302 void set_spoiled_var() { flags |= CVAR_SPOILED; }
1303 void clr_spoiled_var() { flags &= ~CVAR_SPOILED; }
1304 void set_mapdst_var() { flags |= CVAR_MAPDST; }
1305 void clr_mapdst_var() { flags &= ~CVAR_MAPDST; }
1306 void set_partialy_typed() { flags |= CVAR_PARTIAL; }
1307 void clr_partialy_typed() { flags &= ~CVAR_PARTIAL; }
1308 void set_noptr_var() { flags |= CVAR_NOPTR; }
1309 void clr_noptr_var() { flags &= ~CVAR_NOPTR; }
1310 void set_thisarg() { flags |= CVAR_THISARG; }
1311 void clr_thisarg() { flags &= ~CVAR_THISARG; }
1312 void set_split_var() { flags |= CVAR_SPLIT; }
1313 void clr_split_var() { flags &= ~CVAR_SPLIT; }
1314 void set_dummy_arg() { flags |= CVAR_DUMMY; }
1315 void clr_dummy_arg() { flags &= ~CVAR_DUMMY; }
1316 void set_notarg() { clr_arg_var(); flags |= CVAR_NOTARG; }
1317 void clr_notarg() { flags &= ~CVAR_NOTARG; }
1318 void set_automapped() { flags |= CVAR_AUTOMAP; }
1319 void clr_automapped() { flags &= ~CVAR_AUTOMAP; }
1320 void set_used_byref() { flags |= CVAR_BYREF; }
1321 void clr_used_byref() { flags &= ~CVAR_BYREF; }
1322 void set_decl_unused() { flags |= CVAR_UNUSED; }
1323 void clr_decl_unused() { flags &= ~CVAR_UNUSED; }
1324 void set_shared() { flags |= CVAR_SHARED; }
1325 void clr_shared() { flags &= ~CVAR_SHARED; }
1326
1327 /// Do variables overlap?
1328 bool has_common(const lvar_t &v) const
1329 {
1330 return arglocs_overlap(location, width, v.location, v.width);
1331 }
1332 /// Does the variable overlap with the specified location?
1333 bool has_common_bit(const vdloc_t &loc, asize_t width2) const
1334 {
1335 return arglocs_overlap(location, width, loc, width2);
1336 }
1337 /// Get variable type
1338 const tinfo_t &type() const { return tif; }
1339 tinfo_t &type() { return tif; }
1340
1341 /// Check if the variable accept the specified type.
1342 /// Some types are forbidden (void, function types, wrong arrays, etc)
1343 bool hexapi accepts_type(const tinfo_t &t, bool may_change_thisarg=false);
1344 /// Set variable type
1345 /// Note: this function does not modify the idb, only the lvar instance
1346 /// in the memory. For permanent changes see modify_user_lvars()
1347 /// Also, the variable type is not considered as final by the decompiler
1348 /// and may be modified later by the type derivation.
1349 /// In some cases set_final_var_type() may work better, but it does not
1350 /// do persistent changes to the database neither.
1351 /// \param t new type
1352 /// \param may_fail if false and type is bad, interr
1353 /// \return success
1354 bool hexapi set_lvar_type(const tinfo_t &t, bool may_fail=false);
1355
1356 /// Set final variable type.
1357 void set_final_lvar_type(const tinfo_t &t)
1358 {
1359 set_lvar_type(t);
1360 set_typed();
1361 }
1362
1363 /// Change the variable width.
1364 /// We call the variable size 'width', it is represents the number of bytes.
1365 /// This function may change the variable type using set_lvar_type().
1366 /// \param w new width
1367 /// \param svw_flags combination of SVW_... bits
1368 /// \return success
1369 bool hexapi set_width(int w, int svw_flags=0);
1370#define SVW_INT 0x00 // integer value
1371#define SVW_FLOAT 0x01 // floating point value
1372#define SVW_SOFT 0x02 // may fail and return false;
1373 // if this bit is not set and the type is bad, interr
1374
1375 /// Append local variable to mlist.
1376 /// \param mba ptr to the current mba_t
1377 /// \param lst list to append to
1378 /// \param pad_if_scattered if true, append padding bytes in case of scattered lvar
1379 void hexapi append_list(const mba_t *mba, mlist_t *lst, bool pad_if_scattered=false) const;
1380
1381 /// Is the variable aliasable?
1382 /// \param mba ptr to the current mba_t
1383 /// Aliasable variables may be modified indirectly (through a pointer)
1384 bool is_aliasable(const mba_t *mba) const
1385 {
1386 return location.is_aliasable(mba, width);
1387 }
1388
1389};
1390DECLARE_TYPE_AS_MOVABLE(lvar_t);
1391
1392/// Vector of local variables
1393struct lvars_t : public qvector<lvar_t>
1394{
1395 /// Find input variable at the specified location.
1396 /// \param argloc variable location
1397 /// \param _size variable size
1398 /// \return -1 if failed, otherwise the index into the variables vector.
1399 int find_input_lvar(const vdloc_t &argloc, int _size) { return find_lvar(argloc, _size, 0); }
1400
1401
1402 /// Find stack variable at the specified location.
1403 /// \param spoff offset from the minimal sp
1404 /// \param width variable size
1405 /// \return -1 if failed, otherwise the index into the variables vector.
1406 int hexapi find_stkvar(sval_t spoff, int width);
1407
1408
1409 /// Find variable at the specified location.
1410 /// \param ll variable location
1411 /// \return pointer to variable or nullptr
1412 lvar_t *hexapi find(const lvar_locator_t &ll);
1413
1414
1415 /// Find variable at the specified location.
1416 /// \param location variable location
1417 /// \param width variable size
1418 /// \param defblk definition block of the lvar. -1 means any block
1419 /// \return -1 if failed, otherwise the index into the variables vector.
1420 int hexapi find_lvar(const vdloc_t &location, int width, int defblk=-1) const;
1421};
1422
1423/// Saved user settings for local variables: name, type, comment.
1425{
1426 lvar_locator_t ll; ///< Variable locator
1427 qstring name; ///< Name
1428 tinfo_t type; ///< Type
1429 qstring cmt; ///< Comment
1430 ssize_t size = BADSIZE; ///< Type size (if not initialized then -1)
1431 int flags = 0; ///< \ref LVINF_
1432/// \defgroup LVINF_ saved user lvar info property bits
1433/// Used in lvar_saved_info_t::flags
1434///@{
1435#define LVINF_KEEP 0x0001 ///< preserve saved user settings regardless of vars
1436 ///< for example, if a var loses all its
1437 ///< user-defined attributes or even gets
1438 ///< destroyed, keep its lvar_saved_info_t.
1439 ///< this is used for ephemeral variables that
1440 ///< get destroyed by macro recognition.
1441#define LVINF_SPLIT 0x0002 ///< split allocation of a new variable.
1442 ///< forces the decompiler to create a new
1443 ///< variable at ll.defea
1444#define LVINF_NOPTR 0x0004 ///< variable type should not be a pointer
1445#define LVINF_NOMAP 0x0008 ///< forbid automatic mapping of the variable
1446#define LVINF_UNUSED 0x0010 ///< unused argument, corresponds to CVAR_UNUSED
1447///@}
1448 bool has_info() const
1449 {
1450 return !name.empty()
1451 || !type.empty()
1452 || !cmt.empty()
1453 || is_split_lvar()
1454 || is_noptr_lvar()
1455 || is_nomap_lvar();
1456 }
1457 bool operator==(const lvar_saved_info_t &r) const
1458 {
1459 return name == r.name
1460 && cmt == r.cmt
1461 && ll == r.ll
1462 && type == r.type;
1463 }
1464 bool operator!=(const lvar_saved_info_t &r) const { return !(*this == r); }
1465 bool is_kept() const { return (flags & LVINF_KEEP) != 0; }
1466 void clear_keep() { flags &= ~LVINF_KEEP; }
1467 void set_keep() { flags |= LVINF_KEEP; }
1468 bool is_split_lvar() const { return (flags & LVINF_SPLIT) != 0; }
1469 void set_split_lvar() { flags |= LVINF_SPLIT; }
1470 void clr_split_lvar() { flags &= ~LVINF_SPLIT; }
1471 bool is_noptr_lvar() const { return (flags & LVINF_NOPTR) != 0; }
1472 void set_noptr_lvar() { flags |= LVINF_NOPTR; }
1473 void clr_noptr_lvar() { flags &= ~LVINF_NOPTR; }
1474 bool is_nomap_lvar() const { return (flags & LVINF_NOMAP) != 0; }
1475 void set_nomap_lvar() { flags |= LVINF_NOMAP; }
1476 void clr_nomap_lvar() { flags &= ~LVINF_NOMAP; }
1477 bool is_unused_lvar() const { return (flags & LVINF_UNUSED) != 0; }
1478 void set_unused_lvar() { flags |= LVINF_UNUSED; }
1479 void clr_unused_lvar() { flags &= ~LVINF_UNUSED; }
1480};
1481DECLARE_TYPE_AS_MOVABLE(lvar_saved_info_t);
1482typedef qvector<lvar_saved_info_t> lvar_saved_infos_t;
1483
1484/// Local variable mapping (is used to merge variables)
1485typedef std::map<lvar_locator_t, lvar_locator_t> lvar_mapping_t;
1486
1487/// All user-defined information about local variables
1489{
1490 /// User-specified names, types, comments for lvars. Variables without
1491 /// user-specified info are not present in this vector.
1492 lvar_saved_infos_t lvvec;
1493
1494 /// Local variable mapping (used for merging variables)
1496
1497 /// Delta to add to IDA stack offset to calculate Hex-Rays stack offsets.
1498 /// Should be set by the caller before calling save_user_lvar_settings();
1499 uval_t stkoff_delta = 0;
1500
1501/// \defgroup ULV_ lvar_uservec_t property bits
1502/// Used in lvar_uservec_t::ulv_flags
1503///@{
1504#define ULV_PRECISE_DEFEA 0x0001 ///< Use precise defea's for lvar locations
1505///@}
1506 /// Various flags. Possible values are from \ref ULV_
1507 int ulv_flags = ULV_PRECISE_DEFEA;
1508
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();
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() 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 = nullptr; ///< pointer to bitmap
1751 size_t high = 0; ///< highest bit+1 (multiply of bitset_width)
1752
1753public:
1754 bitset_t() {}
1755 hexapi bitset_t(const bitset_t &m); // copy constructor
1756 ~bitset_t()
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() const;
1784 bool hexapi empty() const; // is empty?
1785 int hexapi count() const; // number of set bits
1786 int hexapi count(int bit) const; // get number set bits starting from 'bit'
1787 int hexapi last() const; // get the number of the last bit (-1-no bits)
1788 void clear() { 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*() const { return i; }
1807 };
1808 typedef iterator const_iterator;
1809 iterator itat(int n) const { return iterator(goup(n)); }
1810 iterator begin() const { return itat(0); }
1811 iterator end() const { return iterator(high); }
1812 int front() const { return *begin(); }
1813 int back() 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() const { return size == 0; }
1847 void clear() { size = 0; }
1848 void print(qstring *vout) const;
1849 const char *hexapi dstr() 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() 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() {}
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() const { return bag.back(); }
1940 size_t nivls() const { return bag.size(); }
1941 bool empty() const { return bag.empty(); }
1942 void clear() { bag.clear(); }
1943 void qclear() { 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() const { return bag.begin(); }
1955 const_iterator end() const { return bag.end(); }
1956 iterator begin() { return bag.begin(); }
1957 iterator end() { 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() const;
1981 asize_t hexapi count() 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() {}
1999 rlist_t(const rlist_t &m) : bitset_t(m) {}
2000 rlist_t(mreg_t reg, int width) { add(reg, width); }
2001 ~rlist_t() {}
2002 rlist_t &operator=(const rlist_t &) = default;
2003 void hexapi print(qstring *vout) const;
2004 const char *hexapi dstr() const;
2005};
2006DECLARE_TYPE_AS_MOVABLE(rlist_t);
2007
2008//-------------------------------------------------------------------------
2009// Microlist: list of register and memory locations
2011{
2012 rlist_t reg; // registers
2013 ivlset_t mem; // memory locations
2014
2015 mlist_t() {}
2016 mlist_t(const ivl_t &ivl) : mem(ivl) {}
2017 mlist_t(mreg_t r, int size) : reg(r, size) {}
2018
2019 void swap(mlist_t &r) { reg.swap(r.reg); mem.swap(r.mem); }
2020 bool hexapi addmem(ea_t ea, asize_t size);
2021 bool add(mreg_t r, int size) { return add(mlist_t(r, size)); } // also see append_def_list()
2022 bool add(const rlist_t &r) { return reg.add(r); }
2023 bool add(const ivl_t &ivl) { return add(mlist_t(ivl)); }
2024 bool add(const mlist_t &lst)
2025 {
2026 bool changed = reg.add(lst.reg);
2027 if ( mem.add(lst.mem) )
2028 changed = true;
2029 return changed;
2030 }
2031 bool sub(mreg_t r, int size) { return sub(mlist_t(r, size)); }
2032 bool sub(const ivl_t &ivl) { return sub(mlist_t(ivl)); }
2033 bool sub(const mlist_t &lst)
2034 {
2035 bool changed = reg.sub(lst.reg);
2036 if ( mem.sub(lst.mem) )
2037 changed = true;
2038 return changed;
2039 }
2040 asize_t count() const { return reg.count() + mem.count(); }
2041 void hexapi print(qstring *vout) const;
2042 const char *hexapi dstr() const;
2043 bool empty() const { return reg.empty() && mem.empty(); }
2044 void clear() { reg.clear(); mem.clear(); }
2045 bool has(mreg_t r) const { return reg.has(r); }
2046 bool has_all(mreg_t r, int size) const { return reg.has_all(r, size); }
2047 bool has_any(mreg_t r, int size) const { return reg.has_any(r, size); }
2048 bool has_memory() const { return !mem.empty(); }
2049 bool has_allmem() const { return mem == ALLMEM; }
2050 bool has_common(const mlist_t &lst) const { return reg.has_common(lst.reg) || mem.has_common(lst.mem); }
2051 bool includes(const mlist_t &lst) const { return reg.includes(lst.reg) && mem.includes(lst.mem); }
2052 bool intersect(const mlist_t &lst)
2053 {
2054 bool changed = reg.intersect(lst.reg);
2055 if ( mem.intersect(lst.mem) )
2056 changed = true;
2057 return changed;
2058 }
2059 bool is_subset_of(const mlist_t &lst) const { return lst.includes(*this); }
2060
2061 DECLARE_COMPARISONS(mlist_t);
2062 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2063};
2064DECLARE_TYPE_AS_MOVABLE(mlist_t);
2065typedef qvector<mlist_t> mlistvec_t;
2066DECLARE_TYPE_AS_MOVABLE(mlistvec_t);
2067
2068//-------------------------------------------------------------------------
2069/// Get list of temporary registers.
2070/// Tempregs are temporary registers that are used during code generation.
2071/// They do not map to regular processor registers. They are used only to
2072/// store temporary values during execution of one instruction.
2073/// Tempregs may not be used to pass a value from one block to another.
2074/// In other words, at the end of a block all tempregs must be dead.
2076
2077/// Is a kernel register?
2078/// Kernel registers are temporary registers that can be used freely.
2079/// They may be used to store values that cross instruction or basic block
2080/// boundaries. Kernel registers do not map to regular processor registers.
2081/// See also \ref mba_t::alloc_kreg()
2082bool hexapi is_kreg(mreg_t r);
2083
2084/// Map a processor register to a microregister.
2085/// \param reg processor register number
2086/// \return microregister register id or mr_none
2087mreg_t hexapi reg2mreg(int reg);
2088
2089/// Map a microregister to a processor register.
2090/// \param reg microregister number
2091/// \param width size of microregister in bytes
2092/// \return processor register id or -1
2093int hexapi mreg2reg(mreg_t reg, int width);
2094
2095/// Get the microregister name.
2096/// \param out output buffer, may be nullptr
2097/// \param reg microregister number
2098/// \param width size of microregister in bytes. may be bigger than the real
2099/// register size.
2100/// \param ud reserved, must be nullptr
2101/// \return width of the printed register. this value may be less than
2102/// the WIDTH argument.
2103
2104int hexapi get_mreg_name(qstring *out, mreg_t reg, int width, void *ud=nullptr);
2105
2106//-------------------------------------------------------------------------
2107/// User defined callback to optimize individual microcode instructions
2109{
2110 /// Optimize an instruction.
2111 /// \param blk current basic block. maybe nullptr, which means that
2112 /// the instruction must be optimized without context
2113 /// \param ins instruction to optimize; it is always a top-level instruction.
2114 /// the callback may not delete the instruction but may
2115 /// convert it into nop (see mblock_t::make_nop). to optimize
2116 /// sub-instructions, visit them using minsn_visitor_t.
2117 /// sub-instructions may not be converted into nop but
2118 /// can be converted to "mov x,x". for example:
2119 /// add x,0,x => mov x,x
2120 /// this callback may change other instructions in the block,
2121 /// but should do this with care, e.g. to no break the
2122 /// propagation algorithm if called with OPTI_NO_LDXOPT.
2123 /// \param optflags combination of \ref OPTI_ bits
2124 /// \return number of changes made to the instruction.
2125 /// if after this call the instruction's use/def lists have changed,
2126 /// you must mark the block level lists as dirty (see mark_lists_dirty)
2127 virtual int idaapi func(mblock_t *blk, minsn_t *ins, int optflags) = 0;
2128};
2129
2130/// Install an instruction level custom optimizer
2131/// \param opt an instance of optinsn_t. cannot be destroyed before calling
2132/// remove_optinsn_handler().
2134
2135/// Remove an instruction level custom optimizer
2137
2138/// User defined callback to optimize microcode blocks
2140{
2141 /// Optimize a block.
2142 /// This function usually performs the optimizations that require analyzing
2143 /// the entire block and/or its neighbors. For example it can recognize
2144 /// patterns and perform conversions like:
2145 /// b0: b0:
2146 /// ... ...
2147 /// jnz x, 0, @b2 => jnz x, 0, @b2
2148 /// b1: b1:
2149 /// add x, 0, y mov x, y
2150 /// ... ...
2151 /// \param blk Basic block to optimize as a whole.
2152 /// \return number of changes made to the block. See also mark_lists_dirty.
2153 virtual int idaapi func(mblock_t *blk) = 0;
2154};
2155
2156/// Install a block level custom optimizer.
2157/// \param opt an instance of optblock_t. cannot be destroyed before calling
2158/// remove_optblock_handler().
2160
2161/// Remove a block level custom optimizer
2163
2164
2165//-------------------------------------------------------------------------
2166// abstract graph interface
2167class simple_graph_t : public gdl_graph_t
2168{
2169public:
2170 qstring title;
2171 bool colored_gdl_edges = false;
2172private:
2173 friend class iterator;
2174 virtual int goup(int node) const newapi;
2175};
2176
2177//-------------------------------------------------------------------------
2178// Since our data structures are quite complex, we use the visitor pattern
2179// in many of our algorthims. This functionality is available for plugins too.
2180// https://en.wikipedia.org/wiki/Visitor_pattern
2181
2182// All our visitor callbacks return an integer value.
2183// Visiting is interrupted as soon an the return value is non-zero.
2184// This non-zero value is returned as the result of the for_all_... function.
2185// If for_all_... returns 0, it means that it successfully visited all items.
2186
2187/// The context info used by visitors
2189{
2190 mba_t *mba; // current microcode
2191 mblock_t *blk; // current block
2192 minsn_t *topins; // top level instruction (parent of curins or curins itself)
2193 minsn_t *curins; // currently visited instruction
2195 mba_t *_mba=nullptr,
2196 mblock_t *_blk=nullptr,
2197 minsn_t *_topins=nullptr)
2198 : mba(_mba), blk(_blk), topins(_topins), curins(nullptr) {}
2199 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2200 bool really_alloc() const;
2201};
2202
2203/// Micro instruction visitor.
2204/// See mba_t::for_all_topinsns, minsn_t::for_all_insns,
2205/// mblock_::for_all_insns, mba_t::for_all_insns
2207{
2209 mba_t *_mba=nullptr,
2210 mblock_t *_blk=nullptr,
2211 minsn_t *_topins=nullptr)
2212 : op_parent_info_t(_mba, _blk, _topins) {}
2213 virtual int idaapi visit_minsn() = 0;
2214};
2215
2216/// Micro operand visitor.
2217/// See mop_t::for_all_ops, minsn_t::for_all_ops, mblock_t::for_all_insns,
2218/// mba_t::for_all_insns
2220{
2222 mba_t *_mba=nullptr,
2223 mblock_t *_blk=nullptr,
2224 minsn_t *_topins=nullptr)
2225 : op_parent_info_t(_mba, _blk, _topins), prune(false) {}
2226 /// Should skip sub-operands of the current operand?
2227 /// visit_mop() may set 'prune=true' for that.
2228 bool prune;
2229 virtual int idaapi visit_mop(mop_t *op, const tinfo_t *type, bool is_target) = 0;
2230};
2231
2232/// Scattered mop: visit each of the scattered locations as a separate mop.
2233/// See mop_t::for_all_scattered_submops
2235{
2236 virtual int idaapi visit_scif_mop(const mop_t &r, int off) = 0;
2237};
2238
2239// Used operand visitor.
2240// See mblock_t::for_all_uses
2242{
2243 minsn_t *topins = nullptr;
2244 minsn_t *curins = nullptr;
2245 bool changed = false;
2246 mlist_t *list = nullptr;
2247 virtual int idaapi visit_mop(mop_t *op) = 0;
2248};
2249
2250//-------------------------------------------------------------------------
2251/// Instruction operand types
2252
2253typedef uint8 mopt_t;
2254const mopt_t
2255 mop_z = 0, ///< none
2256 mop_r = 1, ///< register (they exist until MMAT_LVARS)
2257 mop_n = 2, ///< immediate number constant
2258 mop_str = 3, ///< immediate string constant (user representation)
2259 mop_d = 4, ///< result of another instruction
2260 mop_S = 5, ///< local stack variable (they exist until MMAT_LVARS)
2261 mop_v = 6, ///< global variable
2262 mop_b = 7, ///< micro basic block (mblock_t)
2263 mop_f = 8, ///< list of arguments
2264 mop_l = 9, ///< local variable
2265 mop_a = 10, ///< mop_addr_t: address of operand (mop_l, mop_v, mop_S, mop_r)
2266 mop_h = 11, ///< helper function
2267 mop_c = 12, ///< mcases
2268 mop_fn = 13, ///< floating point constant
2269 mop_p = 14, ///< operand pair
2270 mop_sc = 15; ///< scattered
2271
2272const int NOSIZE = -1; ///< wrong or unexisting operand size
2273
2274//-------------------------------------------------------------------------
2275/// Reference to a local variable. Used by mop_l
2277{
2278 /// Pointer to the parent mba_t object.
2279 /// Since we need to access the 'mba->vars' array in order to retrieve
2280 /// the referenced variable, we keep a pointer to mba_t here.
2281 /// Note: this means this class and consequently mop_t, minsn_t, mblock_t
2282 /// are specific to a mba_t object and cannot migrate between
2283 /// them. fortunately this is not something we need to do.
2284 /// second, lvar_ref_t's appear only after MMAT_LVARS.
2285 mba_t *const mba;
2286 sval_t off; ///< offset from the beginning of the variable
2287 int idx; ///< index into mba->vars
2288 lvar_ref_t(mba_t *m, int i, sval_t o=0) : mba(m), off(o), idx(i) {}
2289 lvar_ref_t(const lvar_ref_t &r) : mba(r.mba), off(r.off), idx(r.idx) {}
2290 lvar_ref_t &operator=(const lvar_ref_t &r)
2291 {
2292 off = r.off;
2293 idx = r.idx;
2294 return *this;
2295 }
2296 DECLARE_COMPARISONS(lvar_ref_t);
2297 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2298 void swap(lvar_ref_t &r)
2299 {
2300 std::swap(off, r.off);
2301 std::swap(idx, r.idx);
2302 }
2303 lvar_t &hexapi var() const; ///< Retrieve the referenced variable
2304};
2305
2306//-------------------------------------------------------------------------
2307/// Reference to a stack variable. Used for mop_S
2309{
2310 /// Pointer to the parent mba_t object.
2311 /// We need it in order to retrieve the referenced stack variable.
2312 /// See notes for lvar_ref_t::mba.
2313 mba_t *const mba;
2314
2315 /// Offset to the stack variable from the bottom of the stack frame.
2316 /// It is called 'decompiler stkoff' and it is different from IDA stkoff.
2317 /// See a note and a picture about 'decompiler stkoff' below.
2318 sval_t off;
2319
2320 stkvar_ref_t(mba_t *m, sval_t o) : mba(m), off(o) {}
2321 DECLARE_COMPARISONS(stkvar_ref_t);
2322 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2323 void swap(stkvar_ref_t &r)
2324 {
2325 std::swap(off, r.off);
2326 }
2327 /// Retrieve the referenced stack variable.
2328 /// \param p_off if specified, will hold IDA stkoff after the call.
2329 /// \return pointer to the stack variable
2330 member_t *hexapi get_stkvar(uval_t *p_off=nullptr) const;
2331};
2332
2333//-------------------------------------------------------------------------
2334/// Scattered operand info. Used for mop_sc
2335struct scif_t : public vdloc_t
2336{
2337 /// Pointer to the parent mba_t object.
2338 /// Some operations may convert a scattered operand into something simpler,
2339 /// (a stack operand, for example). We will need to create stkvar_ref_t at
2340 /// that moment, this is why we need this pointer.
2341 /// See notes for lvar_ref_t::mba.
2343
2344 /// Usually scattered operands are created from a function prototype,
2345 /// which has the name information. We preserve it and use it to name
2346 /// the corresponding local variable.
2347 qstring name;
2348
2349 /// Scattered operands always have type info assigned to them
2350 /// because without it we won't be able to manipulte them.
2351 tinfo_t type;
2352
2353 scif_t(mba_t *_mba, tinfo_t *tif, qstring *n=nullptr) : mba(_mba)
2354 {
2355 if ( n != nullptr )
2356 n->swap(name);
2357 tif->swap(type);
2358 }
2359 scif_t &operator =(const vdloc_t &loc)
2360 {
2361 *(vdloc_t *)this = loc;
2362 return *this;
2363 }
2364};
2365
2366//-------------------------------------------------------------------------
2367/// An integer constant. Used for mop_n
2368/// We support 64-bit values but 128-bit values can be represented with mop_p
2370{
2371 uint64 value;
2372 uint64 org_value; // original value before changing the operand size
2373 mnumber_t(uint64 v, ea_t _ea=BADADDR, int n=0)
2374 : operand_locator_t(_ea, n), value(v), org_value(v) {}
2375 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2376 DECLARE_COMPARISONS(mnumber_t)
2377 {
2378 if ( value < r.value )
2379 return -1;
2380 if ( value > r.value )
2381 return -1;
2382 return 0;
2383 }
2384 // always use this function instead of manually modifying the 'value' field
2385 void update_value(uint64 val64)
2386 {
2387 value = val64;
2388 org_value = val64;
2389 }
2390};
2391
2392//-------------------------------------------------------------------------
2393/// Floating point constant. Used for mop_fn
2394/// For more details, please see the ieee.h file from IDA SDK.
2396{
2397 fpvalue_t fnum; ///< Internal representation of the number
2398 int nbytes; ///< Original size of the constant in bytes
2399 operator uint16 *() { return fnum.w; }
2400 operator const uint16 *() const { return fnum.w; }
2401 void hexapi print(qstring *vout) const;
2402 const char *hexapi dstr() const;
2403 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2404 DECLARE_COMPARISONS(fnumber_t)
2405 {
2406 return ecmp(fnum, r.fnum);
2407 }
2408};
2409
2410//-------------------------------------------------------------------------
2411/// \defgroup SHINS_ Bits to control how we print instructions
2412///@{
2413#define SHINS_NUMADDR 0x01 ///< display definition addresses for numbers
2414#define SHINS_VALNUM 0x02 ///< display value numbers
2415#define SHINS_SHORT 0x04 ///< do not display use-def chains and other attrs
2416#define SHINS_LDXEA 0x08 ///< display address of ldx expressions (not used)
2417///@}
2418
2419//-------------------------------------------------------------------------
2420/// How to handle side effect of change_size()
2421/// Sometimes we need to create a temporary operand and change its size in order
2422/// to check some hypothesis. If we revert our changes, we do not want that the
2423/// database (global variables, stack frame, etc) changes in any manner.
2425{
2426 NO_SIDEFF, ///< change operand size but ignore side effects
2427 ///< if you decide to keep the changed operand,
2428 ///< handle_new_size() must be called
2429 WITH_SIDEFF, ///< change operand size and handle side effects
2430 ONLY_SIDEFF, ///< only handle side effects
2431 ANY_REGSIZE = 0x80, ///< any register size is permitted
2432 ANY_FPSIZE = 0x100, ///< any size of floating operand is permitted
2433};
2434
2435//-------------------------------------------------------------------------
2436/// A microinstruction operand.
2437/// This is the smallest building block of our microcode.
2438/// Operands will be part of instructions, which are then grouped into basic blocks.
2439/// The microcode consists of an array of such basic blocks + some additional info.
2441{
2442 void hexapi copy(const mop_t &rop);
2443public:
2444 /// Operand type.
2446
2447 /// Operand properties.
2448 uint8 oprops;
2449#define OPROP_IMPDONE 0x01 ///< imported operand (a pointer) has been dereferenced
2450#define OPROP_UDT 0x02 ///< a struct or union
2451#define OPROP_FLOAT 0x04 ///< possibly floating value
2452#define OPROP_CCFLAGS 0x08 ///< mop_n: a pc-relative value
2453 ///< mop_a: an address obtained from a relocation
2454 ///< else: value of a condition code register (like mr_cc)
2455#define OPROP_UDEFVAL 0x10 ///< uses undefined value
2456#define OPROP_LOWADDR 0x20 ///< a low address offset
2457
2458 /// Value number.
2459 /// Zero means unknown.
2460 /// Operands with the same value number are equal.
2461 uint16 valnum;
2462
2463 /// Operand size.
2464 /// Usually it is 1,2,4,8 or NOSIZE but for UDTs other sizes are permitted
2465 int size;
2466
2467 /// The following union holds additional details about the operand.
2468 /// Depending on the operand type different kinds of info are stored.
2469 /// You should access these fields only after verifying the operand type.
2470 /// All pointers are owned by the operand and are freed by its destructor.
2471 union
2472 {
2473 mreg_t r; // mop_r register number
2474 mnumber_t *nnn; // mop_n immediate value
2475 minsn_t *d; // mop_d result (destination) of another instruction
2476 stkvar_ref_t *s; // mop_S stack variable
2477 ea_t g; // mop_v global variable (its linear address)
2478 int b; // mop_b block number (used in jmp,call instructions)
2479 mcallinfo_t *f; // mop_f function call information
2480 lvar_ref_t *l; // mop_l local variable
2481 mop_addr_t *a; // mop_a variable whose address is taken
2482 char *helper; // mop_h helper function name
2483 char *cstr; // mop_str utf8 string constant, user representation
2484 mcases_t *c; // mop_c cases
2485 fnumber_t *fpc; // mop_fn floating point constant
2486 mop_pair_t *pair; // mop_p operand pair
2487 scif_t *scif; // mop_sc scattered operand info
2488 };
2489 // -- End of data fields, member function declarations follow:
2490
2491 void set_impptr_done() { oprops |= OPROP_IMPDONE; }
2492 void set_udt() { oprops |= OPROP_UDT; }
2493 void set_undef_val() { oprops |= OPROP_UDEFVAL; }
2494 void set_lowaddr() { oprops |= OPROP_LOWADDR; }
2495 bool is_impptr_done() const { return (oprops & OPROP_IMPDONE) != 0; }
2496 bool is_udt() const { return (oprops & OPROP_UDT) != 0; }
2497 bool probably_floating() const { return (oprops & OPROP_FLOAT) != 0; }
2498 bool is_undef_val() const { return (oprops & OPROP_UDEFVAL) != 0; }
2499 bool is_lowaddr() const { return (oprops & OPROP_LOWADDR) != 0; }
2500 bool is_ccflags() const
2501 {
2502 return (oprops & OPROP_CCFLAGS) != 0
2503 && (t == mop_l || t == mop_v || t == mop_S || t == mop_r);
2504 }
2505 bool is_pcval() const
2506 {
2507 return t == mop_n && (oprops & OPROP_CCFLAGS) != 0;
2508 }
2509 bool is_glbaddr_from_fixup() const
2510 {
2511 return is_glbaddr() && (oprops & OPROP_CCFLAGS) != 0;
2512 }
2513
2514 mop_t() { zero(); }
2515 mop_t(const mop_t &rop) { copy(rop); }
2516 mop_t(mreg_t _r, int _s) : t(mop_r), oprops(0), valnum(0), size(_s), r(_r) {}
2517 mop_t &operator=(const mop_t &rop) { return assign(rop); }
2518 mop_t &hexapi assign(const mop_t &rop);
2519 ~mop_t()
2520 {
2521 erase();
2522 }
2523 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2524 void zero() { t = mop_z; oprops = 0; valnum = 0; size = NOSIZE; nnn = nullptr; }
2525 void hexapi swap(mop_t &rop);
2526 void hexapi erase();
2527 void erase_but_keep_size() { int s2 = size; erase(); size = s2; }
2528
2529 void hexapi print(qstring *vout, int shins_flags=SHINS_SHORT|SHINS_VALNUM) const;
2530 const char *hexapi dstr() const; // use this function for debugging
2531
2532 //-----------------------------------------------------------------------
2533 // Operand creation
2534 //-----------------------------------------------------------------------
2535 /// Create operand from mlist_t.
2536 /// Example: if LST contains 4 bits for R0.4, our operand will be
2537 /// (t=mop_r, r=R0, size=4)
2538 /// \param mba pointer to microcode
2539 /// \param lst list of locations
2540 /// \param fullsize mba->fullsize
2541 /// \return success
2542 bool hexapi create_from_mlist(mba_t *mba, const mlist_t &lst, sval_t fullsize);
2543
2544 /// Create operand from ivlset_t.
2545 /// Example: if IVS contains [glbvar..glbvar+4), our operand will be
2546 /// (t=mop_v, g=&glbvar, size=4)
2547 /// \param mba pointer to microcode
2548 /// \param ivs set of memory intervals
2549 /// \param fullsize mba->fullsize
2550 /// \return success
2551 bool hexapi create_from_ivlset(mba_t *mba, const ivlset_t &ivs, sval_t fullsize);
2552
2553 /// Create operand from vdloc_t.
2554 /// Example: if LOC contains (type=ALOC_REG1, r=R0), our operand will be
2555 /// (t=mop_r, r=R0, size=_SIZE)
2556 /// \param mba pointer to microcode
2557 /// \param loc location
2558 /// \param _size operand size
2559 /// Note: this function cannot handle scattered locations.
2560 /// \return success
2561 void hexapi create_from_vdloc(mba_t *mba, const vdloc_t &loc, int _size);
2562
2563 /// Create operand from scattered vdloc_t.
2564 /// Example: if LOC is (ALOC_DIST, {EAX.4, EDX.4}) and TYPE is _LARGE_INTEGER,
2565 /// our operand will be
2566 /// (t=mop_sc, scif={EAX.4, EDX.4})
2567 /// \param mba pointer to microcode
2568 /// \param name name of the operand, if available
2569 /// \param type type of the operand, must be present
2570 /// \param loc a scattered location
2571 /// \return success
2572 void hexapi create_from_scattered_vdloc(
2573 mba_t *mba,
2574 const char *name,
2575 tinfo_t type,
2576 const vdloc_t &loc);
2577
2578 /// Create operand from an instruction.
2579 /// This function creates a nested instruction that can be used as an operand.
2580 /// Example: if m="add x,y,z", our operand will be (t=mop_d,d=m).
2581 /// The destination operand of 'add' (z) is lost.
2582 /// \param m instruction to embed into operand. may not be nullptr.
2583 void hexapi create_from_insn(const minsn_t *m);
2584
2585 /// Create an integer constant operand.
2586 /// \param _value value to store in the operand
2587 /// \param _size size of the value in bytes (1,2,4,8)
2588 /// \param _ea address of the processor instruction that made the value
2589 /// \param opnum operand number of the processor instruction
2590 void hexapi make_number(uint64 _value, int _size, ea_t _ea=BADADDR, int opnum=0);
2591
2592 /// Create a floating point constant operand.
2593 /// \param bytes pointer to the floating point value as used by the current
2594 /// processor (e.g. for x86 it must be in IEEE 754)
2595 /// \param _size number of bytes occupied by the constant.
2596 /// \return success
2597 bool hexapi make_fpnum(const void *bytes, size_t _size);
2598
2599 /// Create a register operand without erasing previous data.
2600 /// \param reg micro register number
2601 /// Note: this function does not erase the previous contents of the operand;
2602 /// call erase() if necessary
2604 {
2605 t = mop_r;
2606 r = reg;
2607 }
2608 void _make_reg(mreg_t reg, int _size)
2609 {
2610 t = mop_r;
2611 r = reg;
2612 size = _size;
2613 }
2614 /// Create a register operand.
2615 void make_reg(mreg_t reg) { erase(); _make_reg(reg); }
2616 void make_reg(mreg_t reg, int _size) { erase(); _make_reg(reg, _size); }
2617
2618 /// Create a local variable operand.
2619 /// \param mba pointer to microcode
2620 /// \param idx index into mba->vars
2621 /// \param off offset from the beginning of the variable
2622 /// Note: this function does not erase the previous contents of the operand;
2623 /// call erase() if necessary
2624 void _make_lvar(mba_t *mba, int idx, sval_t off=0)
2625 {
2626 t = mop_l;
2627 l = new lvar_ref_t(mba, idx, off);
2628 }
2629
2630 /// Create a global variable operand without erasing previous data.
2631 /// \param ea address of the variable
2632 /// Note: this function does not erase the previous contents of the operand;
2633 /// call erase() if necessary
2634 void hexapi _make_gvar(ea_t ea);
2635 /// Create a global variable operand.
2636 void hexapi make_gvar(ea_t ea);
2637
2638 /// Create a stack variable operand.
2639 /// \param mba pointer to microcode
2640 /// \param off decompiler stkoff
2641 /// Note: this function does not erase the previous contents of the operand;
2642 /// call erase() if necessary
2643 void _make_stkvar(mba_t *mba, sval_t off)
2644 {
2645 t = mop_S;
2646 s = new stkvar_ref_t(mba, off);
2647 }
2648 void make_stkvar(mba_t *mba, sval_t off) { erase(); _make_stkvar(mba, off); }
2649
2650 /// Create pair of registers.
2651 /// \param loreg register holding the low part of the value
2652 /// \param hireg register holding the high part of the value
2653 /// \param halfsize the size of each of loreg/hireg
2654 void hexapi make_reg_pair(int loreg, int hireg, int halfsize);
2655
2656 /// Create a nested instruction without erasing previous data.
2657 /// \param ins pointer to the instruction to encapsulate into the operand
2658 /// Note: this function does not erase the previous contents of the operand;
2659 /// call erase() if necessary
2660 /// See also create_from_insn, which is higher level
2661 void _make_insn(minsn_t *ins);
2662 /// Create a nested instruction.
2663 void make_insn(minsn_t *ins) { erase(); _make_insn(ins); }
2664
2665 /// Create a block reference operand without erasing previous data.
2666 /// \param blknum block number
2667 /// Note: this function does not erase the previous contents of the operand;
2668 /// call erase() if necessary
2669 void _make_blkref(int blknum)
2670 {
2671 t = mop_b;
2672 b = blknum;
2673 }
2674 /// Create a global variable operand.
2675 void make_blkref(int blknum) { erase(); _make_blkref(blknum); }
2676
2677 /// Create a helper operand.
2678 /// A helper operand usually keeps a built-in function name like "va_start"
2679 /// It is essentially just an arbitrary identifier without any additional info.
2680 void hexapi make_helper(const char *name);
2681
2682 /// Create a constant string operand.
2683 void _make_strlit(const char *str)
2684 {
2685 t = mop_str;
2686 cstr = ::qstrdup(str);
2687 }
2688 void _make_strlit(qstring *str) // str is consumed
2689 {
2690 t = mop_str;
2691 cstr = str->extract();
2692 }
2693
2694 /// Create a call info operand without erasing previous data.
2695 /// \param fi callinfo
2696 /// Note: this function does not erase the previous contents of the operand;
2697 /// call erase() if necessary
2699 {
2700 t = mop_f;
2701 f = fi;
2702 }
2703
2704 /// Create a 'switch cases' operand without erasing previous data.
2705 /// Note: this function does not erase the previous contents of the operand;
2706 /// call erase() if necessary
2707 void _make_cases(mcases_t *_cases)
2708 {
2709 t = mop_c;
2710 c = _cases;
2711 }
2712
2713 /// Create a pair operand without erasing previous data.
2714 /// Note: this function does not erase the previous contents of the operand;
2715 /// call erase() if necessary
2717 {
2718 t = mop_p;
2719 pair = _pair;
2720 }
2721
2722 //-----------------------------------------------------------------------
2723 // Various operand tests
2724 //-----------------------------------------------------------------------
2725 bool empty() const { return t == mop_z; }
2726 /// Is a register operand?
2727 /// See also get_mreg_name()
2728 bool is_reg() const { return t == mop_r; }
2729 /// Is the specified register?
2730 bool is_reg(mreg_t _r) const { return t == mop_r && r == _r; }
2731 /// Is the specified register of the specified size?
2732 bool is_reg(mreg_t _r, int _size) const { return t == mop_r && r == _r && size == _size; }
2733 /// Is a list of arguments?
2734 bool is_arglist() const { return t == mop_f; }
2735 /// Is a condition code?
2736 bool is_cc() const { return is_reg() && r >= mr_cf && r < mr_first; }
2737 /// Is a bit register?
2738 /// This includes condition codes and eventually other bit registers
2739 static bool hexapi is_bit_reg(mreg_t reg);
2740 bool is_bit_reg() const { return is_reg() && is_bit_reg(r); }
2741 /// Is a kernel register?
2742 bool is_kreg() const;
2743 /// Is a block reference to the specified block?
2744 bool is_mob(int serial) const { return t == mop_b && b == serial; }
2745 /// Is a scattered operand?
2746 bool is_scattered() const { return t == mop_sc; }
2747 /// Is address of a global memory cell?
2748 bool is_glbaddr() const;
2749 /// Is address of the specified global memory cell?
2750 bool is_glbaddr(ea_t ea) const;
2751 /// Is address of a stack variable?
2752 bool is_stkaddr() const;
2753 /// Is a sub-instruction?
2754 bool is_insn() const { return t == mop_d; }
2755 /// Is a sub-instruction with the specified opcode?
2756 bool is_insn(mcode_t code) const;
2757 /// Has any side effects?
2758 /// \param include_ldx_and_divs consider ldx/div/mod as having side effects?
2759 bool has_side_effects(bool include_ldx_and_divs=false) const;
2760 /// Is it possible for the operand to use aliased memory?
2761 bool hexapi may_use_aliased_memory() const;
2762
2763 /// Are the possible values of the operand only 0 and 1?
2764 /// This function returns true for 0/1 constants, bit registers,
2765 /// the result of 'set' insns, etc.
2766 bool hexapi is01() const;
2767
2768 /// Does the high part of the operand consist of the sign bytes?
2769 /// \param nbytes number of bytes that were sign extended.
2770 /// the remaining size-nbytes high bytes must be sign bytes
2771 /// Example: is_sign_extended_from(xds.4(op.1), 1) -> true
2772 /// because the high 3 bytes are certainly sign bits
2773 bool hexapi is_sign_extended_from(int nbytes) const;
2774
2775 /// Does the high part of the operand consist of zero bytes?
2776 /// \param nbytes number of bytes that were zero extended.
2777 /// the remaining size-nbytes high bytes must be zero
2778 /// Example: is_zero_extended_from(xdu.8(op.1), 2) -> true
2779 /// because the high 6 bytes are certainly zero
2780 bool hexapi is_zero_extended_from(int nbytes) const;
2781
2782 /// Does the high part of the operand consist of zero or sign bytes?
2783 bool is_extended_from(int nbytes, bool is_signed) const
2784 {
2785 if ( is_signed )
2786 return is_sign_extended_from(nbytes);
2787 else
2788 return is_zero_extended_from(nbytes);
2789 }
2790
2791 //-----------------------------------------------------------------------
2792 // Comparisons
2793 //-----------------------------------------------------------------------
2794 /// Compare operands.
2795 /// This is the main comparison function for operands.
2796 /// \param rop operand to compare with
2797 /// \param eqflags combination of \ref EQ_ bits
2798 bool hexapi equal_mops(const mop_t &rop, int eqflags) const;
2799 bool operator==(const mop_t &rop) const { return equal_mops(rop, 0); }
2800 bool operator!=(const mop_t &rop) const { return !equal_mops(rop, 0); }
2801
2802 /// Lexographical operand comparison.
2803 /// It can be used to store mop_t in various containers, like std::set
2804 bool operator <(const mop_t &rop) const { return lexcompare(rop) < 0; }
2805 friend int lexcompare(const mop_t &a, const mop_t &b) { return a.lexcompare(b); }
2806 int hexapi lexcompare(const mop_t &rop) const;
2807
2808 //-----------------------------------------------------------------------
2809 // Visiting operand parts
2810 //-----------------------------------------------------------------------
2811 /// Visit the operand and all its sub-operands.
2812 /// This function visits the current operand as well.
2813 /// \param mv visitor object
2814 /// \param type operand type
2815 /// \param is_target is a destination operand?
2816 int hexapi for_all_ops(
2817 mop_visitor_t &mv,
2818 const tinfo_t *type=nullptr,
2819 bool is_target=false);
2820
2821 /// Visit all sub-operands of a scattered operand.
2822 /// This function does not visit the current operand, only its sub-operands.
2823 /// All sub-operands are synthetic and are destroyed after the visitor.
2824 /// This function works only with scattered operands.
2825 /// \param sv visitor object
2826 int hexapi for_all_scattered_submops(scif_visitor_t &sv) const;
2827
2828 //-----------------------------------------------------------------------
2829 // Working with mop_n operands
2830 //-----------------------------------------------------------------------
2831 /// Retrieve value of a constant integer operand.
2832 /// These functions can be called only for mop_n operands.
2833 /// See is_constant() that can be called on any operand.
2834 uint64 value(bool is_signed) const { return extend_sign(nnn->value, size, is_signed); }
2835 int64 signed_value() const { return value(true); }
2836 uint64 unsigned_value() const { return value(false); }
2837 void update_numop_value(uint64 val)
2838 {
2839 nnn->update_value(extend_sign(val, size, false));
2840 }
2841
2842 /// Retrieve value of a constant integer operand.
2843 /// \param out pointer to the output buffer
2844 /// \param is_signed should treat the value as signed
2845 /// \return true if the operand is mop_n
2846 bool hexapi is_constant(uint64 *out=nullptr, bool is_signed=true) const;
2847
2848 bool is_equal_to(uint64 n, bool is_signed=true) const
2849 {
2850 uint64 v;
2851 return is_constant(&v, is_signed) && v == n;
2852 }
2853 bool is_zero() const { return is_equal_to(0, false); }
2854 bool is_one() const { return is_equal_to(1, false); }
2855 bool is_positive_constant() const
2856 {
2857 uint64 v;
2858 return is_constant(&v, true) && int64(v) > 0;
2859 }
2860 bool is_negative_constant() const
2861 {
2862 uint64 v;
2863 return is_constant(&v, true) && int64(v) < 0;
2864 }
2865
2866 //-----------------------------------------------------------------------
2867 // Working with mop_S operands
2868 //-----------------------------------------------------------------------
2869 /// Retrieve the referenced stack variable.
2870 /// \param p_off if specified, will hold IDA stkoff after the call.
2871 /// \return pointer to the stack variable
2872 member_t *get_stkvar(uval_t *p_off) const { return s->get_stkvar(p_off); }
2873
2874 /// Get the referenced stack offset.
2875 /// This function can also handle mop_sc if it is entirely mapped into
2876 /// a continuous stack region.
2877 /// \param p_off the output buffer
2878 /// \return success
2879 bool hexapi get_stkoff(sval_t *p_off) const;
2880
2881 //-----------------------------------------------------------------------
2882 // Working with mop_d operands
2883 //-----------------------------------------------------------------------
2884 /// Get subinstruction of the operand.
2885 /// If the operand has a subinstruction with the specified opcode, return it.
2886 /// \param code desired opcode
2887 /// \return pointer to the instruction or nullptr
2888 const minsn_t *get_insn(mcode_t code) const;
2889 minsn_t *get_insn(mcode_t code);
2890
2891 //-----------------------------------------------------------------------
2892 // Transforming operands
2893 //-----------------------------------------------------------------------
2894 /// Make the low part of the operand.
2895 /// This function takes into account the memory endianness (byte sex)
2896 /// \param width the desired size of the operand part in bytes
2897 /// \return success
2898 bool hexapi make_low_half(int width);
2899
2900 /// Make the high part of the operand.
2901 /// This function takes into account the memory endianness (byte sex)
2902 /// \param width the desired size of the operand part in bytes
2903 /// \return success
2904 bool hexapi make_high_half(int width);
2905
2906 /// Make the first part of the operand.
2907 /// This function does not care about the memory endianness
2908 /// \param width the desired size of the operand part in bytes
2909 /// \return success
2910 bool hexapi make_first_half(int width);
2911
2912 /// Make the second part of the operand.
2913 /// This function does not care about the memory endianness
2914 /// \param width the desired size of the operand part in bytes
2915 /// \return success
2916 bool hexapi make_second_half(int width);
2917
2918 /// Shift the operand.
2919 /// This function shifts only the beginning of the operand.
2920 /// The operand size will be changed.
2921 /// Examples: shift_mop(AH.1, -1) -> AX.2
2922 /// shift_mop(qword_00000008.8, 4) -> dword_0000000C.4
2923 /// shift_mop(xdu.8(op.4), 4) -> #0.4
2924 /// shift_mop(#0x12345678.4, 3) -> #12.1
2925 /// \param offset shift count (the number of bytes to shift)
2926 /// \return success
2927 bool hexapi shift_mop(int offset);
2928
2929 /// Change the operand size.
2930 /// Examples: change_size(AL.1, 2) -> AX.2
2931 /// change_size(qword_00000008.8, 4) -> dword_00000008.4
2932 /// change_size(xdu.8(op.4), 4) -> op.4
2933 /// change_size(#0x12345678.4, 1) -> #0x78.1
2934 /// \param nsize new operand size
2935 /// \param sideff may modify the database because of the size change?
2936 /// \return success
2937 bool hexapi change_size(int nsize, side_effect_t sideff=WITH_SIDEFF);
2938 bool double_size(side_effect_t sideff=WITH_SIDEFF) { return change_size(size*2, sideff); }
2939
2940 /// Move subinstructions with side effects out of the operand.
2941 /// If we decide to delete an instruction operand, it is a good idea to
2942 /// call this function. Alternatively we should skip such operands
2943 /// by calling mop_t::has_side_effects()
2944 /// For example, if we transform: jnz x, x, @blk => goto @blk
2945 /// then we must call this function before deleting the X operands.
2946 /// \param blk current block
2947 /// \param top top level instruction that contains our operand
2948 /// \param moved_calls pointer to the boolean that will track if all side
2949 /// effects get handled correctly. must be false initially.
2950 /// \return false failed to preserve a side effect, it is not safe to
2951 /// delete the operand
2952 /// true no side effects or successfully preserved them
2953 bool hexapi preserve_side_effects(
2954 mblock_t *blk,
2955 minsn_t *top,
2956 bool *moved_calls=nullptr);
2957
2958 /// Apply a unary opcode to the operand.
2959 /// \param mcode opcode to apply. it must accept 'l' and 'd' operands
2960 /// but not 'r'. examples: m_low/m_high/m_xds/m_xdu
2961 /// \param ea value of minsn_t::ea for the newly created insruction
2962 /// \param newsize new operand size
2963 /// Example: apply_ld_mcode(m_low) will convert op => low(op)
2964 void hexapi apply_ld_mcode(mcode_t mcode, ea_t ea, int newsize);
2965 void apply_xdu(ea_t ea, int newsize) { apply_ld_mcode(m_xdu, ea, newsize); }
2966 void apply_xds(ea_t ea, int newsize) { apply_ld_mcode(m_xds, ea, newsize); }
2967};
2968DECLARE_TYPE_AS_MOVABLE(mop_t);
2969
2970/// Pair of operands
2972{
2973public:
2974 mop_t lop; ///< low operand
2975 mop_t hop; ///< high operand
2976 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
2977};
2978
2979/// Address of an operand (mop_l, mop_v, mop_S, mop_r)
2980class mop_addr_t : public mop_t
2981{
2982public:
2983 int insize = NOSIZE; // how many bytes of the pointed operand can be read
2984 int outsize = NOSIZE; // how many bytes of the pointed operand can be written
2985
2986 mop_addr_t() {}
2987 mop_addr_t(const mop_addr_t &ra)
2988 : mop_t(ra), insize(ra.insize), outsize(ra.outsize) {}
2989 mop_addr_t(const mop_t &ra, int isz, int osz)
2990 : mop_t(ra), insize(isz), outsize(osz) {}
2991
2992 mop_addr_t &operator=(const mop_addr_t &rop)
2993 {
2994 *(mop_t *)this = mop_t(rop);
2995 insize = rop.insize;
2996 outsize = rop.outsize;
2997 return *this;
2998 }
2999 int lexcompare(const mop_addr_t &ra) const
3000 {
3001 int code = mop_t::lexcompare(ra);
3002 return code != 0 ? code
3003 : insize != ra.insize ? (insize-ra.insize)
3004 : outsize != ra.outsize ? (outsize-ra.outsize)
3005 : 0;
3006 }
3007};
3008
3009/// A call argument
3010class mcallarg_t : public mop_t // #callarg
3011{
3012public:
3013 ea_t ea = BADADDR; ///< address where the argument was initialized.
3014 ///< BADADDR means unknown.
3015 tinfo_t type; ///< formal argument type
3016 qstring name; ///< formal argument name
3017 argloc_t argloc; ///< ida argloc
3018 uint32 flags = 0; ///< FAI_...
3019
3020 mcallarg_t() {}
3021 mcallarg_t(const mop_t &rarg) : mop_t(rarg) {}
3022 void copy_mop(const mop_t &op) { *(mop_t *)this = op; }
3023 void hexapi print(qstring *vout, int shins_flags=SHINS_SHORT|SHINS_VALNUM) const;
3024 const char *hexapi dstr() const;
3025 void hexapi set_regarg(mreg_t mr, int sz, const tinfo_t &tif);
3026 void set_regarg(mreg_t mr, const tinfo_t &tif)
3027 {
3028 set_regarg(mr, tif.get_size(), tif);
3029 }
3030 void set_regarg(mreg_t mr, char dt, type_sign_t sign = type_unsigned)
3031 {
3032 int sz = get_dtype_size(dt);
3033 set_regarg(mr, sz, get_int_type_by_width_and_sign(sz, sign));
3034 }
3035 void make_int(int val, ea_t val_ea, int opno = 0)
3036 {
3037 type = tinfo_t(BTF_INT);
3038 make_number(val, inf_get_cc_size_i(), val_ea, opno);
3039 }
3040 void make_uint(int val, ea_t val_ea, int opno = 0)
3041 {
3042 type = tinfo_t(BTF_UINT);
3043 make_number(val, inf_get_cc_size_i(), val_ea, opno);
3044 }
3045};
3046DECLARE_TYPE_AS_MOVABLE(mcallarg_t);
3047typedef qvector<mcallarg_t> mcallargs_t;
3048
3049/// Function roles.
3050/// They are used to calculate use/def lists and to recognize functions
3051/// without using string comparisons.
3053{
3054 ROLE_UNK, ///< unknown function role
3055 ROLE_EMPTY, ///< empty, does not do anything (maybe spoils regs)
3056 ROLE_MEMSET, ///< memset(void *dst, uchar value, size_t count);
3057 ROLE_MEMSET32, ///< memset32(void *dst, uint32 value, size_t count);
3058 ROLE_MEMSET64, ///< memset64(void *dst, uint64 value, size_t count);
3059 ROLE_MEMCPY, ///< memcpy(void *dst, const void *src, size_t count);
3060 ROLE_STRCPY, ///< strcpy(char *dst, const char *src);
3061 ROLE_STRLEN, ///< strlen(const char *src);
3062 ROLE_STRCAT, ///< strcat(char *dst, const char *src);
3063 ROLE_TAIL, ///< char *tail(const char *str);
3064 ROLE_BUG, ///< BUG() helper macro: never returns, causes exception
3065 ROLE_ALLOCA, ///< alloca() function
3066 ROLE_BSWAP, ///< bswap() function (any size)
3067 ROLE_PRESENT, ///< present() function (used in patterns)
3068 ROLE_CONTAINING_RECORD, ///< CONTAINING_RECORD() macro
3069 ROLE_FASTFAIL, ///< __fastfail()
3070 ROLE_READFLAGS, ///< __readeflags, __readcallersflags
3071 ROLE_IS_MUL_OK, ///< is_mul_ok
3072 ROLE_SATURATED_MUL, ///< saturated_mul
3073 ROLE_BITTEST, ///< [lock] bt
3074 ROLE_BITTESTANDSET, ///< [lock] bts
3075 ROLE_BITTESTANDRESET, ///< [lock] btr
3077 ROLE_VA_ARG, ///< va_arg() macro
3078 ROLE_VA_COPY, ///< va_copy() function
3079 ROLE_VA_START, ///< va_start() function
3080 ROLE_VA_END, ///< va_end() function
3081 ROLE_ROL, ///< rotate left
3082 ROLE_ROR, ///< rotate right
3083 ROLE_CFSUB3, ///< carry flag after subtract with carry
3084 ROLE_OFSUB3, ///< overflow flag after subtract with carry
3085 ROLE_ABS, ///< integer absolute value
3086 ROLE_3WAYCMP0, ///< 3-way compare helper, returns -1/0/1
3087 ROLE_3WAYCMP1, ///< 3-way compare helper, returns 0/1/2
3088 ROLE_WMEMCPY, ///< wchar_t *wmemcpy(wchar_t *dst, const wchar_t *src, size_t n)
3089 ROLE_WMEMSET, ///< wchar_t *wmemset(wchar_t *dst, wchar_t wc, size_t n)
3090 ROLE_WCSCPY, ///< wchar_t *wcscpy(wchar_t *dst, const wchar_t *src);
3091 ROLE_WCSLEN, ///< size_t wcslen(const wchar_t *s)
3092 ROLE_WCSCAT, ///< wchar_t *wcscat(wchar_t *dst, const wchar_t *src)
3093 ROLE_SSE_CMP4, ///< e.g. _mm_cmpgt_ss
3094 ROLE_SSE_CMP8, ///< e.g. _mm_cmpgt_sd
3095};
3096
3097/// \defgroup FUNC_NAME_ Well known function names
3098///@{
3099#define FUNC_NAME_MEMCPY "memcpy"
3100#define FUNC_NAME_WMEMCPY "wmemcpy"
3101#define FUNC_NAME_MEMSET "memset"
3102#define FUNC_NAME_WMEMSET "wmemset"
3103#define FUNC_NAME_MEMSET32 "memset32"
3104#define FUNC_NAME_MEMSET64 "memset64"
3105#define FUNC_NAME_STRCPY "strcpy"
3106#define FUNC_NAME_WCSCPY "wcscpy"
3107#define FUNC_NAME_STRLEN "strlen"
3108#define FUNC_NAME_WCSLEN "wcslen"
3109#define FUNC_NAME_STRCAT "strcat"
3110#define FUNC_NAME_WCSCAT "wcscat"
3111#define FUNC_NAME_TAIL "tail"
3112#define FUNC_NAME_VA_ARG "va_arg"
3113#define FUNC_NAME_EMPTY "$empty"
3114#define FUNC_NAME_PRESENT "$present"
3115#define FUNC_NAME_CONTAINING_RECORD "CONTAINING_RECORD"
3116#define FUNC_NAME_MORESTACK "runtime_morestack"
3117///@}
3118
3119
3120// the default 256 function arguments is too big, we use a lower value
3121#undef MAX_FUNC_ARGS
3122#define MAX_FUNC_ARGS 64
3123
3124/// Information about a call
3125class mcallinfo_t // #callinfo
3126{
3127public:
3128 ea_t callee; ///< address of the called function, if known
3129 int solid_args; ///< number of solid args.
3130 ///< there may be variadic args in addtion
3131 int call_spd = 0; ///< sp value at call insn
3132 int stkargs_top = 0; ///< first offset past stack arguments
3133 cm_t cc = CM_CC_INVALID; ///< calling convention
3134 mcallargs_t args; ///< call arguments
3135 mopvec_t retregs; ///< return register(s) (e.g., AX, AX:DX, etc.)
3136 ///< this vector is built from return_regs
3137 tinfo_t return_type; ///< type of the returned value
3138 argloc_t return_argloc; ///< location of the returned value
3139
3140 mlist_t return_regs; ///< list of values returned by the function
3141 mlist_t spoiled; ///< list of spoiled locations (includes return_regs)
3142 mlist_t pass_regs; ///< passthrough registers: registers that depend on input
3143 ///< values (subset of spoiled)
3144 ivlset_t visible_memory; ///< what memory is visible to the call?
3145 mlist_t dead_regs; ///< registers defined by the function but never used.
3146 ///< upon propagation we do the following:
3147 ///< - dead_regs += return_regs
3148 ///< - retregs.clear() since the call is propagated
3149 int flags = 0; ///< combination of \ref FCI_... bits
3150/// \defgroup FCI_ Call properties
3151///@{
3152#define FCI_PROP 0x001 ///< call has been propagated
3153#define FCI_DEAD 0x002 ///< some return registers were determined dead
3154#define FCI_FINAL 0x004 ///< call type is final, should not be changed
3155#define FCI_NORET 0x008 ///< call does not return
3156#define FCI_PURE 0x010 ///< pure function
3157#define FCI_NOSIDE 0x020 ///< call does not have side effects
3158#define FCI_SPLOK 0x040 ///< spoiled/visible_memory lists have been
3159 ///< optimized. for some functions we can reduce them
3160 ///< as soon as information about the arguments becomes
3161 ///< available. in order not to try optimize them again
3162 ///< we use this bit.
3163#define FCI_HASCALL 0x080 ///< A function is an synthetic helper combined
3164 ///< from several instructions and at least one
3165 ///< of them was a call to a real functions
3166#define FCI_HASFMT 0x100 ///< A variadic function with recognized
3167 ///< printf- or scanf-style format string
3168#define FCI_EXPLOCS 0x400 ///< all arglocs are specified explicitly
3169///@}
3170 funcrole_t role = ROLE_UNK; ///< function role
3171 type_attrs_t fti_attrs; ///< extended function attributes
3172
3173 mcallinfo_t(ea_t _callee=BADADDR, int _sargs=0)
3174 : callee(_callee), solid_args(_sargs)
3175 {
3176 }
3177 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
3178 int hexapi lexcompare(const mcallinfo_t &f) const;
3179 bool hexapi set_type(const tinfo_t &type);
3180 tinfo_t hexapi get_type() const;
3181 bool is_vararg() const { return is_vararg_cc(cc); }
3182 void hexapi print(qstring *vout, int size=-1, int shins_flags=SHINS_SHORT|SHINS_VALNUM) const;
3183 const char *hexapi dstr() const;
3184};
3185
3186/// List of switch cases and targets
3187class mcases_t // #cases
3188{
3189public:
3190 casevec_t values; ///< expression values for each target
3191 intvec_t targets; ///< target block numbers
3192
3193 void swap(mcases_t &r) { values.swap(r.values); targets.swap(r.targets); }
3194 DECLARE_COMPARISONS(mcases_t);
3195 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
3196 bool empty() const { return targets.empty(); }
3197 size_t size() const { return targets.size(); }
3198 void resize(int s) { values.resize(s); targets.resize(s); }
3199 void hexapi print(qstring *vout) const;
3200 const char *hexapi dstr() const;
3201};
3202
3203//-------------------------------------------------------------------------
3204/// Value offset (microregister number or stack offset)
3206{
3207 sval_t off = -1; ///< register number or stack offset
3208 mopt_t type = mop_z; ///< mop_r - register, mop_S - stack, mop_z - undefined
3209
3210 voff_t() {}
3211 voff_t(mopt_t _type, sval_t _off) : off(_off), type(_type) {}
3212 voff_t(const mop_t &op)
3213 {
3214 if ( op.is_reg() || op.t == mop_S )
3215 set(op.t, op.is_reg() ? op.r : op.s->off);
3216 }
3217
3218 void set(mopt_t _type, sval_t _off) { type = _type; off = _off; }
3219 void set_stkoff(sval_t stkoff) { set(mop_S, stkoff); }
3220 void set_reg(mreg_t mreg) { set(mop_r, mreg); }
3221 void undef() { set(mop_z, -1); }
3222
3223 bool defined() const { return type != mop_z; }
3224 bool is_reg() const { return type == mop_r; }
3225 bool is_stkoff() const { return type == mop_S; }
3226 mreg_t get_reg() const { QASSERT(51892, is_reg()); return off; }
3227 sval_t get_stkoff() const { QASSERT(51893, is_stkoff()); return off; }
3228
3229 void inc(sval_t delta) { off += delta; }
3230 voff_t add(int width) const { return voff_t(type, off+width); }
3231 sval_t diff(const voff_t &r) const { QASSERT(51894, type == r.type); return off - r.off; }
3232
3233 DECLARE_COMPARISONS(voff_t)
3234 {
3235 int code = ::compare(type, r.type);
3236 return code != 0 ? code : ::compare(off, r.off);
3237 }
3238};
3239
3240//-------------------------------------------------------------------------
3241/// Value interval (register or stack range)
3243{
3244 int size; ///< Interval size in bytes
3245
3246 vivl_t(mopt_t _type = mop_z, sval_t _off = -1, int _size = 0)
3247 : voff_t(_type, _off), size(_size) {}
3248 vivl_t(const class chain_t &ch);
3249 vivl_t(const mop_t &op) : voff_t(op), size(op.size) {}
3250
3251 // Make a value interval
3252 void set(mopt_t _type, sval_t _off, int _size = 0)
3253 { voff_t::set(_type, _off); size = _size; }
3254 void set(const voff_t &voff, int _size)
3255 { set(voff.type, voff.off, _size); }
3256 void set_stkoff(sval_t stkoff, int sz = 0) { set(mop_S, stkoff, sz); }
3257 void set_reg (mreg_t mreg, int sz = 0) { set(mop_r, mreg, sz); }
3258
3259 /// Extend a value interval using another value interval of the same type
3260 /// \return success
3261 bool hexapi extend_to_cover(const vivl_t &r);
3262
3263 /// Intersect value intervals the same type
3264 /// \return size of the resulting intersection
3265 uval_t hexapi intersect(const vivl_t &r);
3266
3267 /// Do two value intervals overlap?
3268 bool overlap(const vivl_t &r) const
3269 {
3270 return type == r.type
3271 && interval::overlap(off, size, r.off, r.size);
3272 }
3273 /// Does our value interval include another?
3274 bool includes(const vivl_t &r) const
3275 {
3276 return type == r.type
3277 && interval::includes(off, size, r.off, r.size);
3278 }
3279
3280 /// Does our value interval contain the specified value offset?
3281 bool contains(const voff_t &voff2) const
3282 {
3283 return type == voff2.type
3284 && interval::contains(off, size, voff2.off);
3285 }
3286
3287 // Comparisons
3288 DECLARE_COMPARISONS(vivl_t)
3289 {
3290 int code = voff_t::compare(r);
3291 return code; //return code != 0 ? code : ::compare(size, r.size);
3292 }
3293 bool operator==(const mop_t &mop) const
3294 {
3295 return type == mop.t && off == (mop.is_reg() ? mop.r : mop.s->off);
3296 }
3297 void hexapi print(qstring *vout) const;
3298 const char *hexapi dstr() const;
3299};
3300
3301//-------------------------------------------------------------------------
3302/// ud (use->def) and du (def->use) chain.
3303/// We store in chains only the block numbers, not individual instructions
3304/// See https://en.wikipedia.org/wiki/Use-define_chain
3305class chain_t : public intvec_t // sequence of block numbers
3306{
3307 voff_t k; ///< Value offset of the chain.
3308 ///< (what variable is this chain about)
3309
3310public:
3311 int width = 0; ///< size of the value in bytes
3312 int varnum = -1; ///< allocated variable index (-1 - not allocated yet)
3313 uchar flags; ///< combination \ref CHF_ bits
3314/// \defgroup CHF_ Chain properties
3315///@{
3316#define CHF_INITED 0x01 ///< is chain initialized? (valid only after lvar allocation)
3317#define CHF_REPLACED 0x02 ///< chain operands have been replaced?
3318#define CHF_OVER 0x04 ///< overlapped chain
3319#define CHF_FAKE 0x08 ///< fake chain created by widen_chains()
3320#define CHF_PASSTHRU 0x10 ///< pass-thru chain, must use the input variable to the block
3321#define CHF_TERM 0x20 ///< terminating chain; the variable does not survive across the block
3322///@}
3323 chain_t() : flags(CHF_INITED) {}
3324 chain_t(mopt_t t, sval_t off, int w=1, int v=-1)
3325 : k(t, off), width(w), varnum(v), flags(CHF_INITED) {}
3326 chain_t(const voff_t &_k, int w=1)
3327 : k(_k), width(w), varnum(-1), flags(CHF_INITED) {}
3328 void set_value(const chain_t &r)
3329 { width = r.width; varnum = r.varnum; flags = r.flags; *(intvec_t *)this = (intvec_t &)r; }
3330 const voff_t &key() const { return k; }
3331 bool is_inited() const { return (flags & CHF_INITED) != 0; }
3332 bool is_reg() const { return k.is_reg(); }
3333 bool is_stkoff() const { return k.is_stkoff(); }
3334 bool is_replaced() const { return (flags & CHF_REPLACED) != 0; }
3335 bool is_overlapped() const { return (flags & CHF_OVER) != 0; }
3336 bool is_fake() const { return (flags & CHF_FAKE) != 0; }
3337 bool is_passreg() const { return (flags & CHF_PASSTHRU) != 0; }
3338 bool is_term() const { return (flags & CHF_TERM) != 0; }
3339 void set_inited(bool b) { setflag(flags, CHF_INITED, b); }
3340 void set_replaced(bool b) { setflag(flags, CHF_REPLACED, b); }
3341 void set_overlapped(bool b) { setflag(flags, CHF_OVER, b); }
3342 void set_term(bool b) { setflag(flags, CHF_TERM, b); }
3343 mreg_t get_reg() const { return k.get_reg(); }
3344 sval_t get_stkoff() const { return k.get_stkoff(); }
3345 bool overlap(const chain_t &r) const
3346 { return k.type == r.k.type && interval::overlap(k.off, width, r.k.off, r.width); }
3347 bool includes(const chain_t &r) const
3348 { return k.type == r.k.type && interval::includes(k.off, width, r.k.off, r.width); }
3349 const voff_t endoff() const { return k.add(width); }
3350
3351 bool operator<(const chain_t &r) const { return key() < r.key(); }
3352
3353 void hexapi print(qstring *vout) const;
3354 const char *hexapi dstr() const;
3355 /// Append the contents of the chain to the specified list of locations.
3356 void hexapi append_list(const mba_t *mba, mlist_t *list) const;
3357 void clear_varnum() { varnum = -1; set_replaced(false); }
3358};
3359
3360//-------------------------------------------------------------------------
3361#if defined(__NT__)
3362# ifdef _DEBUG
3363# define SIZEOF_BLOCK_CHAINS 32
3364#else
3365# define SIZEOF_BLOCK_CHAINS 24
3366# endif
3367#elif defined(__MAC__)
3368# define SIZEOF_BLOCK_CHAINS 32
3369#else
3370# define SIZEOF_BLOCK_CHAINS 56
3371#endif
3372
3373/// Chains of one block.
3374/// Please note that this class is based on std::set and it must be accessed
3375/// using the block_chains_begin(), block_chains_find() and similar functions.
3376/// This is required because different compilers use different implementations
3377/// of std::set. However, since the size of std::set depends on the compilation
3378/// options, we replace it with a byte array.
3380{
3381 size_t body[SIZEOF_BLOCK_CHAINS/sizeof(size_t)]; // opaque std::set, uncopyable
3382public:
3383 /// Get chain for the specified register
3384 /// \param reg register number
3385 /// \param width size of register in bytes
3386 const chain_t *get_reg_chain(mreg_t reg, int width=1) const
3387 { return get_chain((chain_t(mop_r, reg, width))); }
3388 chain_t *get_reg_chain(mreg_t reg, int width=1)
3389 { return get_chain((chain_t(mop_r, reg, width))); }
3390
3391 /// Get chain for the specified stack offset
3392 /// \param off stack offset
3393 /// \param width size of stack value in bytes
3394 const chain_t *get_stk_chain(sval_t off, int width=1) const
3395 { return get_chain(chain_t(mop_S, off, width)); }
3396 chain_t *get_stk_chain(sval_t off, int width=1)
3397 { return get_chain(chain_t(mop_S, off, width)); }
3398
3399 /// Get chain for the specified value offset.
3400 /// \param k value offset (register number or stack offset)
3401 /// \param width size of value in bytes
3402 const chain_t *get_chain(const voff_t &k, int width=1) const
3403 { return get_chain(chain_t(k, width)); }
3404 chain_t *get_chain(const voff_t &k, int width=1)
3405 { return (chain_t*)((const block_chains_t *)this)->get_chain(k, width); }
3406
3407 /// Get chain similar to the specified chain
3408 /// \param ch chain to search for. only its 'k' and 'width' are used.
3409 const chain_t *hexapi get_chain(const chain_t &ch) const;
3410 chain_t *get_chain(const chain_t &ch)
3411 { return (chain_t*)((const block_chains_t *)this)->get_chain(ch); }
3412
3413 void hexapi print(qstring *vout) const;
3414 const char *hexapi dstr() const;
3415 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
3416};
3417//-------------------------------------------------------------------------
3418/// Chain visitor class
3420{
3421 block_chains_t *parent = nullptr; ///< parent of the current chain
3422 virtual int idaapi visit_chain(int nblock, chain_t &ch) = 0;
3423};
3424
3425//-------------------------------------------------------------------------
3426/// Graph chains.
3427/// This class represents all ud and du chains of the decompiled function
3428typedef qvector<block_chains_t> block_chains_vec_t;
3430{
3431 int lock = 0; ///< are chained locked? (in-use)
3432public:
3433 ~graph_chains_t() { QASSERT(50444, !lock); }
3434 /// Visit all chains
3435 /// \param cv chain visitor
3436 /// \param gca_flags combination of GCA_ bits
3437 int hexapi for_all_chains(chain_visitor_t &cv, int gca_flags);
3438 /// \defgroup GCA_ chain visitor flags
3439 //@{
3440#define GCA_EMPTY 0x01 ///< include empty chains
3441#define GCA_SPEC 0x02 ///< include chains for special registers
3442#define GCA_ALLOC 0x04 ///< enumerate only allocated chains
3443#define GCA_NALLOC 0x08 ///< enumerate only non-allocated chains
3444#define GCA_OFIRST 0x10 ///< consider only chains of the first block
3445#define GCA_OLAST 0x20 ///< consider only chains of the last block
3446 //@}
3447 /// Are the chains locked?
3448 /// It is a good idea to lock the chains before using them. This ensures
3449 /// that they won't be recalculated and reallocated during the use.
3450 /// See the \ref chain_keeper_t class for that.
3451 bool is_locked() const { return lock != 0; }
3452 /// Lock the chains
3453 void acquire() { lock++; }
3454 /// Unlock the chains
3455 void hexapi release();
3456 void swap(graph_chains_t &r)
3457 {
3458 qvector<block_chains_t>::swap(r);
3459 std::swap(lock, r.lock);
3460 }
3461};
3462//-------------------------------------------------------------------------
3463/// Microinstruction class #insn
3465{
3466 void hexapi init(ea_t _ea);
3467 void hexapi copy(const minsn_t &m);
3468public:
3469 mcode_t opcode; ///< instruction opcode
3470 int iprops; ///< combination of \ref IPROP_ bits
3471 minsn_t *next; ///< next insn in doubly linked list. check also nexti()
3472 minsn_t *prev; ///< prev insn in doubly linked list. check also previ()
3473 ea_t ea; ///< instruction address
3474 mop_t l; ///< left operand
3475 mop_t r; ///< right operand
3476 mop_t d; ///< destination operand
3477
3478 /// \defgroup IPROP_ instruction property bits
3479 //@{
3480 // bits to be used in patterns:
3481#define IPROP_OPTIONAL 0x0001 ///< optional instruction
3482#define IPROP_PERSIST 0x0002 ///< persistent insn; they are not destroyed
3483#define IPROP_WILDMATCH 0x0004 ///< match multiple insns
3484
3485 // instruction attributes:
3486#define IPROP_CLNPOP 0x0008 ///< the purpose of the instruction is to clean stack
3487 ///< (e.g. "pop ecx" is often used for that)
3488#define IPROP_FPINSN 0x0010 ///< floating point insn
3489#define IPROP_FARCALL 0x0020 ///< call of a far function using push cs/call sequence
3490#define IPROP_TAILCALL 0x0040 ///< tail call
3491#define IPROP_ASSERT 0x0080 ///< assertion: usually mov #val, op.
3492 ///< assertions are used to help the optimizer.
3493 ///< assertions are ignored when generating ctree
3494
3495 // instruction history:
3496#define IPROP_SPLIT 0x0700 ///< the instruction has been split:
3497#define IPROP_SPLIT1 0x0100 ///< into 1 byte
3498#define IPROP_SPLIT2 0x0200 ///< into 2 bytes
3499#define IPROP_SPLIT4 0x0300 ///< into 4 bytes
3500#define IPROP_SPLIT8 0x0400 ///< into 8 bytes
3501#define IPROP_COMBINED 0x0800 ///< insn has been modified because of a partial reference
3502#define IPROP_EXTSTX 0x1000 ///< this is m_ext propagated into m_stx
3503#define IPROP_IGNLOWSRC 0x2000 ///< low part of the instruction source operand
3504 ///< has been created artificially
3505 ///< (this bit is used only for 'and x, 80...')
3506#define IPROP_INV_JX 0x4000 ///< inverted conditional jump
3507#define IPROP_WAS_NORET 0x8000 ///< was noret icall
3508#define IPROP_MULTI_MOV 0x10000 ///< the minsn was generated as part of insn that moves multiple registers
3509 ///< (example: STM on ARM may transfer multiple registers)
3510
3511 ///< bits that can be set by plugins:
3512#define IPROP_DONT_PROP 0x20000 ///< may not propagate
3513#define IPROP_DONT_COMB 0x40000 ///< may not combine this instruction with others
3514#define IPROP_MBARRIER 0x80000 ///< this instruction acts as a memory barrier
3515 ///< (instructions accessing memory may not be reordered past it)
3516#define IPROP_UNMERGED 0x100000 ///< 'goto' instruction was transformed info 'call'
3517 //@}
3518
3519 bool is_optional() const { return (iprops & IPROP_OPTIONAL) != 0; }
3520 bool is_combined() const { return (iprops & IPROP_COMBINED) != 0; }
3521 bool is_farcall() const { return (iprops & IPROP_FARCALL) != 0; }
3522 bool is_cleaning_pop() const { return (iprops & IPROP_CLNPOP) != 0; }
3523 bool is_extstx() const { return (iprops & IPROP_EXTSTX) != 0; }
3524 bool is_tailcall() const { return (iprops & IPROP_TAILCALL) != 0; }
3525 bool is_fpinsn() const { return (iprops & IPROP_FPINSN) != 0; }
3526 bool is_assert() const { return (iprops & IPROP_ASSERT) != 0; }
3527 bool is_persistent() const { return (iprops & IPROP_PERSIST) != 0; }
3528 bool is_wild_match() const { return (iprops & IPROP_WILDMATCH) != 0; }
3529 bool is_propagatable() const { return (iprops & IPROP_DONT_PROP) == 0; }
3530 bool is_ignlowsrc() const { return (iprops & IPROP_IGNLOWSRC) != 0; }
3531 bool is_inverted_jx() const { return (iprops & IPROP_INV_JX) != 0; }
3532 bool was_noret_icall() const { return (iprops & IPROP_WAS_NORET) != 0; }
3533 bool is_multimov() const { return (iprops & IPROP_MULTI_MOV) != 0; }
3534 bool is_combinable() const { return (iprops & IPROP_DONT_COMB) == 0; }
3535 bool was_split() const { return (iprops & IPROP_SPLIT) != 0; }
3536 bool is_mbarrier() const { return (iprops & IPROP_MBARRIER) != 0; }
3537 bool was_unmerged() const { return (iprops & IPROP_UNMERGED) != 0; }
3538
3539 void set_optional() { iprops |= IPROP_OPTIONAL; }
3540 void hexapi set_combined();
3541 void clr_combined() { iprops &= ~IPROP_COMBINED; }
3542 void set_farcall() { iprops |= IPROP_FARCALL; }
3543 void set_cleaning_pop() { iprops |= IPROP_CLNPOP; }
3544 void set_extstx() { iprops |= IPROP_EXTSTX; }
3545 void set_tailcall() { iprops |= IPROP_TAILCALL; }
3546 void clr_tailcall() { iprops &= ~IPROP_TAILCALL; }
3547 void set_fpinsn() { iprops |= IPROP_FPINSN; }
3548 void clr_fpinsn() { iprops &= ~IPROP_FPINSN; }
3549 void set_assert() { iprops |= IPROP_ASSERT; }
3550 void clr_assert() { iprops &= ~IPROP_ASSERT; }
3551 void set_persistent() { iprops |= IPROP_PERSIST; }
3552 void set_wild_match() { iprops |= IPROP_WILDMATCH; }
3553 void clr_propagatable() { iprops |= IPROP_DONT_PROP; }
3554 void set_ignlowsrc() { iprops |= IPROP_IGNLOWSRC; }
3555 void clr_ignlowsrc() { iprops &= ~IPROP_IGNLOWSRC; }
3556 void set_inverted_jx() { iprops |= IPROP_INV_JX; }
3557 void set_noret_icall() { iprops |= IPROP_WAS_NORET; }
3558 void clr_noret_icall() { iprops &= ~IPROP_WAS_NORET; }
3559 void set_multimov() { iprops |= IPROP_MULTI_MOV; }
3560 void clr_multimov() { iprops &= ~IPROP_MULTI_MOV; }
3561 void set_combinable() { iprops &= ~IPROP_DONT_COMB; }
3562 void clr_combinable() { iprops |= IPROP_DONT_COMB; }
3563 void set_mbarrier() { iprops |= IPROP_MBARRIER; }
3564 void set_unmerged() { iprops |= IPROP_UNMERGED; }
3565 void set_split_size(int s)
3566 { // s may be only 1,2,4,8. other values are ignored
3567 iprops &= ~IPROP_SPLIT;
3568 iprops |= (s == 1 ? IPROP_SPLIT1
3569 : s == 2 ? IPROP_SPLIT2
3570 : s == 4 ? IPROP_SPLIT4
3571 : s == 8 ? IPROP_SPLIT8 : 0);
3572 }
3573 int get_split_size() const
3574 {
3575 int cnt = (iprops & IPROP_SPLIT) >> 8;
3576 return cnt == 0 ? 0 : 1 << (cnt-1);
3577 }
3578
3579 /// Constructor
3580 minsn_t(ea_t _ea) { init(_ea); }
3581 minsn_t(const minsn_t &m) { next = prev = nullptr; copy(m); } //-V1077 uninitialized: opcode, iprops, ea
3582 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
3583
3584 /// Assignment operator. It does not copy prev/next fields.
3585 minsn_t &operator=(const minsn_t &m) { copy(m); return *this; }
3586
3587 /// Swap two instructions.
3588 /// The prev/next fields are not modified by this function
3589 /// because it would corrupt the doubly linked list.
3590 void hexapi swap(minsn_t &m);
3591
3592 /// Generate insn text into the buffer
3593 void hexapi print(qstring *vout, int shins_flags=SHINS_SHORT|SHINS_VALNUM) const;
3594
3595 /// Get displayable text without tags in a static buffer
3596 const char *hexapi dstr() const;
3597
3598 /// Change the instruction address.
3599 /// This function modifies subinstructions as well.
3600 void hexapi setaddr(ea_t new_ea);
3601
3602 /// Optimize one instruction without context.
3603 /// This function does not have access to the instruction context (the
3604 /// previous and next instructions in the list, the block number, etc).
3605 /// It performs only basic optimizations that are available without this info.
3606 /// \param optflags combination of \ref OPTI_ bits
3607 /// \return number of changes, 0-unchanged
3608 /// See also mblock_t::optimize_insn()
3609 int optimize_solo(int optflags=0) { return optimize_subtree(nullptr, nullptr, nullptr, nullptr, optflags); }
3610 /// \defgroup OPTI_ optimization flags
3611 //@{
3612#define OPTI_ADDREXPRS 0x0001 ///< optimize all address expressions (&x+N; &x-&y)
3613#define OPTI_MINSTKREF 0x0002 ///< may update minstkref
3614#define OPTI_COMBINSNS 0x0004 ///< may combine insns (only for optimize_insn)
3615#define OPTI_NO_LDXOPT 0x0008 ///< the function is called after the
3616 ///< propagation attempt, we do not optimize
3617 ///< low/high(ldx) in this case
3618 //@}
3619
3620 /// Optimize instruction in its context.
3621 /// Do not use this function, use mblock_t::optimize()
3622 int hexapi optimize_subtree(
3623 mblock_t *blk,
3624 minsn_t *top,
3625 minsn_t *parent,
3626 ea_t *converted_call,
3627 int optflags=OPTI_MINSTKREF);
3628
3629 /// Visit all instruction operands.
3630 /// This function visits subinstruction operands as well.
3631 /// \param mv operand visitor
3632 /// \return non-zero value returned by mv.visit_mop() or zero
3633 int hexapi for_all_ops(mop_visitor_t &mv);
3634
3635 /// Visit all instructions.
3636 /// This function visits the instruction itself and all its subinstructions.
3637 /// \param mv instruction visitor
3638 /// \return non-zero value returned by mv.visit_mop() or zero
3639 int hexapi for_all_insns(minsn_visitor_t &mv);
3640
3641 /// Convert instruction to nop.
3642 /// This function erases all info but the prev/next fields.
3643 /// In most cases it is better to use mblock_t::make_nop(), which also
3644 /// marks the block lists as dirty.
3645 void hexapi _make_nop();
3646
3647 /// Compare instructions.
3648 /// This is the main comparison function for instructions.
3649 /// \param m instruction to compare with
3650 /// \param eqflags combination of \ref EQ_ bits
3651 bool hexapi equal_insns(const minsn_t &m, int eqflags) const; // intelligent comparison
3652 /// \defgroup EQ_ comparison bits
3653 //@{
3654#define EQ_IGNSIZE 0x0001 ///< ignore source operand sizes
3655#define EQ_IGNCODE 0x0002 ///< ignore instruction opcodes
3656#define EQ_CMPDEST 0x0004 ///< compare instruction destinations
3657#define EQ_OPTINSN 0x0008 ///< optimize mop_d operands
3658 //@}
3659
3660 /// Lexographical comparison
3661 /// It can be used to store minsn_t in various containers, like std::set
3662 bool operator <(const minsn_t &ri) const { return lexcompare(ri) < 0; }
3663 int hexapi lexcompare(const minsn_t &ri) const;
3664
3665 //-----------------------------------------------------------------------
3666 // Call instructions
3667 //-----------------------------------------------------------------------
3668 /// Is a non-returing call?
3669 /// \param flags combination of NORET_... bits
3670 bool hexapi is_noret_call(int flags=0);
3671#define NORET_IGNORE_WAS_NORET_ICALL 0x01 // ignore was_noret_icall() bit
3672#define NORET_FORBID_ANALYSIS 0x02 // forbid additional analysis
3673
3674 /// Is an unknown call?
3675 /// Unknown calls are calls without the argument list (mcallinfo_t).
3676 /// Usually the argument lists are determined by mba_t::analyze_calls().
3677 /// Unknown calls exist until the MMAT_CALLS maturity level.
3678 /// See also \ref mblock_t::is_call_block
3679 bool is_unknown_call() const { return is_mcode_call(opcode) && d.empty(); }
3680
3681 /// Is a helper call with the specified name?
3682 /// Helper calls usually have well-known function names (see \ref FUNC_NAME_)
3683 /// but they may have any other name. The decompiler does not assume any
3684 /// special meaning for non-well-known names.
3685 bool hexapi is_helper(const char *name) const;
3686
3687 /// Find a call instruction.
3688 /// Check for the current instruction and its subinstructions.
3689 /// \param with_helpers consider helper calls as well?
3690 minsn_t *hexapi find_call(bool with_helpers=false) const;
3691
3692 /// Does the instruction contain a call?
3693 bool contains_call(bool with_helpers=false) const { return find_call(with_helpers) != nullptr; }
3694
3695 /// Does the instruction have a side effect?
3696 /// \param include_ldx_and_divs consider ldx/div/mod as having side effects?
3697 /// stx is always considered as having side effects.
3698 /// Apart from ldx/std only call may have side effects.
3699 bool hexapi has_side_effects(bool include_ldx_and_divs=false) const;
3700
3701 /// Get the function role of a call
3702 funcrole_t get_role() const { return d.is_arglist() ? d.f->role : ROLE_UNK; }
3703 bool is_memcpy() const { return get_role() == ROLE_MEMCPY; }
3704 bool is_memset() const { return get_role() == ROLE_MEMSET; }
3705 bool is_alloca() const { return get_role() == ROLE_ALLOCA; }
3706 bool is_bswap () const { return get_role() == ROLE_BSWAP; }
3707 bool is_readflags () const { return get_role() == ROLE_READFLAGS; }
3708
3709 //-----------------------------------------------------------------------
3710 // Misc
3711 //-----------------------------------------------------------------------
3712 /// Does the instruction have the specified opcode?
3713 /// This function searches subinstructions as well.
3714 /// \param mcode opcode to search for.
3715 bool contains_opcode(mcode_t mcode) const { return find_opcode(mcode) != nullptr; }
3716
3717 /// Find a (sub)insruction with the specified opcode.
3718 /// \param mcode opcode to search for.
3719 const minsn_t *find_opcode(mcode_t mcode) const { return (CONST_CAST(minsn_t*)(this))->find_opcode(mcode); }
3720 minsn_t *hexapi find_opcode(mcode_t mcode);
3721
3722 /// Find an operand that is a subinsruction with the specified opcode.
3723 /// This function checks only the 'l' and 'r' operands of the current insn.
3724 /// \param[out] other pointer to the other operand
3725 /// (&r if we return &l and vice versa)
3726 /// \param op opcode to search for
3727 /// \return &l or &r or nullptr
3728 const minsn_t *hexapi find_ins_op(const mop_t **other, mcode_t op=m_nop) const;
3729 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)); }
3730
3731 /// Find a numeric operand of the current instruction.
3732 /// This function checks only the 'l' and 'r' operands of the current insn.
3733 /// \param[out] other pointer to the other operand
3734 /// (&r if we return &l and vice versa)
3735 /// \return &l or &r or nullptr
3736 const mop_t *hexapi find_num_op(const mop_t **other) const;
3737 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)); }
3738
3739 bool is_mov() const { return opcode == m_mov || (opcode == m_f2f && l.size == d.size); }
3740 bool is_like_move() const { return is_mov() || is_mcode_xdsu(opcode) || opcode == m_low; }
3741
3742 /// Does the instruction modify its 'd' operand?
3743 /// Some instructions (e.g. m_stx) do not modify the 'd' operand.
3744 bool hexapi modifies_d() const;
3745 bool modifies_pair_mop() const { return d.t == mop_p && modifies_d(); }
3746
3747 /// Is the instruction in the specified range of instructions?
3748 /// \param m1 beginning of the range in the doubly linked list
3749 /// \param m2 end of the range in the doubly linked list (excluded, may be nullptr)
3750 /// This function assumes that m1 and m2 belong to the same basic block
3751 /// and they are top level instructions.
3752 bool hexapi is_between(const minsn_t *m1, const minsn_t *m2) const;
3753
3754 /// Is the instruction after the specified one?
3755 /// \param m the instruction to compare against in the list
3756 bool is_after(const minsn_t *m) const { return m != nullptr && is_between(m->next, nullptr); }
3757
3758 /// Is it possible for the instruction to use aliased memory?
3759 bool hexapi may_use_aliased_memory() const;
3760
3761 /// Serialize an instruction
3762 /// \param b the output buffer
3763 /// \return the serialization format that was used to store info
3764 int hexapi serialize(bytevec_t *b) const;
3765
3766 /// Deserialize an instruction
3767 /// \param bytes pointer to serialized data
3768 /// \param nbytes number of bytes to deserialize
3769 /// \param format_version serialization format version. this value is returned by minsn_t::serialize()
3770 /// \return success
3771 bool hexapi deserialize(const uchar *bytes, size_t nbytes, int format_version);
3772
3773};
3774
3775/// Skip assertions forward
3776const minsn_t *hexapi getf_reginsn(const minsn_t *ins);
3777/// Skip assertions backward
3778const minsn_t *hexapi getb_reginsn(const minsn_t *ins);
3779inline minsn_t *getf_reginsn(minsn_t *ins) { return CONST_CAST(minsn_t*)(getf_reginsn(CONST_CAST(const minsn_t *)(ins))); }
3780inline minsn_t *getb_reginsn(minsn_t *ins) { return CONST_CAST(minsn_t*)(getb_reginsn(CONST_CAST(const minsn_t *)(ins))); }
3781
3782//-------------------------------------------------------------------------
3783/// Basic block types
3785{
3786 BLT_NONE = 0, ///< unknown block type
3787 BLT_STOP = 1, ///< stops execution regularly (must be the last block)
3788 BLT_0WAY = 2, ///< does not have successors (tail is a noret function)
3789 BLT_1WAY = 3, ///< passes execution to one block (regular or goto block)
3790 BLT_2WAY = 4, ///< passes execution to two blocks (conditional jump)
3791 BLT_NWAY = 5, ///< passes execution to many blocks (switch idiom)
3792 BLT_XTRN = 6, ///< external block (out of function address)
3793};
3794
3795// Maximal bit range
3796#define MAXRANGE bitrange_t(0, USHRT_MAX)
3797
3798//-------------------------------------------------------------------------
3799/// Microcode of one basic block.
3800/// All blocks are part of a doubly linked list. They can also be addressed
3801/// by indexing the mba->natural array. A block contains a doubly linked list
3802/// of instructions, various location lists that are used for data flow
3803/// analysis, and other attributes.
3805{
3806 friend class codegen_t;
3807 DECLARE_UNCOPYABLE(mblock_t)
3808 void hexapi init();
3809public:
3810 mblock_t *nextb; ///< next block in the doubly linked list
3811 mblock_t *prevb; ///< previous block in the doubly linked list
3812 uint32 flags; ///< combination of \ref MBL_ bits
3813 /// \defgroup MBL_ Basic block properties
3814 //@{
3815#define MBL_PRIV 0x0001 ///< private block - no instructions except
3816 ///< the specified are accepted (used in patterns)
3817#define MBL_NONFAKE 0x0000 ///< regular block
3818#define MBL_FAKE 0x0002 ///< fake block
3819#define MBL_GOTO 0x0004 ///< this block is a goto target
3820#define MBL_TCAL 0x0008 ///< aritifical call block for tail calls
3821#define MBL_PUSH 0x0010 ///< needs "convert push/pop instructions"
3822#define MBL_DMT64 0x0020 ///< needs "demote 64bits"
3823#define MBL_COMB 0x0040 ///< needs "combine" pass
3824#define MBL_PROP 0x0080 ///< needs 'propagation' pass
3825#define MBL_DEAD 0x0100 ///< needs "eliminate deads" pass
3826#define MBL_LIST 0x0200 ///< use/def lists are ready (not dirty)
3827#define MBL_INCONST 0x0400 ///< inconsistent lists: we are building them
3828#define MBL_CALL 0x0800 ///< call information has been built
3829#define MBL_BACKPROP 0x1000 ///< performed backprop_cc
3830#define MBL_NORET 0x2000 ///< dead end block: doesn't return execution control
3831#define MBL_DSLOT 0x4000 ///< block for delay slot
3832#define MBL_VALRANGES 0x8000 ///< should optimize using value ranges
3833#define MBL_KEEP 0x10000 ///< do not remove even if unreachable
3834 //@}
3835 ea_t start; ///< start address
3836 ea_t end; ///< end address
3837 ///< note: we cannot rely on start/end addresses
3838 ///< very much because instructions are
3839 ///< propagated between blocks
3840 minsn_t *head; ///< pointer to the first instruction of the block
3841 minsn_t *tail; ///< pointer to the last instruction of the block
3842 mba_t *mba; ///< the parent micro block array
3843 int serial; ///< block number
3844 mblock_type_t type; ///< block type (BLT_NONE - not computed yet)
3845
3846 mlist_t dead_at_start; ///< data that is dead at the block entry
3847 mlist_t mustbuse; ///< data that must be used by the block
3848 mlist_t maybuse; ///< data that may be used by the block
3849 mlist_t mustbdef; ///< data that must be defined by the block
3850 mlist_t maybdef; ///< data that may be defined by the block
3851 mlist_t dnu; ///< data that is defined but not used in the block
3852
3853 sval_t maxbsp; ///< maximal sp value in the block (0...stacksize)
3854 sval_t minbstkref; ///< lowest stack location accessible with indirect
3855 ///< addressing (offset from the stack bottom)
3856 ///< initially it is 0 (not computed)
3857 sval_t minbargref; ///< the same for arguments
3858
3859 intvec_t predset; ///< control flow graph: list of our predecessors
3860 ///< use npred() and pred() to access it
3861 intvec_t succset; ///< control flow graph: list of our successors
3862 ///< use nsucc() and succ() to access it
3863
3864 // the exact size of this class is not documented, there may be more fields
3865 char reserved[];
3866
3867 void mark_lists_dirty() { flags &= ~MBL_LIST; request_propagation(); }
3868 void request_propagation() { flags |= MBL_PROP; }
3869 bool needs_propagation() const { return (flags & MBL_PROP) != 0; }
3870 void request_demote64() { flags |= MBL_DMT64; }
3871 bool lists_dirty() const { return (flags & MBL_LIST) == 0; }
3872 bool lists_ready() const { return (flags & (MBL_LIST|MBL_INCONST)) == MBL_LIST; }
3873 int make_lists_ready() // returns number of changes
3874 {
3875 if ( lists_ready() )
3876 return 0;
3877 return build_lists(false);
3878 }
3879
3880 /// Get number of block predecessors
3881 int npred() const { return predset.size(); } // number of xrefs to the block
3882 /// Get number of block successors
3883 int nsucc() const { return succset.size(); } // number of xrefs from the block
3884 // Get predecessor number N
3885 int pred(int n) const { return predset[n]; }
3886 // Get successor number N
3887 int succ(int n) const { return succset[n]; }
3888
3889 mblock_t() = delete;
3890 virtual ~mblock_t();
3891 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
3892 bool empty() const { return head == nullptr; }
3893
3894 /// Print block contents.
3895 /// \param vp print helpers class. it can be used to direct the printed
3896 /// info to any destination
3897 void hexapi print(vd_printer_t &vp) const;
3898
3899 /// Dump block info.
3900 /// This function is useful for debugging, see mba_t::dump for info
3901 void hexapi dump() const;
3902 AS_PRINTF(2, 0) void hexapi vdump_block(const char *title, va_list va) const;
3903 AS_PRINTF(2, 3) void dump_block(const char *title, ...) const
3904 {
3905 va_list va;
3906 va_start(va, title);
3907 vdump_block(title, va);
3908 va_end(va);
3909 }
3910
3911 //-----------------------------------------------------------------------
3912 // Functions to insert/remove insns during the microcode optimization phase.
3913 // See codegen_t, microcode_filter_t, udcall_t classes for the initial
3914 // microcode generation.
3915 //-----------------------------------------------------------------------
3916 /// Insert instruction into the doubly linked list
3917 /// \param nm new instruction
3918 /// \param om existing instruction, part of the doubly linked list
3919 /// if nullptr, then the instruction will be inserted at the beginning
3920 /// of the list
3921 /// NM will be inserted immediately after OM
3922 /// \return pointer to NM
3923 minsn_t *hexapi insert_into_block(minsn_t *nm, minsn_t *om);
3924
3925 /// Remove instruction from the doubly linked list
3926 /// \param m instruction to remove
3927 /// The removed instruction is not deleted, the caller gets its ownership
3928 /// \return pointer to the next instruction
3929 minsn_t *hexapi remove_from_block(minsn_t *m);
3930
3931 //-----------------------------------------------------------------------
3932 // Iterator over instructions and operands
3933 //-----------------------------------------------------------------------
3934 /// Visit all instructions.
3935 /// This function visits subinstructions too.
3936 /// \param mv instruction visitor
3937 /// \return zero or the value returned by mv.visit_insn()
3938 /// See also mba_t::for_all_topinsns()
3939 int hexapi for_all_insns(minsn_visitor_t &mv);
3940
3941 /// Visit all operands.
3942 /// This function visit subinstruction operands too.
3943 /// \param mv operand visitor
3944 /// \return zero or the value returned by mv.visit_mop()
3945 int hexapi for_all_ops(mop_visitor_t &mv);
3946
3947 /// Visit all operands that use LIST.
3948 /// \param list ptr to the list of locations. it may be modified:
3949 /// parts that get redefined by the instructions in [i1,i2)
3950 /// will be deleted.
3951 /// \param i1 starting instruction. must be a top level insn.
3952 /// \param i2 ending instruction (excluded). must be a top level insn.
3953 /// \param mmv operand visitor
3954 /// \return zero or the value returned by mmv.visit_mop()
3955 int hexapi for_all_uses(
3956 mlist_t *list,
3957 minsn_t *i1,
3958 minsn_t *i2,
3959 mlist_mop_visitor_t &mmv);
3960
3961 //-----------------------------------------------------------------------
3962 // Optimization functions
3963 //-----------------------------------------------------------------------
3964 /// Optimize one instruction in the context of the block.
3965 /// \param m pointer to a top level instruction
3966 /// \param optflags combination of \ref OPTI_ bits
3967 /// \return number of changes made to the block
3968 /// This function may change other instructions in the block too.
3969 /// However, it will not destroy top level instructions (it may convert them
3970 /// to nop's). This function performs only intrablock modifications.
3971 /// See also minsn_t::optimize_solo()
3972 int hexapi optimize_insn(minsn_t *m, int optflags=OPTI_MINSTKREF|OPTI_COMBINSNS);
3973
3974 /// Optimize a basic block.
3975 /// Usually there is no need to call this function explicitly because the
3976 /// decompiler will call it itself if optinsn_t::func or optblock_t::func
3977 /// return non-zero.
3978 /// \return number of changes made to the block
3979 int hexapi optimize_block();
3980
3981 /// Build def-use lists and eliminate deads.
3982 /// \param kill_deads do delete dead instructions?
3983 /// \return the number of eliminated instructions
3984 /// Better mblock_t::call make_lists_ready() rather than this function.
3985 int hexapi build_lists(bool kill_deads);
3986
3987 /// Remove a jump at the end of the block if it is useless.
3988 /// This function preserves any side effects when removing a useless jump.
3989 /// Both conditional and unconditional jumps are handled (and jtbl too).
3990 /// This function deletes useless jumps, not only replaces them with a nop.
3991 /// (please note that \optimize_insn does not handle useless jumps).
3992 /// \return number of changes made to the block
3993 int hexapi optimize_useless_jump();
3994
3995 //-----------------------------------------------------------------------
3996 // Functions that build with use/def lists. These lists are used to
3997 // reprsent list of registers and stack locations that are either modified
3998 // or accessed by microinstructions.
3999 //-----------------------------------------------------------------------
4000 /// Append use-list of an operand.
4001 /// This function calculates list of locations that may or must be used
4002 /// by the operand and appends it to LIST.
4003 /// \param list ptr to the output buffer. we will append to it.
4004 /// \param op operand to calculate the use list of
4005 /// \param maymust should we calculate 'may-use' or 'must-use' list?
4006 /// see \ref maymust_t for more details.
4007 /// \param mask if only part of the operand should be considered,
4008 /// a bitmask can be used to specify which part.
4009 /// example: op=AX,mask=0xFF means that we will consider only AL.
4010 void hexapi append_use_list(
4011 mlist_t *list,
4012 const mop_t &op,
4013 maymust_t maymust,
4014 bitrange_t mask=MAXRANGE) const;
4015
4016 /// Append def-list of an operand.
4017 /// This function calculates list of locations that may or must be modified
4018 /// by the operand and appends it to LIST.
4019 /// \param list ptr to the output buffer. we will append to it.
4020 /// \param op operand to calculate the def list of
4021 /// \param maymust should we calculate 'may-def' or 'must-def' list?
4022 /// see \ref maymust_t for more details.
4023 void hexapi append_def_list(
4024 mlist_t *list,
4025 const mop_t &op,
4026 maymust_t maymust) const;
4027
4028 /// Build use-list of an instruction.
4029 /// This function calculates list of locations that may or must be used
4030 /// by the instruction. Examples:
4031 /// "ldx ds.2, eax.4, ebx.4", may-list: all aliasable memory
4032 /// "ldx ds.2, eax.4, ebx.4", must-list: empty
4033 /// Since LDX uses EAX for indirect access, it may access any aliasable
4034 /// memory. On the other hand, we cannot tell for sure which memory cells
4035 /// will be accessed, this is why the must-list is empty.
4036 /// \param ins instruction to calculate the use list of
4037 /// \param maymust should we calculate 'may-use' or 'must-use' list?
4038 /// see \ref maymust_t for more details.
4039 /// \return the calculated use-list
4040 mlist_t hexapi build_use_list(const minsn_t &ins, maymust_t maymust) const;
4041
4042 /// Build def-list of an instruction.
4043 /// This function calculates list of locations that may or must be modified
4044 /// by the instruction. Examples:
4045 /// "stx ebx.4, ds.2, eax.4", may-list: all aliasable memory
4046 /// "stx ebx.4, ds.2, eax.4", must-list: empty
4047 /// Since STX uses EAX for indirect access, it may modify any aliasable
4048 /// memory. On the other hand, we cannot tell for sure which memory cells
4049 /// will be modified, this is why the must-list is empty.
4050 /// \param ins instruction to calculate the def list of
4051 /// \param maymust should we calculate 'may-def' or 'must-def' list?
4052 /// see \ref maymust_t for more details.
4053 /// \return the calculated def-list
4054 mlist_t hexapi build_def_list(const minsn_t &ins, maymust_t maymust) const;
4055
4056 //-----------------------------------------------------------------------
4057 // The use/def lists can be used to search for interesting instructions
4058 //-----------------------------------------------------------------------
4059 /// Is the list used by the specified instruction range?
4060 /// \param list list of locations. LIST may be modified by the function:
4061 /// redefined locations will be removed from it.
4062 /// \param i1 starting instruction of the range (must be a top level insn)
4063 /// \param i2 end instruction of the range (must be a top level insn)
4064 /// i2 is excluded from the range. it can be specified as nullptr.
4065 /// i1 and i2 must belong to the same block.
4066 /// \param maymust should we search in 'may-access' or 'must-access' mode?
4067 bool is_used(mlist_t *list, const minsn_t *i1, const minsn_t *i2, maymust_t maymust=MAY_ACCESS) const
4068 { return find_first_use(list, i1, i2, maymust) != nullptr; }
4069
4070 /// Find the first insn that uses the specified list in the insn range.
4071 /// \param list list of locations. LIST may be modified by the function:
4072 /// redefined locations will be removed from it.
4073 /// \param i1 starting instruction of the range (must be a top level insn)
4074 /// \param i2 end instruction of the range (must be a top level insn)
4075 /// i2 is excluded from the range. it can be specified as nullptr.
4076 /// i1 and i2 must belong to the same block.
4077 /// \param maymust should we search in 'may-access' or 'must-access' mode?
4078 /// \return pointer to such instruction or nullptr.
4079 /// Upon return LIST will contain only locations not redefined
4080 /// by insns [i1..result]
4081 const minsn_t *hexapi find_first_use(mlist_t *list, const minsn_t *i1, const minsn_t *i2, maymust_t maymust=MAY_ACCESS) const;
4082 minsn_t *find_first_use(mlist_t *list, minsn_t *i1, const minsn_t *i2, maymust_t maymust=MAY_ACCESS) const
4083 {
4084 return CONST_CAST(minsn_t*)(find_first_use(list,
4085 CONST_CAST(const minsn_t*)(i1),
4086 i2,
4087 maymust));
4088 }
4089
4090 /// Is the list redefined by the specified instructions?
4091 /// \param list list of locations to check.
4092 /// \param i1 starting instruction of the range (must be a top level insn)
4093 /// \param i2 end instruction of the range (must be a top level insn)
4094 /// i2 is excluded from the range. it can be specified as nullptr.
4095 /// i1 and i2 must belong to the same block.
4096 /// \param maymust should we search in 'may-access' or 'must-access' mode?
4098 const mlist_t &list,
4099 const minsn_t *i1,
4100 const minsn_t *i2,
4101 maymust_t maymust=MAY_ACCESS) const
4102 {
4103 return find_redefinition(list, i1, i2, maymust) != nullptr;
4104 }
4105
4106 /// Find the first insn that redefines any part of the list in the insn range.
4107 /// \param list list of locations to check.
4108 /// \param i1 starting instruction of the range (must be a top level insn)
4109 /// \param i2 end instruction of the range (must be a top level insn)
4110 /// i2 is excluded from the range. it can be specified as nullptr.
4111 /// i1 and i2 must belong to the same block.
4112 /// \param maymust should we search in 'may-access' or 'must-access' mode?
4113 /// \return pointer to such instruction or nullptr.
4114 const minsn_t *hexapi find_redefinition(
4115 const mlist_t &list,
4116 const minsn_t *i1,
4117 const minsn_t *i2,
4118 maymust_t maymust=MAY_ACCESS) const;
4119 minsn_t *find_redefinition(
4120 const mlist_t &list,
4121 minsn_t *i1,
4122 const minsn_t *i2,
4123 maymust_t maymust=MAY_ACCESS) const
4124 {
4125 return CONST_CAST(minsn_t*)(find_redefinition(list,
4126 CONST_CAST(const minsn_t*)(i1),
4127 i2,
4128 maymust));
4129 }
4130
4131 /// Is the right hand side of the instruction redefined the insn range?
4132 /// "right hand side" corresponds to the source operands of the instruction.
4133 /// \param ins instruction to consider
4134 /// \param i1 starting instruction of the range (must be a top level insn)
4135 /// \param i2 end instruction of the range (must be a top level insn)
4136 /// i2 is excluded from the range. it can be specified as nullptr.
4137 /// i1 and i2 must belong to the same block.
4138 bool hexapi is_rhs_redefined(const minsn_t *ins, const minsn_t *i1, const minsn_t *i2) const;
4139
4140 /// Find the instruction that accesses the specified operand.
4141 /// This function search inside one block.
4142 /// \param op operand to search for
4143 /// \param parent ptr to ptr to a top level instruction.
4144 /// denotes the beginning of the search range.
4145 /// \param mend end instruction of the range (must be a top level insn)
4146 /// mend is excluded from the range. it can be specified as nullptr.
4147 /// parent and mend must belong to the same block.
4148 /// \param fdflags combination of \ref FD_ bits
4149 /// \return the instruction that accesses the operand. this instruction
4150 /// may be a sub-instruction. to find out the top level
4151 /// instruction, check out *p_i1.
4152 /// nullptr means 'not found'.
4153 minsn_t *hexapi find_access(
4154 const mop_t &op,
4155 minsn_t **parent,
4156 const minsn_t *mend,
4157 int fdflags) const;
4158 /// \defgroup FD_ bits for mblock_t::find_access
4159 //@{
4160#define FD_BACKWARD 0x0000 ///< search direction
4161#define FD_FORWARD 0x0001 ///< search direction
4162#define FD_USE 0x0000 ///< look for use
4163#define FD_DEF 0x0002 ///< look for definition
4164#define FD_DIRTY 0x0004 ///< ignore possible implicit definitions
4165 ///< by function calls and indirect memory access
4166 //@}
4167
4168 // Convenience functions:
4169 minsn_t *find_def(
4170 const mop_t &op,
4171 minsn_t **p_i1,
4172 const minsn_t *i2,
4173 int fdflags)
4174 {
4175 return find_access(op, p_i1, i2, fdflags|FD_DEF);
4176 }
4177 minsn_t *find_use(
4178 const mop_t &op,
4179 minsn_t **p_i1,
4180 const minsn_t *i2,
4181 int fdflags)
4182 {
4183 return find_access(op, p_i1, i2, fdflags|FD_USE);
4184 }
4185
4186 /// Find possible values for a block.
4187 /// \param res set of value ranges
4188 /// \param vivl what to search for
4189 /// \param vrflags combination of \ref VR_ bits
4190 bool hexapi get_valranges(
4191 valrng_t *res,
4192 const vivl_t &vivl,
4193 int vrflags) const;
4194
4195 /// Find possible values for an instruction.
4196 /// \param res set of value ranges
4197 /// \param vivl what to search for
4198 /// \param m insn to search value ranges at. \sa VR_ bits
4199 /// \param vrflags combination of \ref VR_ bits
4200 bool hexapi get_valranges(
4201 valrng_t *res,
4202 const vivl_t &vivl,
4203 const minsn_t *m,
4204 int vrflags) const;
4205
4206 /// \defgroup VR_ bits for get_valranges
4207 //@{
4208#define VR_AT_START 0x0000 ///< get value ranges before the instruction or
4209 ///< at the block start (if M is nullptr)
4210#define VR_AT_END 0x0001 ///< get value ranges after the instruction or
4211 ///< at the block end, just after the last
4212 ///< instruction (if M is nullptr)
4213#define VR_EXACT 0x0002 ///< find exact match. if not set, the returned
4214 ///< valrng size will be >= vivl.size
4215 //@}
4216
4217 /// Erase the instruction (convert it to nop) and mark the lists dirty.
4218 /// This is the recommended function to use because it also marks the block
4219 /// use-def lists dirty.
4220 void make_nop(minsn_t *m) { m->_make_nop(); mark_lists_dirty(); }
4221
4222 /// Calculate number of regular instructions in the block.
4223 /// Assertions are skipped by this function.
4224 /// \return Number of non-assertion instructions in the block.
4225 size_t hexapi get_reginsn_qty() const;
4226
4227 bool is_call_block() const { return tail != nullptr && is_mcode_call(tail->opcode); }
4228 bool is_unknown_call() const { return tail != nullptr && tail->is_unknown_call(); }
4229 bool is_nway() const { return type == BLT_NWAY; }
4230 bool is_branch() const { return type == BLT_2WAY && tail->d.t == mop_b; }
4231 bool is_simple_goto_block() const
4232 {
4233 return get_reginsn_qty() == 1
4234 && tail->opcode == m_goto
4235 && tail->l.t == mop_b;
4236 }
4237 bool is_simple_jcnd_block() const
4238 {
4239 return is_branch()
4240 && npred() == 1
4241 && get_reginsn_qty() == 1
4242 && is_mcode_convertible_to_set(tail->opcode);
4243 }
4244};
4245//-------------------------------------------------------------------------
4246/// Warning ids
4248{
4249 WARN_VARARG_REGS, ///< 0 cannot handle register arguments in vararg function, discarded them
4250 WARN_ILL_PURGED, ///< 1 odd caller purged bytes %d, correcting
4251 WARN_ILL_FUNCTYPE, ///< 2 invalid function type '%s' has been ignored
4252 WARN_VARARG_TCAL, ///< 3 cannot handle tail call to vararg
4253 WARN_VARARG_NOSTK, ///< 4 call vararg without local stack
4254 WARN_VARARG_MANY, ///< 5 too many varargs, some ignored
4255 WARN_ADDR_OUTARGS, ///< 6 cannot handle address arithmetics in outgoing argument area of stack frame -- unused
4256 WARN_DEP_UNK_CALLS, ///< 7 found interdependent unknown calls
4257 WARN_ILL_ELLIPSIS, ///< 8 erroneously detected ellipsis type has been ignored
4258 WARN_GUESSED_TYPE, ///< 9 using guessed type %s;
4259 WARN_EXP_LINVAR, ///< 10 failed to expand a linear variable
4260 WARN_WIDEN_CHAINS, ///< 11 failed to widen chains
4261 WARN_BAD_PURGED, ///< 12 inconsistent function type and number of purged bytes
4262 WARN_CBUILD_LOOPS, ///< 13 too many cbuild loops
4263 WARN_NO_SAVE_REST, ///< 14 could not find valid save-restore pair for %s
4264 WARN_ODD_INPUT_REG, ///< 15 odd input register %s
4265 WARN_ODD_ADDR_USE, ///< 16 odd use of a variable address
4266 WARN_MUST_RET_FP, ///< 17 function return type is incorrect (must be floating point)
4267 WARN_ILL_FPU_STACK, ///< 18 inconsistent fpu stack
4268 WARN_SELFREF_PROP, ///< 19 self-referencing variable has been detected
4269 WARN_WOULD_OVERLAP, ///< 20 variables would overlap: %s
4270 WARN_ARRAY_INARG, ///< 21 array has been used for an input argument
4271 WARN_MAX_ARGS, ///< 22 too many input arguments, some ignored
4272 WARN_BAD_FIELD_TYPE,///< 23 incorrect structure member type for %s::%s, ignored
4273 WARN_WRITE_CONST, ///< 24 write access to const memory at %a has been detected
4274 WARN_BAD_RETVAR, ///< 25 wrong return variable
4275 WARN_FRAG_LVAR, ///< 26 fragmented variable at %s may be wrong
4276 WARN_HUGE_STKOFF, ///< 27 exceedingly huge offset into the stack frame
4277 WARN_UNINITED_REG, ///< 28 reference to an uninitialized register has been removed: %s
4278 WARN_FIXED_MACRO, ///< 29 fixed broken macro-insn
4279 WARN_WRONG_VA_OFF, ///< 30 wrong offset of va_list variable
4280 WARN_CR_NOFIELD, ///< 31 CONTAINING_RECORD: no field '%s' in struct '%s' at %d
4281 WARN_CR_BADOFF, ///< 32 CONTAINING_RECORD: too small offset %d for struct '%s'
4282 WARN_BAD_STROFF, ///< 33 user specified stroff has not been processed: %s
4283 WARN_BAD_VARSIZE, ///< 34 inconsistent variable size for '%s'
4284 WARN_UNSUPP_REG, ///< 35 unsupported processor register '%s'
4285 WARN_UNALIGNED_ARG, ///< 36 unaligned function argument '%s'
4286 WARN_BAD_STD_TYPE, ///< 37 corrupted or unexisting local type '%s'
4287 WARN_BAD_CALL_SP, ///< 38 bad sp value at call
4288 WARN_MISSED_SWITCH, ///< 39 wrong markup of switch jump, skipped it
4289 WARN_BAD_SP, ///< 40 positive sp value %a has been found
4290 WARN_BAD_STKPNT, ///< 41 wrong sp change point
4291 WARN_UNDEF_LVAR, ///< 42 variable '%s' is possibly undefined
4292 WARN_JUMPOUT, ///< 43 control flows out of bounds
4293 WARN_BAD_VALRNG, ///< 44 values range analysis failed
4294 WARN_BAD_SHADOW, ///< 45 ignored the value written to the shadow area of the succeeding call
4295 WARN_OPT_VALRNG, ///< 46 conditional instruction was optimized away because %s
4296 WARN_RET_LOCREF, ///< 47 returning address of temporary local variable '%s'
4297 WARN_BAD_MAPDST, ///< 48 too short map destination '%s' for variable '%s'
4298 WARN_BAD_INSN, ///< 49 bad instruction
4299 WARN_ODD_ABI, ///< 50 encountered odd instruction for the current ABI
4300 WARN_UNBALANCED_STACK, ///< 51 unbalanced stack, ignored a potential tail call
4301
4302 WARN_OPT_VALRNG2, ///< 52 mask 0x%X is shortened because %s <= 0x%X"
4303
4304 WARN_OPT_VALRNG3, ///< 53 masking with 0X%X was optimized away because %s <= 0x%X
4305 WARN_OPT_USELESS_JCND, ///< 54 simplified comparisons for '%s': %s became %s
4306 WARN_MAX, ///< may be used in notes as a placeholder when the
4307 ///< warning id is not available
4308};
4309
4310/// Warning instances
4312{
4313 ea_t ea; ///< Address where the warning occurred
4314 warnid_t id; ///< Warning id
4315 qstring text; ///< Fully formatted text of the warning
4316 DECLARE_COMPARISONS(hexwarn_t)
4317 {
4318 if ( ea < r.ea )
4319 return -1;
4320 if ( ea > r.ea )
4321 return 1;
4322 if ( id < r.id )
4323 return -1;
4324 if ( id > r.id )
4325 return 1;
4326 return strcmp(text.c_str(), r.text.c_str());
4327 }
4328};
4329DECLARE_TYPE_AS_MOVABLE(hexwarn_t);
4330typedef qvector<hexwarn_t> hexwarns_t;
4331
4332//-------------------------------------------------------------------------
4333/// Microcode maturity levels
4335{
4336 MMAT_ZERO, ///< microcode does not exist
4337 MMAT_GENERATED, ///< generated microcode
4338 MMAT_PREOPTIMIZED, ///< preoptimized pass is complete
4339 MMAT_LOCOPT, ///< local optimization of each basic block is complete.
4340 ///< control flow graph is ready too.
4341 MMAT_CALLS, ///< detected call arguments. see also hxe_calls_done
4342 MMAT_GLBOPT1, ///< performed the first pass of global optimization
4343 MMAT_GLBOPT2, ///< most global optimization passes are done
4344 MMAT_GLBOPT3, ///< completed all global optimization. microcode is fixed now.
4345 MMAT_LVARS, ///< allocated local variables
4346};
4347
4348//-------------------------------------------------------------------------
4349enum memreg_index_t ///< memory region types
4350{
4351 MMIDX_GLBLOW, ///< global memory: low part
4352 MMIDX_LVARS, ///< stack: local variables
4353 MMIDX_RETADDR, ///< stack: return address
4354 MMIDX_SHADOW, ///< stack: shadow arguments
4355 MMIDX_ARGS, ///< stack: regular stack arguments
4356 MMIDX_GLBHIGH, ///< global memory: high part
4357};
4358
4359//-------------------------------------------------------------------------
4360/// Ranges to decompile. Either a function or an explicit vector of ranges.
4362{
4363 func_t *pfn = nullptr; ///< function to decompile. if not null, then function mode.
4364 rangevec_t ranges; ///< snippet mode: ranges to decompile.
4365 ///< function mode: list of outlined ranges
4366 mba_ranges_t(func_t *_pfn=nullptr) : pfn(_pfn) {}
4367 mba_ranges_t(const rangevec_t &r) : ranges(r) {}
4368 ea_t start() const { return (pfn != nullptr ? *pfn : ranges[0]).start_ea; }
4369 bool empty() const { return pfn == nullptr && ranges.empty(); }
4370 void clear() { pfn = nullptr; ranges.clear(); }
4371 bool is_snippet() const { return pfn == nullptr; }
4372 bool hexapi range_contains(ea_t ea) const;
4373 bool is_fragmented() const
4374 {
4375 int n_frags = ranges.size();
4376 if ( pfn != nullptr )
4377 n_frags += pfn->tailqty + 1;
4378 return n_frags > 1;
4379 }
4380};
4381
4382/// Item iterator of arbitrary rangevec items
4384{
4385 const rangevec_t *ranges = nullptr;
4386 const range_t *rptr = nullptr; // pointer into ranges
4387 ea_t cur = BADADDR; // current address
4388 bool set(const rangevec_t &r);
4389 bool next_code();
4390 ea_t current() const { return cur; }
4391};
4392
4393/// Item iterator for mba_ranges_t
4395{
4397 func_item_iterator_t fii;
4398 bool func_items_done = true;
4399 bool set(const mba_ranges_t &mbr)
4400 {
4401 bool ok = false;
4402 if ( mbr.pfn != nullptr )
4403 {
4404 ok = fii.set(mbr.pfn);
4405 if ( ok )
4406 func_items_done = false;
4407 }
4408 if ( rii.set(mbr.ranges) )
4409 ok = true;
4410 return ok;
4411 }
4412 bool next_code()
4413 {
4414 bool ok = false;
4415 if ( !func_items_done )
4416 {
4417 ok = fii.next_code();
4418 if ( !ok )
4419 func_items_done = true;
4420 }
4421 if ( !ok )
4422 ok = rii.next_code();
4423 return ok;
4424 }
4425 ea_t current() const
4426 {
4427 return func_items_done ? rii.current() : fii.current();
4428 }
4429};
4430
4431/// Chunk iterator of arbitrary rangevec items
4433{
4434 const range_t *rptr = nullptr; // pointer into ranges
4435 const range_t *rend = nullptr;
4436 bool set(const rangevec_t &r) { rptr = r.begin(); rend = r.end(); return rptr != rend; }
4437 bool next() { return ++rptr != rend; }
4438 const range_t &chunk() const { return *rptr; }
4439};
4440
4441/// Chunk iterator for mba_ranges_t
4443{
4445 func_tail_iterator_t fii; // this is used if rii.rptr==nullptr
4446 bool is_snippet() const { return rii.rptr != nullptr; }
4447 bool set(const mba_ranges_t &mbr)
4448 {
4449 if ( mbr.is_snippet() )
4450 return rii.set(mbr.ranges);
4451 else
4452 return fii.set(mbr.pfn);
4453 }
4454 bool next()
4455 {
4456 if ( is_snippet() )
4457 return rii.next();
4458 else
4459 return fii.next();
4460 }
4461 const range_t &chunk() const
4462 {
4463 return is_snippet() ? rii.chunk() : fii.chunk();
4464 }
4465};
4466
4467//-------------------------------------------------------------------------
4468/// Array of micro blocks representing microcode for a decompiled function.
4469/// The first micro block is the entry point, the last one is the exit point.
4470/// The entry and exit blocks are always empty. The exit block is generated
4471/// at MMAT_LOCOPT maturity level.
4472class mba_t
4473{
4474 DECLARE_UNCOPYABLE(mba_t)
4475 uint32 flags;
4476 uint32 flags2;
4477
4478public:
4479 // bits to describe the microcode, set by the decompiler
4480#define MBA_PRCDEFS 0x00000001 ///< use precise defeas for chain-allocated lvars
4481#define MBA_NOFUNC 0x00000002 ///< function is not present, addresses might be wrong
4482#define MBA_PATTERN 0x00000004 ///< microcode pattern, callinfo is present
4483#define MBA_LOADED 0x00000008 ///< loaded gdl, no instructions (debugging)
4484#define MBA_RETFP 0x00000010 ///< function returns floating point value
4485#define MBA_SPLINFO 0x00000020 ///< (final_type ? idb_spoiled : spoiled_regs) is valid
4486#define MBA_PASSREGS 0x00000040 ///< has mcallinfo_t::pass_regs
4487#define MBA_THUNK 0x00000080 ///< thunk function
4488#define MBA_CMNSTK 0x00000100 ///< stkvars+stkargs should be considered as one area
4489
4490 // bits to describe analysis stages and requests
4491#define MBA_PREOPT 0x00000200 ///< preoptimization stage complete
4492#define MBA_CMBBLK 0x00000400 ///< request to combine blocks
4493#define MBA_ASRTOK 0x00000800 ///< assertions have been generated
4494#define MBA_CALLS 0x00001000 ///< callinfo has been built
4495#define MBA_ASRPROP 0x00002000 ///< assertion have been propagated
4496#define MBA_SAVRST 0x00004000 ///< save-restore analysis has been performed
4497#define MBA_RETREF 0x00008000 ///< return type has been refined
4498#define MBA_GLBOPT 0x00010000 ///< microcode has been optimized globally
4499#define MBA_LVARS0 0x00040000 ///< lvar pre-allocation has been performed
4500#define MBA_LVARS1 0x00080000 ///< lvar real allocation has been performed
4501#define MBA_DELPAIRS 0x00100000 ///< pairs have been deleted once
4502#define MBA_CHVARS 0x00200000 ///< can verify chain varnums
4503
4504 // bits that can be set by the caller:
4505#define MBA_SHORT 0x00400000 ///< use short display
4506#define MBA_COLGDL 0x00800000 ///< display graph after each reduction
4507#define MBA_INSGDL 0x01000000 ///< display instruction in graphs
4508#define MBA_NICE 0x02000000 ///< apply transformations to c code
4509#define MBA_REFINE 0x04000000 ///< may refine return value size
4510#define MBA_WINGR32 0x10000000 ///< use wingraph32
4511#define MBA_NUMADDR 0x20000000 ///< display definition addresses for numbers
4512#define MBA_VALNUM 0x40000000 ///< display value numbers
4513
4514#define MBA_INITIAL_FLAGS (MBA_INSGDL|MBA_NICE|MBA_CMBBLK|MBA_REFINE\
4515 |MBA_PRCDEFS|MBA_WINGR32|MBA_VALNUM)
4516
4517#define MBA2_LVARNAMES_OK 0x00000001 ///< may verify lvar_names?
4518#define MBA2_LVARS_RENAMED 0x00000002 ///< accept empty names now?
4519#define MBA2_OVER_CHAINS 0x00000004 ///< has overlapped chains?
4520#define MBA2_VALRNG_DONE 0x00000008 ///< calculated valranges?
4521#define MBA2_IS_CTR 0x00000010 ///< is constructor?
4522#define MBA2_IS_DTR 0x00000020 ///< is destructor?
4523#define MBA2_ARGIDX_OK 0x00000040 ///< may verify input argument list?
4524#define MBA2_NO_DUP_CALLS 0x00000080 ///< forbid multiple calls with the same ea
4525#define MBA2_NO_DUP_LVARS 0x00000100 ///< forbid multiple lvars with the same ea
4526#define MBA2_UNDEF_RETVAR 0x00000200 ///< return value is undefined
4527#define MBA2_ARGIDX_SORTED 0x00000400 ///< args finally sorted according to ABI
4528 ///< (e.g. reverse stkarg order in Borland)
4529#define MBA2_CODE16_BIT 0x00000800 ///< the code16 bit removed
4530#define MBA2_STACK_RETVAL 0x00001000 ///< the return value is on the stack
4531#define MBA2_HAS_OUTLINES 0x00002000 ///< calls to outlined code have been inlined
4532#define MBA2_NO_FRAME 0x00004000 ///< do not use function frame info (only snippet mode)
4533#define MBA2_PROP_COMPLEX 0x00008000 ///< allow propagation of more complex variable definitions
4534
4535#define MBA2_DONT_VERIFY 0x80000000 ///< Do not verify microcode. This flag
4536 ///< is recomended to be set only when
4537 ///< debugging decompiler plugins
4538
4539#define MBA2_INITIAL_FLAGS (MBA2_LVARNAMES_OK|MBA2_LVARS_RENAMED)
4540
4541#define MBA2_ALL_FLAGS 0x0001FFFF
4542
4543 bool precise_defeas() const { return (flags & MBA_PRCDEFS) != 0; }
4544 bool optimized() const { return (flags & MBA_GLBOPT) != 0; }
4545 bool short_display() const { return (flags & MBA_SHORT ) != 0; }
4546 bool show_reduction() const { return (flags & MBA_COLGDL) != 0; }
4547 bool graph_insns() const { return (flags & MBA_INSGDL) != 0; }
4548 bool loaded_gdl() const { return (flags & MBA_LOADED) != 0; }
4549 bool should_beautify()const { return (flags & MBA_NICE ) != 0; }
4550 bool rtype_refined() const { return (flags & MBA_RETREF) != 0; }
4551 bool may_refine_rettype() const { return (flags & MBA_REFINE) != 0; }
4552 bool use_wingraph32() const { return (flags & MBA_WINGR32) != 0; }
4553 bool display_numaddrs() const { return (flags & MBA_NUMADDR) != 0; }
4554 bool display_valnums() const { return (flags & MBA_VALNUM) != 0; }
4555 bool is_pattern() const { return (flags & MBA_PATTERN) != 0; }
4556 bool is_thunk() const { return (flags & MBA_THUNK) != 0; }
4557 bool saverest_done() const { return (flags & MBA_SAVRST) != 0; }
4558 bool callinfo_built() const { return (flags & MBA_CALLS) != 0; }
4559 bool really_alloc() const { return (flags & MBA_LVARS0) != 0; }
4560 bool lvars_allocated()const { return (flags & MBA_LVARS1) != 0; }
4561 bool chain_varnums_ok()const { return (flags & MBA_CHVARS) != 0; }
4562 bool returns_fpval() const { return (flags & MBA_RETFP) != 0; }
4563 bool has_passregs() const { return (flags & MBA_PASSREGS) != 0; }
4564 bool generated_asserts() const { return (flags & MBA_ASRTOK) != 0; }
4565 bool propagated_asserts() const { return (flags & MBA_ASRPROP) != 0; }
4566 bool deleted_pairs() const { return (flags & MBA_DELPAIRS) != 0; }
4567 bool common_stkvars_stkargs() const { return (flags & MBA_CMNSTK) != 0; }
4568 bool lvar_names_ok() const { return (flags2 & MBA2_LVARNAMES_OK) != 0; }
4569 bool lvars_renamed() const { return (flags2 & MBA2_LVARS_RENAMED) != 0; }
4570 bool has_over_chains() const { return (flags2 & MBA2_OVER_CHAINS) != 0; }
4571 bool valranges_done() const { return (flags2 & MBA2_VALRNG_DONE) != 0; }
4572 bool argidx_ok() const { return (flags2 & MBA2_ARGIDX_OK) != 0; }
4573 bool argidx_sorted() const { return (flags2 & MBA2_ARGIDX_SORTED) != 0; }
4574 bool code16_bit_removed() const { return (flags2 & MBA2_CODE16_BIT) != 0; }
4575 bool has_stack_retval() const { return (flags2 & MBA2_STACK_RETVAL) != 0; }
4576 bool has_outlines() const { return (flags2 & MBA2_HAS_OUTLINES) != 0; }
4577 bool is_ctr() const { return (flags2 & MBA2_IS_CTR) != 0; }
4578 bool is_dtr() const { return (flags2 & MBA2_IS_DTR) != 0; }
4579 bool is_cdtr() const { return (flags2 & (MBA2_IS_CTR|MBA2_IS_DTR)) != 0; }
4580 bool prop_complex() const { return (flags2 & MBA2_PROP_COMPLEX) != 0; }
4581 int get_mba_flags() const { return flags; }
4582 int get_mba_flags2() const { return flags2; }
4583 void set_mba_flags(int f) { flags |= f; }
4584 void clr_mba_flags(int f) { flags &= ~f; }
4585 void set_mba_flags2(int f) { flags2 |= f; }
4586 void clr_mba_flags2(int f) { flags2 &= ~f; }
4587 void clr_cdtr() { flags2 &= ~(MBA2_IS_CTR|MBA2_IS_DTR); }
4588 int calc_shins_flags() const
4589 {
4590 int shins_flags = 0;
4591 if ( short_display() )
4592 shins_flags |= SHINS_SHORT;
4593 if ( display_valnums() )
4594 shins_flags |= SHINS_VALNUM;
4595 if ( display_numaddrs() )
4596 shins_flags |= SHINS_NUMADDR;
4597 return shins_flags;
4598 }
4599
4600/*
4601 +-----------+ <- inargtop
4602 | prmN |
4603 | ... | <- minargref
4604 | prm0 |
4605 +-----------+ <- inargoff
4606 |shadow_args|
4607 +-----------+
4608 | retaddr |
4609 frsize+frregs +-----------+ <- initial esp |
4610 | frregs | |
4611 +frsize +-----------+ <- typical ebp |
4612 | | | |
4613 | | | fpd |
4614 | | | |
4615 | frsize | <- current ebp |
4616 | | |
4617 | | |
4618 | | | stacksize
4619 | | |
4620 | | |
4621 | | <- minstkref |
4622 stkvar base off 0 +---.. | | | current
4623 | | | | stack
4624 | | | | pointer
4625 | | | | range
4626 |tmpstk_size| | | (what getspd() returns)
4627 | | | |
4628 | | | |
4629 +-----------+ <- minimal sp | | offset 0 for the decompiler (vd)
4630
4631 There is a detail that may add confusion when working with stack variables.
4632 The decompiler does not use the same stack offsets as IDA.
4633 The picture above should explain the difference:
4634 - IDA stkoffs are displayed on the left, decompiler stkoffs - on the right
4635 - Decompiler stkoffs are always >= 0
4636 - IDA stkoff==0 corresponds to stkoff==tmpstk_size in the decompiler
4637 - See stkoff_vd2ida and stkoff_ida2vd below to convert IDA stkoffs to vd stkoff
4638
4639*/
4640
4641 // convert a stack offset used in vd to a stack offset used in ida stack frame
4642 sval_t hexapi stkoff_vd2ida(sval_t off) const;
4643 // convert a ida stack frame offset to a stack offset used in vd
4644 sval_t hexapi stkoff_ida2vd(sval_t off) const;
4645 sval_t argbase() const
4646 {
4647 return retsize + stacksize;
4648 }
4649 static vdloc_t hexapi idaloc2vd(const argloc_t &loc, int width, sval_t spd);
4650 vdloc_t hexapi idaloc2vd(const argloc_t &loc, int width) const;
4651
4652 static argloc_t hexapi vd2idaloc(const vdloc_t &loc, int width, sval_t spd);
4653 argloc_t hexapi vd2idaloc(const vdloc_t &loc, int width) const;
4654
4655 bool is_stkarg(const lvar_t &v) const
4656 {
4657 return v.is_stk_var() && v.get_stkoff() >= inargoff;
4658 }
4659 member_t *get_stkvar(sval_t vd_stkoff, uval_t *poff) const;
4660 // get lvar location
4661 argloc_t get_ida_argloc(const lvar_t &v) const
4662 {
4663 return vd2idaloc(v.location, v.width);
4664 }
4665 mba_ranges_t mbr;
4666 ea_t entry_ea = BADADDR;
4667 ea_t last_prolog_ea = BADADDR;
4668 ea_t first_epilog_ea = BADADDR;
4669 int qty = 0; ///< number of basic blocks
4670 int npurged = -1; ///< -1 - unknown
4671 cm_t cc = CM_CC_UNKNOWN; ///< calling convention
4672 sval_t tmpstk_size = 0; ///< size of the temporary stack part
4673 ///< (which dynamically changes with push/pops)
4674 sval_t frsize = 0; ///< size of local stkvars range in the stack frame
4675 sval_t frregs = 0; ///< size of saved registers range in the stack frame
4676 sval_t fpd = 0; ///< frame pointer delta
4677 int pfn_flags = 0; ///< copy of func_t::flags
4678 int retsize = 0; ///< size of return address in the stack frame
4679 int shadow_args = 0; ///< size of shadow argument area
4680 sval_t fullsize = 0; ///< Full stack size including incoming args
4681 sval_t stacksize = 0; ///< The maximal size of the function stack including
4682 ///< bytes allocated for outgoing call arguments
4683 ///< (up to retaddr)
4684 sval_t inargoff = 0; ///< offset of the first stack argument;
4685 ///< after fix_scattered_movs() INARGOFF may
4686 ///< be less than STACKSIZE
4687 sval_t minstkref = 0; ///< The lowest stack location whose address was taken
4688 ea_t minstkref_ea = BADADDR; ///< address with lowest minstkref (for debugging)
4689 sval_t minargref = 0; ///< The lowest stack argument location whose address was taken
4690 ///< This location and locations above it can be aliased
4691 ///< It controls locations >= inargoff-shadow_args
4692 sval_t spd_adjust = 0; ///< If sp>0, the max positive sp value
4693 ivl_t aliased_vars = ivl_t(0, 0); ///< Aliased stkvar locations
4694 ivl_t aliased_args = ivl_t(0, 0); ///< Aliased stkarg locations
4695 ivlset_t gotoff_stkvars; ///< stkvars that hold .got offsets. considered to be unaliasable
4696 ivlset_t restricted_memory;
4697 ivlset_t aliased_memory = ALLMEM; ///< aliased_memory+restricted_memory=ALLMEM
4698 mlist_t nodel_memory; ///< global dead elimination may not delete references to this area
4699 rlist_t consumed_argregs; ///< registers converted into stack arguments, should not be used as arguments
4700
4701 mba_maturity_t maturity = MMAT_ZERO; ///< current maturity level
4702 mba_maturity_t reqmat = MMAT_ZERO; ///< required maturity level
4703
4704 bool final_type = false; ///< is the function type final? (specified by the user)
4705 tinfo_t idb_type; ///< function type as retrieved from the database
4706 reginfovec_t idb_spoiled; ///< MBA_SPLINFO && final_type: info in ida format
4707 mlist_t spoiled_list; ///< MBA_SPLINFO && !final_type: info in vd format
4708 int fti_flags = 0; ///< FTI_... constants for the current function
4709
4710 netnode deprecated_idb_node; ///< netnode with additional decompiler info.
4711 ///< deprecated, do not use it anymore. it may get
4712 ///< stale after undo.
4713#define NALT_VD 2 ///< this index is not used by ida
4714
4715 qstring label; ///< name of the function or pattern (colored)
4716 lvars_t vars; ///< local variables
4717 intvec_t argidx; ///< input arguments (indexes into 'vars')
4718 int retvaridx = -1; ///< index of variable holding the return value
4719 ///< -1 means none
4720
4721 ea_t error_ea = BADADDR; ///< during microcode generation holds ins.ea
4722 qstring error_strarg;
4723
4724 mblock_t *blocks = nullptr; ///< double linked list of blocks
4725 mblock_t **natural = nullptr; ///< natural order of blocks
4726
4727 ivl_with_name_t std_ivls[6]; ///< we treat memory as consisting of 6 parts
4728 ///< see \ref memreg_index_t
4729
4730 mutable hexwarns_t notes;
4731 mutable uchar occurred_warns[32]; // occurred warning messages
4732 // (even disabled warnings are taken into account)
4733 bool write_to_const_detected() const
4734 {
4735 return test_bit(occurred_warns, WARN_WRITE_CONST);
4736 }
4737 bool bad_call_sp_detected() const
4738 {
4739 return test_bit(occurred_warns, WARN_BAD_CALL_SP);
4740 }
4741 bool regargs_is_not_aligned() const
4742 {
4743 return test_bit(occurred_warns, WARN_UNALIGNED_ARG);
4744 }
4745 bool has_bad_sp() const
4746 {
4747 return test_bit(occurred_warns, WARN_BAD_SP);
4748 }
4749
4750 // the exact size of this class is not documented, there may be more fields
4751 char reserved[];
4752 mba_t(); // use gen_microcode() or create_empty_mba() to create microcode objects
4753 ~mba_t() { term(); }
4754 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
4755 void hexapi term();
4756 func_t *hexapi get_curfunc() const;
4757 bool use_frame() const { return get_curfunc() != nullptr; }
4758 bool range_contains(ea_t ea) const { return mbr.range_contains(map_fict_ea(ea)); }
4759 bool is_snippet() const { return mbr.is_snippet(); }
4760
4761 /// Set maturity level.
4762 /// \param mat new maturity level
4763 /// \return true if it is time to stop analysis
4764 /// Plugins may use this function to skip some parts of the analysis.
4765 /// The maturity level cannot be decreased.
4766 bool hexapi set_maturity(mba_maturity_t mat);
4767
4768 /// Optimize each basic block locally
4769 /// \param locopt_bits combination of \ref LOCOPT_ bits
4770 /// \return number of changes. 0 means nothing changed
4771 /// This function is called by the decompiler, usually there is no need to
4772 /// call it explicitly.
4773 int hexapi optimize_local(int locopt_bits);
4774 /// \defgroup LOCOPT_ Bits for optimize_local()
4775 //@{
4776#define LOCOPT_ALL 0x0001 ///< redo optimization for all blocks. if this bit
4777 ///< is not set, only dirty blocks will be optimized
4778#define LOCOPT_REFINE 0x0002 ///< refine return type, ok to fail
4779#define LOCOPT_REFINE2 0x0004 ///< refine return type, try harder
4780 //@}
4781
4782 /// Build control flow graph.
4783 /// This function may be called only once. It calculates the type of each
4784 /// basic block and the adjacency list. optimize_local() calls this function
4785 /// if necessary. You need to call this function only before MMAT_LOCOPT.
4786 /// \return error code
4787 merror_t hexapi build_graph();
4788
4789 /// Get control graph.
4790 /// Call build_graph() if you need the graph before MMAT_LOCOPT.
4791 mbl_graph_t *hexapi get_graph();
4792
4793 /// Analyze calls and determine calling conventions.
4794 /// \param acflags permitted actions that are necessary for successful detection
4795 /// of calling conventions. See \ref ACFL_
4796 /// \return number of calls. -1 means error.
4797 int hexapi analyze_calls(int acflags);
4798 /// \defgroup ACFL_ Bits for analyze_calls()
4799 //@{
4800#define ACFL_LOCOPT 0x01 ///< perform local propagation (requires ACFL_BLKOPT)
4801#define ACFL_BLKOPT 0x02 ///< perform interblock transformations
4802#define ACFL_GLBPROP 0x04 ///< perform global propagation
4803#define ACFL_GLBDEL 0x08 ///< perform dead code eliminition
4804#define ACFL_GUESS 0x10 ///< may guess calling conventions
4805 //@}
4806
4807 /// Optimize microcode globally.
4808 /// This function applies various optimization methods until we reach the
4809 /// fixed point. After that it preallocates lvars unless reqmat forbids it.
4810 /// \return error code
4811 merror_t hexapi optimize_global();
4812
4813 /// Allocate local variables.
4814 /// Must be called only immediately after optimize_global(), with no
4815 /// modifications to the microcode. Converts registers,
4816 /// stack variables, and similar operands into mop_l. This call will not fail
4817 /// because all necessary checks were performed in optimize_global().
4818 /// After this call the microcode reaches its final state.
4819 void hexapi alloc_lvars();
4820
4821 /// Dump microcode to a file.
4822 /// The file will be created in the directory pointed by IDA_DUMPDIR envvar.
4823 /// Dump will be created only if IDA is run under debugger.
4824 void hexapi dump() const;
4825 AS_PRINTF(3, 0) void hexapi vdump_mba(bool _verify, const char *title, va_list va) const;
4826 AS_PRINTF(3, 4) void dump_mba(bool _verify, const char *title, ...) const
4827 {
4828 va_list va;
4829 va_start(va, title);
4830 vdump_mba(_verify, title, va);
4831 va_end(va);
4832 }
4833
4834 /// Print microcode to any destination.
4835 /// \param vp print sink
4836 void hexapi print(vd_printer_t &vp) const;
4837
4838 /// Verify microcode consistency.
4839 /// \param always if false, the check will be performed only if ida runs
4840 /// under debugger
4841 /// If any inconsistency is discovered, an internal error will be generated.
4842 /// We strongly recommend you to call this function before returing control
4843 /// to the decompiler from your callbacks, in the case if you modified
4844 /// the microcode. If the microcode is inconsistent, this function will
4845 /// generate an internal error. We provide the source code of this function
4846 /// in the plugins/hexrays_sdk/verifier directory for your reference.
4847 void hexapi verify(bool always) const;
4848
4849 /// Mark the microcode use-def chains dirty.
4850 /// Call this function is any inter-block data dependencies got changed
4851 /// because of your modifications to the microcode. Failing to do so may
4852 /// cause an internal error.
4853 void hexapi mark_chains_dirty();
4854
4855 /// Get basic block by its serial number.
4856 const mblock_t *get_mblock(int n) const { return natural[n]; }
4857 mblock_t *get_mblock(int n) { return CONST_CAST(mblock_t*)((CONST_CAST(const mba_t *)(this))->get_mblock(n)); }
4858
4859 /// Insert a block in the middle of the mbl array.
4860 /// The very first block of microcode must be empty, it is the entry block.
4861 /// The very last block of microcode must be BLT_STOP, it is the exit block.
4862 /// Therefore inserting a new block before the entry point or after the exit
4863 /// block is not a good idea.
4864 /// \param bblk the new block will be inserted before BBLK
4865 /// \return ptr to the new block
4866 mblock_t *hexapi insert_block(int bblk);
4867
4868 /// Delete a block.
4869 /// \param blk block to delete
4870 /// \return true if at least one of the other blocks became empty or unreachable
4871 bool hexapi remove_block(mblock_t *blk);
4872
4873 /// Make a copy of a block.
4874 /// This function makes a simple copy of the block. It does not fix the
4875 /// predecessor and successor lists, they must be fixed if necessary.
4876 /// \param blk block to copy
4877 /// \param new_serial position of the copied block
4878 /// \param cpblk_flags combination of \ref CPBLK_... bits
4879 /// \return pointer to the new copy
4880 mblock_t *hexapi copy_block(mblock_t *blk, int new_serial, int cpblk_flags=3);
4881/// \defgroup CPBLK_ Batch decompilation bits
4882///@{
4883#define CPBLK_FAST 0x0000 ///< do not update minbstkref and minbargref
4884#define CPBLK_MINREF 0x0001 ///< update minbstkref and minbargref
4885#define CPBLK_OPTJMP 0x0002 ///< del the jump insn at the end of the block
4886 ///< if it becomes useless
4887///@}
4888
4889 /// Delete all empty and unreachable blocks.
4890 /// Blocks marked with MBL_KEEP won't be deleted.
4891 bool hexapi remove_empty_and_unreachable_blocks();
4892
4893 /// Combine blocks.
4894 /// This function merges blocks constituting linear flow.
4895 /// It calls remove_empty_and_unreachable_blocks() as well.
4896 /// \return true if changed any blocks
4897 bool hexapi combine_blocks();
4898
4899 /// Visit all operands of all instructions.
4900 /// \param mv operand visitor
4901 /// \return non-zero value returned by mv.visit_mop() or zero
4902 int hexapi for_all_ops(mop_visitor_t &mv);
4903
4904 /// Visit all instructions.
4905 /// This function visits all instruction and subinstructions.
4906 /// \param mv instruction visitor
4907 /// \return non-zero value returned by mv.visit_mop() or zero
4908 int hexapi for_all_insns(minsn_visitor_t &mv);
4909
4910 /// Visit all top level instructions.
4911 /// \param mv instruction visitor
4912 /// \return non-zero value returned by mv.visit_mop() or zero
4913 int hexapi for_all_topinsns(minsn_visitor_t &mv);
4914
4915 /// Find an operand in the microcode.
4916 /// This function tries to find the operand that matches LIST.
4917 /// Any operand that overlaps with LIST is considered as a match.
4918 /// \param[out] ctx context information for the result
4919 /// \param ea desired address of the operand. BADADDR means to accept any address.
4920 /// \param is_dest search for destination operand? this argument may be
4921 /// ignored if the exact match could not be found
4922 /// \param list list of locations the correspond to the operand
4923 /// \return pointer to the operand or nullptr.
4924 mop_t *hexapi find_mop(op_parent_info_t *ctx, ea_t ea, bool is_dest, const mlist_t &list);
4925
4926 /// Create a call of a helper function.
4927 /// \param ea The desired address of the instruction
4928 /// \param helper The helper name
4929 /// \param rettype The return type (nullptr or empty type means 'void')
4930 /// \param callargs The helper arguments (nullptr-no arguments)
4931 /// \param out The operand where the call result should be stored.
4932 /// If this argument is not nullptr, "mov helper_call(), out"
4933 /// will be generated. Otherwise "call helper()" will be
4934 /// generated. Note: the size of this operand must be equal
4935 /// to the RETTYPE size
4936 /// \return pointer to the created instruction or nullptr if error
4937 minsn_t *hexapi create_helper_call(
4938 ea_t ea,
4939 const char *helper,
4940 const tinfo_t *rettype=nullptr,
4941 const mcallargs_t *callargs=nullptr,
4942 const mop_t *out=nullptr);
4943
4944 /// Prepare the lists of registers & memory that are defined/killed by a
4945 /// function
4946 /// \param[out] return_regs defined regs to return (eax,edx)
4947 /// \param[out] spoiled spoiled regs (flags,ecx,mem)
4948 /// \param type the function type
4949 /// \param call_ea the call insn address (if known)
4950 /// \param tail_call is it the tail call?
4951 void hexapi get_func_output_lists(
4952 mlist_t *return_regs,
4953 mlist_t *spoiled,
4954 const tinfo_t &type,
4955 ea_t call_ea=BADADDR,
4956 bool tail_call=false);
4957
4958 /// Get input argument of the decompiled function.
4959 /// \param n argument number (0..nargs-1)
4960 lvar_t &hexapi arg(int n);
4961 const lvar_t &arg(int n) const { return CONST_CAST(mba_t*)(this)->arg(n); }
4962
4963 /// Allocate a fictional address.
4964 /// This function can be used to allocate a new unique address for a new
4965 /// instruction, if re-using any existing address leads to conflicts.
4966 /// For example, if the last instruction of the function modifies R0
4967 /// and falls through to the next function, it will be a tail call:
4968 /// LDM R0!, {R4,R7}
4969 /// end of the function
4970 /// start of another function
4971 /// In this case R0 generates two different lvars at the same address:
4972 /// - one modified by LDM
4973 /// - another that represents the return value from the tail call
4974 /// Another example: a third-party plugin makes a copy of an instruction.
4975 /// This may lead to the generation of two variables at the same address.
4976 /// Example 3: fictional addresses can be used for new instructions created
4977 /// while modifying the microcode.
4978 /// This function can be used to allocate a new unique address for a new
4979 /// instruction or a variable.
4980 /// The fictional address is selected from an unallocated address range.
4981 /// \param real_ea real instruction address (BADADDR is ok too)
4982 /// \return a unique fictional address
4983 ea_t hexapi alloc_fict_ea(ea_t real_ea);
4984
4985 /// Resolve a fictional address.
4986 /// This function provides a reverse of the mapping made by alloc_fict_ea().
4987 /// \param fict_ea fictional definition address
4988 /// \return the real instruction address
4989 ea_t hexapi map_fict_ea(ea_t fict_ea) const;
4990
4991 /// Get information about various memory regions.
4992 /// We map the stack frame to the global memory, to some unused range.
4993 const ivl_t &get_std_region(memreg_index_t idx) const;
4994 const ivl_t &get_lvars_region() const;
4995 const ivl_t &get_shadow_region() const;
4996 const ivl_t &get_args_region() const;
4997 ivl_t get_stack_region() const; // get entire stack region
4998
4999 /// Serialize mbl array into a sequence of bytes.
5000 void hexapi serialize(bytevec_t &vout) const;
5001
5002 /// Deserialize a byte sequence into mbl array.
5003 /// \param bytes pointer to the beginning of the byte sequence.
5004 /// \param nbytes number of bytes in the byte sequence.
5005 /// \return new mbl array
5006 WARN_UNUSED_RESULT static mba_t *hexapi deserialize(const uchar *bytes, size_t nbytes);
5007
5008 /// Create and save microcode snapshot
5009 void hexapi save_snapshot(const char *description);
5010
5011 /// Allocate a kernel register.
5012 /// \param size size of the register in bytes
5013 /// \param check_size if true, only the sizes that correspond to a size of
5014 /// a basic type will be accepted.
5015 /// \return allocated register. mr_none means failure.
5016 mreg_t hexapi alloc_kreg(size_t size, bool check_size=true);
5017
5018 /// Free a kernel register.
5019 /// If wrong arguments are passed, this function will generate an internal error.
5020 /// \param reg a previously allocated kernel register
5021 /// \param size size of the register in bytes
5022 void hexapi free_kreg(mreg_t reg, size_t size);
5023 bool hexapi set_lvar_name(lvar_t &v, const char *name, int flagbits);
5024 bool set_nice_lvar_name(lvar_t &v, const char *name) { return set_lvar_name(v, name, CVAR_NAME); }
5025 bool set_user_lvar_name(lvar_t &v, const char *name) { return set_lvar_name(v, name, CVAR_NAME|CVAR_UNAME); }
5026};
5027using mbl_array_t = mba_t;
5028//-------------------------------------------------------------------------
5029/// Convenience class to release graph chains automatically.
5030/// Use this class instead of using graph_chains_t directly.
5032{
5033 graph_chains_t *gc;
5034 chain_keeper_t &operator=(const chain_keeper_t &); // not defined
5035public:
5036 chain_keeper_t(graph_chains_t *_gc) : gc(_gc) { QASSERT(50446, gc != nullptr); gc->acquire(); }
5038 {
5039 gc->release();
5040 }
5041 block_chains_t &operator[](size_t idx) { return (*gc)[idx]; }
5042 block_chains_t &front() { return gc->front(); }
5043 block_chains_t &back() { return gc->back(); }
5044 operator graph_chains_t &() { return *gc; }
5045 int for_all_chains(chain_visitor_t &cv, int gca) { return gc->for_all_chains(cv, gca); }
5046 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
5047};
5048
5049//-------------------------------------------------------------------------
5050/// Kind of use-def and def-use chains
5052{
5053 GC_REGS_AND_STKVARS, ///< registers and stkvars (restricted memory only)
5054 GC_ASR, ///< all the above and assertions
5055 GC_XDSU, ///< only registers calculated with FULL_XDSU
5056 GC_END, ///< number of chain types
5057 GC_DIRTY_ALL = (1 << (2*GC_END))-1, ///< bitmask to represent all chains
5058};
5059
5060//-------------------------------------------------------------------------
5061/// Control flow graph of microcode.
5063{
5064 mba_t *mba; ///< pointer to the mbl array
5065 int dirty = GC_DIRTY_ALL; ///< what kinds of use-def chains are dirty?
5066 int chain_stamp = 0; ///< we increment this counter each time chains are recalculated
5067 graph_chains_t gcs[2*GC_END]; ///< cached use-def chains
5068
5069 /// Is LIST accessed between two instructions?
5070 /// This function can analyze all path between the specified instructions
5071 /// and find if the specified list is used in any of them. The instructions
5072 /// may be located in different basic blocks. This function does not use
5073 /// use-def chains but use the graph for analysis. It may be slow in some
5074 /// cases but its advantage is that is does not require building the use-def
5075 /// chains.
5076 /// \param list list to verify
5077 /// \param b1 starting block
5078 /// \param b2 ending block. may be -1, it means all possible paths from b1
5079 /// \param m1 starting instruction (in b1)
5080 /// \param m2 ending instruction (in b2). excluded. may be nullptr.
5081 /// \param access_type read or write access?
5082 /// \param maymust may access or must access?
5083 /// \return true if found an access to the list
5084 bool hexapi is_accessed_globally(
5085 const mlist_t &list, // list to verify
5086 int b1, // starting block
5087 int b2, // ending block
5088 const minsn_t *m1, // starting instruction (in b1)
5089 const minsn_t *m2, // ending instruction (in b2)
5090 access_type_t access_type,
5091 maymust_t maymust) const;
5092 int get_ud_gc_idx(gctype_t gctype) const { return (gctype << 1); }
5093 int get_du_gc_idx(gctype_t gctype) const { return (gctype << 1)+1; }
5094 int get_ud_dirty_bit(gctype_t gctype) { return 1 << get_ud_gc_idx(gctype); }
5095 int get_du_dirty_bit(gctype_t gctype) { return 1 << get_du_gc_idx(gctype); }
5096
5097public:
5098 /// Is the use-def chain of the specified kind dirty?
5100 {
5101 int bit = get_ud_dirty_bit(gctype);
5102 return (dirty & bit) != 0;
5103 }
5104
5105 /// Is the def-use chain of the specified kind dirty?
5107 {
5108 int bit = get_du_dirty_bit(gctype);
5109 return (dirty & bit) != 0;
5110 }
5111 int get_chain_stamp() const { return chain_stamp; }
5112
5113 /// Get use-def chains.
5114 graph_chains_t *hexapi get_ud(gctype_t gctype);
5115
5116 /// Get def-use chains.
5117 graph_chains_t *hexapi get_du(gctype_t gctype);
5118
5119 /// Is LIST redefined in the graph?
5120 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
5121 { return is_accessed_globally(list, b1, b2, m1, m2, WRITE_ACCESS, maymust); }
5122
5123 /// Is LIST used in the graph?
5124 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
5125 { return is_accessed_globally(list, b1, b2, m1, m2, READ_ACCESS, maymust); }
5126
5127 mblock_t *get_mblock(int n) const { return mba->get_mblock(n); }
5128};
5129
5130//-------------------------------------------------------------------------
5131// Helper for codegen_t. It takes into account delay slots
5133{
5134 const mba_t *mba; // to check range
5135 ea_t ea = BADADDR; // next insn to decode
5136 ea_t end = BADADDR; // end of the block
5137 ea_t dslot = BADADDR; // address of the insn in the delay slot
5138 insn_t dslot_insn; // instruction in the delay slot
5139 ea_t severed_branch = BADADDR; // address of the severed branch insn
5140 // (when this branch insn ends the previous block)
5141 bool is_likely_dslot = false; // execute delay slot only when jumping
5142
5143 cdg_insn_iterator_t(const mba_t *mba_) : mba(mba_) {}
5144 cdg_insn_iterator_t(const cdg_insn_iterator_t &r) = default;
5145 cdg_insn_iterator_t &operator=(const cdg_insn_iterator_t &r) = default;
5146
5147 bool ok() const { return ea < end; }
5148 bool has_dslot() const { return dslot != BADADDR; }
5149 bool dslot_with_xrefs() const { return dslot >= end; }
5150 // the current insn is the severed delayed insn (when this starts a block)
5151 bool is_severed_dslot() const { return severed_branch != BADADDR; }
5152 void start(const range_t &rng)
5153 {
5154 ea = rng.start_ea;
5155 end = rng.end_ea;
5156 }
5157 merror_t hexapi next(insn_t *ins);
5158};
5159
5160//-------------------------------------------------------------------------
5161/// Helper class to generate the initial microcode
5163{
5164public:
5165 mba_t *mba; // ptr to mbl array
5166 mblock_t *mb = nullptr; // current basic block
5167 insn_t insn; // instruction to generate microcode for
5168 char ignore_micro = IM_NONE; // value of get_ignore_micro() for the insn
5169 cdg_insn_iterator_t ii; // instruction iterator
5170 size_t reserved;
5171
5172 codegen_t() = delete;
5173 virtual ~codegen_t()
5174 {
5175 }
5176
5177 /// Analyze prolog/epilog of the function to decompile.
5178 /// If prolog is found, allocate and fill 'mba->pi' structure.
5179 /// \param fc flow chart
5180 /// \param reachable bitmap of reachable blocks
5181 /// \return error code
5182 virtual merror_t idaapi analyze_prolog(
5183 const class qflow_chart_t &fc,
5184 const class bitset_t &reachable) = 0;
5185
5186 /// Generate microcode for one instruction.
5187 /// The instruction is in INSN
5188 /// \return MERR_OK - all ok
5189 /// MERR_BLOCK - all ok, need to switch to new block
5190 /// MERR_BADBLK - delete current block and continue
5191 /// other error codes are fatal
5192 virtual merror_t idaapi gen_micro() = 0;
5193
5194 /// Generate microcode to load one operand.
5195 /// \param opnum number of INSN operand
5196 /// \param flags reserved for future use
5197 /// \return register containing the operand.
5198 virtual mreg_t idaapi load_operand(int opnum, int flags=0) = 0;
5199
5200 /// This method is called when the microcode generation is done
5201 virtual void idaapi microgen_completed() {}
5202
5203 /// Setup internal data to handle new instruction.
5204 /// This method should be called before calling gen_micro().
5205 /// Usually gen_micro() is called by the decompiler. You have to call this
5206 /// function explicitly only if you yourself call gen_micro().
5207 /// The instruction is in INSN
5208 /// \return MERR_OK - all ok
5209 /// other error codes are fatal
5210 virtual merror_t idaapi prepare_gen_micro() { return MERR_OK; }
5211
5212 /// Generate microcode to calculate the address of a memory operand.
5213 /// \param n - number of INSN operand
5214 /// \param flags - reserved for future use
5215 /// \return register containing the operand address.
5216 /// mr_none - failed (not a memory operand)
5217 virtual mreg_t idaapi load_effective_address(int n, int flags=0) = 0;
5218
5219 /// Generate microcode to store an operand.
5220 /// In case of success an arbitrary number of instructions can be
5221 /// generated (and even no instruction if the source and target are the same)
5222 /// \param n - number of target INSN operand
5223 /// \param mop - operand to be stored
5224 /// \param flags - reserved for future use
5225 /// \param outins - (OUT) the last generated instruction
5226 // (nullptr if no instruction was generated)
5227 /// \return success
5228 virtual bool idaapi store_operand(int n, const mop_t &mop, int flags=0, minsn_t **outins=nullptr);
5229
5230 /// Emit one microinstruction.
5231 /// The L, R, D arguments usually mean the register number. However, they depend
5232 /// on CODE. For example:
5233 /// - for m_goto and m_jcnd L is the target address
5234 /// - for m_ldc L is the constant value to load
5235 /// \param code instruction opcode
5236 /// \param width operand size in bytes
5237 /// \param l left operand
5238 /// \param r right operand
5239 /// \param d destination operand
5240 /// \param offsize for ldx/stx, the size of the offset operand
5241 /// for ldc, operand number of the constant value
5242 /// -1, set the FP instruction (e.g. for m_mov)
5243 /// \return created microinstruction. can be nullptr if the instruction got
5244 /// immediately optimized away.
5245 minsn_t *hexapi emit(mcode_t code, int width, uval_t l, uval_t r, uval_t d, int offsize);
5246
5247 /// Emit one microinstruction.
5248 /// This variant takes a data type not a size.
5250 mcode_t code,
5251 op_dtype_t dtype,
5252 uval_t l,
5253 uval_t r,
5254 uval_t d,
5255 int offsize)
5256 {
5257 return emit(code, get_dtype_size(dtype), l, r, d, offsize);
5258 }
5259
5260 /// Emit one microinstruction.
5261 /// This variant accepts pointers to operands. It is more difficult to use
5262 /// but permits to create virtually any instruction. Operands may be nullptr
5263 /// when it makes sense.
5264 minsn_t *hexapi emit(mcode_t code, const mop_t *l, const mop_t *r, const mop_t *d);
5265
5266};
5267
5268//-------------------------------------------------------------------------
5269/// Parse DIRECTIVE and update the current configuration variables.
5270/// For the syntax see hexrays.cfg
5271bool hexapi change_hexrays_config(const char *directive);
5272
5273//-------------------------------------------------------------------------
5275{
5276 t = mop_d;
5277 d = ins;
5278}
5279
5280inline bool mop_t::has_side_effects(bool include_ldx_and_divs) const
5281{
5282 return is_insn() && d->has_side_effects(include_ldx_and_divs);
5283}
5284
5285inline bool mop_t::is_kreg() const
5286{
5287 return t == mop_r && ::is_kreg(r);
5288}
5289
5290inline minsn_t *mop_t::get_insn(mcode_t code)
5291{
5292 return is_insn(code) ? d : nullptr;
5293}
5294inline const minsn_t *mop_t::get_insn(mcode_t code) const
5295{
5296 return is_insn(code) ? d : nullptr;
5297}
5298
5299inline bool mop_t::is_insn(mcode_t code) const
5300{
5301 return is_insn() && d->opcode == code;
5302}
5303
5304inline bool mop_t::is_glbaddr() const
5305{
5306 return t == mop_a && a->t == mop_v;
5307}
5308
5309inline bool mop_t::is_glbaddr(ea_t ea) const
5310{
5311 return is_glbaddr() && a->g == ea;
5312}
5313
5314inline bool mop_t::is_stkaddr() const
5315{
5316 return t == mop_a && a->t == mop_S;
5317}
5318
5319inline vivl_t::vivl_t(const chain_t &ch)
5320 : voff_t(ch.key().type, ch.is_reg() ? ch.get_reg() : ch.get_stkoff()),
5321 size(ch.width)
5322{
5323}
5324
5325// The following memory regions exist
5326// start length
5327// ------------------------ ---------
5328// lvars spbase stacksize
5329// retaddr spbase+stacksize retsize
5330// shadow spbase+stacksize+retsize shadow_args
5331// args inargoff MAX_FUNC_ARGS*sp_width-shadow_args
5332// globals data_segment sizeof_data_segment
5333// heap everything else?
5334
5336{
5337 return std_ivls[idx].ivl;
5338}
5339
5340inline const ivl_t &mba_t::get_lvars_region() const
5341{
5343}
5344
5345inline const ivl_t &mba_t::get_shadow_region() const
5346{
5348}
5349
5350inline const ivl_t &mba_t::get_args_region() const
5351{
5352 return get_std_region(MMIDX_ARGS);
5353}
5354
5355inline ivl_t mba_t::get_stack_region() const
5356{
5357 return ivl_t(std_ivls[MMIDX_LVARS].ivl.off, fullsize);
5358}
5359
5360//-------------------------------------------------------------------------
5361/// Get decompiler version.
5362/// The returned string is of the form <major>.<minor>.<revision>.<build-date>
5363/// \return pointer to version string. For example: "2.0.0.140605"
5364
5365const char *hexapi get_hexrays_version();
5366
5367
5368/// Check out a floating decompiler license.
5369/// This function will display a dialog box if the license is not available.
5370/// For non-floating licenses this function is effectively no-op.
5371/// It is not necessary to call this function before decompiling.
5372/// If the license was not checked out, the decompiler will automatically do it.
5373/// This function can be used to check out a license in advance and ensure
5374/// that a license is available.
5375/// \param silent silently fail if the license cannot be checked out.
5376/// \return false if failed
5377
5378bool hexapi checkout_hexrays_license(bool silent);
5379
5380/// \defgroup OPF_ open_pseudocode flags
5381/// Used in open_pseudocode
5382///@{
5383#define OPF_REUSE 0x00 ///< reuse existing window
5384#define OPF_NEW_WINDOW 0x01 ///< open new window
5385#define OPF_REUSE_ACTIVE 0x02 ///< reuse existing window, only if the
5386 ///< currently active widget is a pseudocode view
5387#define OPF_NO_WAIT 0x08 ///< do not display waitbox if decompilation happens
5388///@}
5389
5390#define OPF_WINDOW_MGMT_MASK 0x07
5391
5392
5393/// Open pseudocode window.
5394/// The specified function is decompiled and the pseudocode window is opened.
5395/// \param ea function to decompile
5396/// \param flags: a combination of OPF_ flags
5397/// \return false if failed
5398
5399vdui_t *hexapi open_pseudocode(ea_t ea, int flags);
5400
5401
5402/// Close pseudocode window.
5403/// \param f pointer to window
5404/// \return false if failed
5405
5407
5408
5409/// Get the vdui_t instance associated to the TWidget
5410/// \param f pointer to window
5411/// \return a vdui_t *, or nullptr
5412
5414
5415
5416/// \defgroup VDRUN_ Batch decompilation bits
5417///@{
5418#define VDRUN_NEWFILE 0x00000000 ///< Create a new file or overwrite existing file
5419#define VDRUN_APPEND 0x00000001 ///< Create a new file or append to existing file
5420#define VDRUN_ONLYNEW 0x00000002 ///< Fail if output file already exists
5421#define VDRUN_SILENT 0x00000004 ///< Silent decompilation
5422#define VDRUN_SENDIDB 0x00000008 ///< Send problematic databases to hex-rays.com
5423#define VDRUN_MAYSTOP 0x00000010 ///< The user can cancel decompilation
5424#define VDRUN_CMDLINE 0x00000020 ///< Called from ida's command line
5425#define VDRUN_STATS 0x00000040 ///< Print statistics into vd_stats.txt
5426#define VDRUN_LUMINA 0x00000080 ///< Use lumina server
5427///@}
5428
5429/// Batch decompilation.
5430/// Decompile all or the specified functions
5431/// \return true if no internal error occurred and the user has not cancelled decompilation
5432/// \param outfile name of the output file
5433/// \param funcaddrs list of functions to decompile.
5434/// If nullptr or empty, then decompile all nonlib functions
5435/// \param flags \ref VDRUN_
5436
5437bool hexapi decompile_many(const char *outfile, const eavec_t *funcaddrs, int flags);
5438
5439
5440/// Exception object: decompiler failure information
5442{
5443 merror_t code = MERR_OK; ///< \ref MERR_
5444 ea_t errea = BADADDR; ///< associated address
5445 qstring str; ///< string information
5447 hexrays_failure_t(merror_t c, ea_t ea, const char *buf=nullptr) : code(c), errea(ea), str(buf) {}
5448 hexrays_failure_t(merror_t c, ea_t ea, const qstring &buf) : code(c), errea(ea), str(buf) {}
5449 qstring hexapi desc() const;
5450 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
5451};
5452
5453/// Exception object: decompiler exception
5454struct vd_failure_t : public std::exception
5455{
5457 vd_failure_t() {}
5458 vd_failure_t(merror_t code, ea_t ea, const char *buf=nullptr) : hf(code, ea, buf) {}
5459 vd_failure_t(merror_t code, ea_t ea, const qstring &buf) : hf(code, ea, buf) {}
5460 vd_failure_t(const hexrays_failure_t &_hf) : hf(_hf) {}
5461 qstring desc() const { return hf.desc(); }
5462#ifdef __GNUC__
5463 ~vd_failure_t() throw() {}
5464#endif
5465 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
5466};
5467
5468/// Exception object: decompiler internal error
5470{
5471 vd_interr_t(ea_t ea, const qstring &buf) : vd_failure_t(MERR_INTERR, ea, buf) {}
5472 vd_interr_t(ea_t ea, const char *buf) : vd_failure_t(MERR_INTERR, ea, buf) {}
5473};
5474
5475/// Send the database to Hex-Rays.
5476/// This function sends the current database to the Hex-Rays server.
5477/// The database is sent in the compressed form over an encrypted (SSL) connection.
5478/// \param err failure description object. Empty hexrays_failure_t object can
5479/// be used if error information is not available.
5480/// \param silent if false, a dialog box will be displayed before sending the database.
5481
5482void hexapi send_database(const hexrays_failure_t &err, bool silent);
5483
5484/// Result of get_current_operand()
5486{
5487 qstring name; ///< register or stkvar name
5488 union
5489 {
5490 sval_t stkoff; ///< if stkvar, stack offset
5491 int regnum; ///< if register, the register id
5492 };
5493 int size; ///< operand size
5494 int flags;
5495#define GCO_STK 0x0000 ///< a stack variable
5496#define GCO_REG 0x0001 ///< is register? otherwise a stack variable
5497#define GCO_USE 0x0002 ///< is source operand?
5498#define GCO_DEF 0x0004 ///< is destination operand?
5499 bool is_reg() const { return (flags & GCO_REG) != 0; }
5500 bool is_use() const { return (flags & GCO_USE) != 0; }
5501 bool is_def() const { return (flags & GCO_DEF) != 0; }
5502
5503 /// Append operand info to LIST.
5504 /// This function converts IDA register number or stack offset to
5505 /// a decompiler list.
5506 /// \param list list to append to
5507 /// \param mba microcode object
5508 bool hexapi append_to_list(mlist_t *list, const mba_t *mba) const;
5509
5510 /// Convert operand info to VIVL.
5511 /// The returned VIVL can be used, for example, in a call of
5512 /// get_valranges().
5514 {
5515 vivl_t ret;
5516 if ( is_reg() )
5517 ret.set_reg(regnum, size);
5518 else
5519 ret.set_stkoff(stkoff, size);
5520 return ret;
5521 }
5522};
5523
5524/// Get the instruction operand under the cursor.
5525/// This function determines the operand that is under the cursor in the active
5526/// disassembly listing. If the operand refers to a register or stack variable,
5527/// it returns true.
5528/// \param out[out] output buffer
5530
5531void hexapi remitem(const citem_t *e);
5532//-------------------------------------------------------------------------
5533/// Ctree item code. At the beginning of this list there are expression
5534/// codes (cot_...), followed by statement codes (cit_...).
5536{
5537 cot_empty = 0,
5538 cot_comma = 1, ///< x, y
5539 cot_asg = 2, ///< x = y
5540 cot_asgbor = 3, ///< x |= y
5541 cot_asgxor = 4, ///< x ^= y
5542 cot_asgband = 5, ///< x &= y
5543 cot_asgadd = 6, ///< x += y
5544 cot_asgsub = 7, ///< x -= y
5545 cot_asgmul = 8, ///< x *= y
5546 cot_asgsshr = 9, ///< x >>= y signed
5547 cot_asgushr = 10, ///< x >>= y unsigned
5548 cot_asgshl = 11, ///< x <<= y
5549 cot_asgsdiv = 12, ///< x /= y signed
5550 cot_asgudiv = 13, ///< x /= y unsigned
5551 cot_asgsmod = 14, ///< x %= y signed
5552 cot_asgumod = 15, ///< x %= y unsigned
5553 cot_tern = 16, ///< x ? y : z
5554 cot_lor = 17, ///< x || y
5555 cot_land = 18, ///< x && y
5556 cot_bor = 19, ///< x | y
5557 cot_xor = 20, ///< x ^ y
5558 cot_band = 21, ///< x & y
5559 cot_eq = 22, ///< x == y int or fpu (see EXFL_FPOP)
5560 cot_ne = 23, ///< x != y int or fpu (see EXFL_FPOP)
5561 cot_sge = 24, ///< x >= y signed or fpu (see EXFL_FPOP)
5562 cot_uge = 25, ///< x >= y unsigned
5563 cot_sle = 26, ///< x <= y signed or fpu (see EXFL_FPOP)
5564 cot_ule = 27, ///< x <= y unsigned
5565 cot_sgt = 28, ///< x > y signed or fpu (see EXFL_FPOP)
5566 cot_ugt = 29, ///< x > y unsigned
5567 cot_slt = 30, ///< x < y signed or fpu (see EXFL_FPOP)
5568 cot_ult = 31, ///< x < y unsigned
5569 cot_sshr = 32, ///< x >> y signed
5570 cot_ushr = 33, ///< x >> y unsigned
5571 cot_shl = 34, ///< x << y
5572 cot_add = 35, ///< x + y
5573 cot_sub = 36, ///< x - y
5574 cot_mul = 37, ///< x * y
5575 cot_sdiv = 38, ///< x / y signed
5576 cot_udiv = 39, ///< x / y unsigned
5577 cot_smod = 40, ///< x % y signed
5578 cot_umod = 41, ///< x % y unsigned
5579 cot_fadd = 42, ///< x + y fp
5580 cot_fsub = 43, ///< x - y fp
5581 cot_fmul = 44, ///< x * y fp
5582 cot_fdiv = 45, ///< x / y fp
5583 cot_fneg = 46, ///< -x fp
5584 cot_neg = 47, ///< -x
5585 cot_cast = 48, ///< (type)x
5586 cot_lnot = 49, ///< !x
5587 cot_bnot = 50, ///< ~x
5588 cot_ptr = 51, ///< *x, access size in 'ptrsize'
5589 cot_ref = 52, ///< &x
5590 cot_postinc = 53, ///< x++
5591 cot_postdec = 54, ///< x--
5592 cot_preinc = 55, ///< ++x
5593 cot_predec = 56, ///< --x
5594 cot_call = 57, ///< x(...)
5595 cot_idx = 58, ///< x[y]
5596 cot_memref = 59, ///< x.m
5597 cot_memptr = 60, ///< x->m, access size in 'ptrsize'
5598 cot_num = 61, ///< n
5599 cot_fnum = 62, ///< fpc
5600 cot_str = 63, ///< string constant (user representation)
5601 cot_obj = 64, ///< obj_ea
5602 cot_var = 65, ///< v
5603 cot_insn = 66, ///< instruction in expression, internal representation only
5604 cot_sizeof = 67, ///< sizeof(x)
5605 cot_helper = 68, ///< arbitrary name
5606 cot_type = 69, ///< arbitrary type
5607 cot_last = cot_type,
5608 cit_empty = 70, ///< instruction types start here
5609 cit_block = 71, ///< block-statement: { ... }
5610 cit_expr = 72, ///< expression-statement: expr;
5611 cit_if = 73, ///< if-statement
5612 cit_for = 74, ///< for-statement
5613 cit_while = 75, ///< while-statement
5614 cit_do = 76, ///< do-statement
5615 cit_switch = 77, ///< switch-statement
5616 cit_break = 78, ///< break-statement
5617 cit_continue = 79, ///< continue-statement
5618 cit_return = 80, ///< return-statement
5619 cit_goto = 81, ///< goto-statement
5620 cit_asm = 82, ///< asm-statement
5621 cit_end
5622};
5623
5624/// Negate a comparison operator. For example, \ref cot_sge becomes \ref cot_slt
5626/// Swap a comparison operator. For example, \ref cot_sge becomes \ref cot_sle
5628/// Get operator sign. Meaningful for sign-dependent operators, like \ref cot_sdiv
5629type_sign_t hexapi get_op_signness(ctype_t op);
5630/// Convert plain operator into assignment operator. For example, \ref cot_add returns \ref cot_asgadd
5632/// Convert assignment operator into plain operator. For example, \ref cot_asgadd returns \ref cot_add
5633/// \return cot_empty is the input operator is not an assignment operator.
5635/// Does operator use the 'x' field of cexpr_t?
5636inline bool op_uses_x(ctype_t op) { return (op >= cot_comma && op <= cot_memptr) || op == cot_sizeof; }
5637/// Does operator use the 'y' field of cexpr_t?
5638inline bool op_uses_y(ctype_t op) { return (op >= cot_comma && op <= cot_fdiv) || op == cot_idx; }
5639/// Does operator use the 'z' field of cexpr_t?
5640inline bool op_uses_z(ctype_t op) { return op == cot_tern; }
5641/// Is binary operator?
5642inline bool is_binary(ctype_t op) { return op_uses_y(op) && op != cot_tern; } // x,y
5643/// Is unary operator?
5644inline bool is_unary(ctype_t op) { return op >= cot_fneg && op <= cot_predec; }
5645/// Is comparison operator?
5646inline bool is_relational(ctype_t op) { return op >= cot_eq && op <= cot_ult; }
5647/// Is assignment operator?
5648inline bool is_assignment(ctype_t op) { return op >= cot_asg && op <= cot_asgumod; }
5649// Can operate on UDTs?
5650inline bool accepts_udts(ctype_t op) { return op == cot_asg || op == cot_comma || op > cot_last; }
5651/// Is pre/post increment/decrement operator?
5652inline bool is_prepost(ctype_t op) { return op >= cot_postinc && op <= cot_predec; }
5653/// Is commutative operator?
5655{
5656 return op == cot_bor
5657 || op == cot_xor
5658 || op == cot_band
5659 || op == cot_add
5660 || op == cot_mul
5661 || op == cot_fadd
5662 || op == cot_fmul
5663 || op == cot_ne
5664 || op == cot_eq;
5665}
5666/// Is additive operator?
5667inline bool is_additive(ctype_t op)
5668{
5669 return op == cot_add
5670 || op == cot_sub
5671 || op == cot_fadd
5672 || op == cot_fsub;
5673}
5674/// Is multiplicative operator?
5676{
5677 return op == cot_mul
5678 || op == cot_sdiv
5679 || op == cot_udiv
5680 || op == cot_fmul
5681 || op == cot_fdiv;
5682}
5683
5684/// Is bit related operator?
5685inline bool is_bitop(ctype_t op)
5686{
5687 return op == cot_bor
5688 || op == cot_xor
5689 || op == cot_band
5690 || op == cot_bnot;
5691}
5692
5693/// Is logical operator?
5694inline bool is_logical(ctype_t op)
5695{
5696 return op == cot_lor
5697 || op == cot_land
5698 || op == cot_lnot;
5699}
5700
5701/// Is loop statement code?
5702inline bool is_loop(ctype_t op)
5703{
5704 return op == cit_for
5705 || op == cit_while
5706 || op == cit_do;
5707}
5708/// Does a break statement influence the specified statement code?
5710{
5711 return is_loop(op) || op == cit_switch;
5712}
5713
5714/// Is Lvalue operator?
5715inline bool is_lvalue(ctype_t op)
5716{
5717 return op == cot_ptr // *x
5718 || op == cot_idx // x[y]
5719 || op == cot_memref // x.m
5720 || op == cot_memptr // x->m
5721 || op == cot_obj // v
5722 || op == cot_var; // l
5723}
5724
5725/// Is the operator allowed on small structure or union?
5727{
5728 return op == cit_return
5729 || op == cot_asg
5730 || op == cot_eq
5731 || op == cot_ne
5732 || op == cot_comma
5733 || op == cot_tern
5734 || (op > cot_last && op < cit_end); // any insn
5735}
5736
5737/// An immediate number
5739{
5740 uint64 _value = 0; ///< its value
5741 number_format_t nf; ///< how to represent it
5742 cnumber_t(int _opnum=0) : nf(_opnum) {}
5743
5744 /// Get text representation
5745 /// \param vout output buffer
5746 /// \param type number type
5747 /// \param parent parent expression
5748 /// \param nice_stroff out: printed as stroff expression
5749 void hexapi print(
5750 qstring *vout,
5751 const tinfo_t &type,
5752 const citem_t *parent=nullptr,
5753 bool *nice_stroff=nullptr) const;
5754
5755 /// Get value.
5756 /// This function will properly extend the number sign to 64bits
5757 /// depending on the type sign.
5758 uint64 hexapi value(const tinfo_t &type) const;
5759
5760 /// Assign new value
5761 /// \param v new value
5762 /// \param nbytes size of the new value in bytes
5763 /// \param sign sign of the value
5764 void hexapi assign(uint64 v, int nbytes, type_sign_t sign);
5765
5766 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
5767 DECLARE_COMPARISONS(cnumber_t);
5768};
5769
5770/// Reference to a local variable
5772{
5773 mba_t *mba; ///< pointer to the underlying micro array
5774 int idx; ///< index into lvars_t
5775 lvar_t &getv() const { return mba->vars[idx]; }
5776 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
5777 DECLARE_COMPARISONS(var_ref_t);
5778};
5779
5780/// Vector of parents
5781typedef qvector<citem_t *> ctree_items_t;
5782typedef ctree_items_t parents_t;
5783
5784/// A generic helper class that is used for ctree traversal.
5785/// When traversing the ctree, the currently visited ctree item and its children
5786/// can be freely modified without interrupting the traversal. However, if a
5787/// parent of the visited item is modified, the traversal must be immediately
5788/// stopped by returning a non-zero value.
5790{
5791 int cv_flags; ///< \ref CV_
5792/// \defgroup CV_ Ctree visitor property bits
5793/// Used in ctree_visitor_t::cv_flags
5794///@{
5795#define CV_FAST 0x0000 ///< do not maintain parent information
5796#define CV_PRUNE 0x0001 ///< this bit is set by visit...() to prune the walk
5797#define CV_PARENTS 0x0002 ///< maintain parent information
5798#define CV_POST 0x0004 ///< call the leave...() functions
5799#define CV_RESTART 0x0008 ///< restart enumeration at the top expr (apply_to_exprs)
5800#define CV_INSNS 0x0010 ///< visit only statements, prune all expressions
5801 ///< do not use before the final ctree maturity because
5802 ///< expressions may contain statements at intermediate
5803 ///< stages (see cot_insn). Otherwise you risk missing
5804 ///< statements embedded into expressions.
5805///@}
5806 /// Should the parent information by maintained?
5807 bool maintain_parents() const { return (cv_flags & CV_PARENTS) != 0; }
5808 /// Should the traversal skip the children of the current item?
5809 bool must_prune() const { return (cv_flags & CV_PRUNE) != 0; }
5810 /// Should the traversal restart?
5811 bool must_restart() const { return (cv_flags & CV_RESTART) != 0; }
5812 /// Should the leave...() functions be called?
5813 bool is_postorder() const { return (cv_flags & CV_POST) != 0; }
5814 /// Should all expressions be automatically pruned?
5815 bool only_insns() const { return (cv_flags & CV_INSNS) != 0; }
5816 /// Prune children.
5817 /// This function may be called by a visitor() to skip all children of the current item.
5818 void prune_now() { cv_flags |= CV_PRUNE; }
5819 /// Do not prune children. This is an internal function, no need to call it.
5820 void clr_prune() { cv_flags &= ~CV_PRUNE; }
5821 /// Restart the travesal. Meaningful only in apply_to_exprs()
5822 void set_restart() { cv_flags |= CV_RESTART; }
5823 /// Do not restart. This is an internal function, no need to call it.
5824 void clr_restart() { cv_flags &= ~CV_RESTART; }
5825
5826 parents_t parents; ///< Vector of parents of the current item
5827
5828 /// Constructor.
5829 /// This constructor can be used with CV_FAST, CV_PARENTS
5830 /// combined with CV_POST, CV_ONLYINS
5831 ctree_visitor_t(int _flags) : cv_flags(_flags) {}
5832
5833 virtual ~ctree_visitor_t() {}
5834 /// Traverse ctree.
5835 /// The traversal will start at the specified item and continue until
5836 /// of one the visit_...() functions return a non-zero value.
5837 /// \param item root of the ctree to traverse
5838 /// \param parent parent of the specified item. can be specified as nullptr.
5839 /// \return 0 or a non-zero value returned by a visit_...() function
5840 int hexapi apply_to(citem_t *item, citem_t *parent);
5841
5842 /// Traverse only expressions.
5843 /// The traversal will start at the specified item and continue until
5844 /// of one the visit_...() functions return a non-zero value.
5845 /// \param item root of the ctree to traverse
5846 /// \param parent parent of the specified item. can be specified as nullptr.
5847 /// \return 0 or a non-zero value returned by a visit_...() function
5848 int hexapi apply_to_exprs(citem_t *item, citem_t *parent);
5849
5850 /// Get parent of the current item as an expression
5851 cexpr_t *parent_expr() { return (cexpr_t *)parents.back(); }
5852 /// Get parent of the current item as a statement
5853 cinsn_t *parent_insn() { return (cinsn_t *)parents.back(); }
5854
5855 // the following functions are redefined by the derived class
5856 // in order to perform the desired actions during the traversal
5857
5858 /// Visit a statement.
5859 /// This is a visitor function which should be overridden by a derived
5860 /// class to do some useful work.
5861 /// This visitor performs pre-order traserval, i.e. an item is visited before
5862 /// its children.
5863 /// \return 0 to continue the traversal, nonzero to stop.
5864 virtual int idaapi visit_insn(cinsn_t *) { return 0; }
5865
5866 /// Visit an expression.
5867 /// This is a visitor function which should be overridden by a derived
5868 /// class to do some useful work.
5869 /// This visitor performs pre-order traserval, i.e. an item is visited before
5870 /// its children.
5871 /// \return 0 to continue the traversal, nonzero to stop.
5872 virtual int idaapi visit_expr(cexpr_t *) { return 0; }
5873
5874 /// Visit a statement after having visited its children.
5875 /// This is a visitor function which should be overridden by a derived
5876 /// class to do some useful work.
5877 /// This visitor performs post-order traserval, i.e. an item is visited after
5878 /// its children.
5879 /// \return 0 to continue the traversal, nonzero to stop.
5880 virtual int idaapi leave_insn(cinsn_t *) { return 0; }
5881
5882 /// Visit an expression after having visited its children.
5883 /// This is a visitor function which should be overridden by a derived
5884 /// class to do some useful work.
5885 /// This visitor performs post-order traserval, i.e. an item is visited after
5886 /// its children.
5887 /// \return 0 to continue the traversal, nonzero to stop.
5888 virtual int idaapi leave_expr(cexpr_t *) { return 0; }
5889
5890 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
5891};
5892
5893/// A helper ctree traversal class that maintains parent information
5895{
5896 ctree_parentee_t(bool post=false)
5897 : ctree_visitor_t((post ? CV_POST : 0)|CV_PARENTS) {}
5898
5899 /// Recalculate type of parent nodes.
5900 /// If a node type has been changed, the visitor must recalculate
5901 /// all parent types, otherwise the ctree becomes inconsistent.
5902 /// If during this recalculation a parent node is added/deleted,
5903 /// this function returns true. In this case the traversal must be
5904 /// stopped because the information about parent nodes is stale.
5905 /// \return false-ok to continue the traversal, true-must stop.
5906 bool hexapi recalc_parent_types();
5907
5908 /// Get pointer to the parent block of the currently visited item.
5909 /// This function should be called only when the parent is a block.
5910 cblock_t *get_block();
5911};
5912
5913/// Class to traverse the whole function.
5915{
5916 cfunc_t *func; ///< Pointer to current function
5917 cfunc_parentee_t(cfunc_t *f, bool post=false)
5918 : ctree_parentee_t(post), func(f) {}
5919
5920 /// Calculate rvalue type.
5921 /// This function tries to determine the type of the specified item
5922 /// based on its context. For example, if the current expression is the
5923 /// right side of an assignment operator, the type
5924 /// of its left side will be returned. This function can be used to determine the 'best'
5925 /// type of the specified expression.
5926 /// \param[in] e expression to determine the desired type
5927 /// \param[out] target 'best' type of the expression will be returned here
5928 /// \return false if failed
5929 bool hexapi calc_rvalue_type(tinfo_t *target, const cexpr_t *e);
5930};
5931
5932/// Ctree maturity level. The level will increase
5933/// as we switch from one phase of ctree generation to the next one
5935{
5936 CMAT_ZERO, ///< does not exist
5937 CMAT_BUILT, ///< just generated
5938 CMAT_TRANS1, ///< applied first wave of transformations
5939 CMAT_NICE, ///< nicefied expressions
5940 CMAT_TRANS2, ///< applied second wave of transformations
5941 CMAT_CPA, ///< corrected pointer arithmetic
5942 CMAT_TRANS3, ///< applied third wave of transformations
5943 CMAT_CASTED, ///< added necessary casts
5944 CMAT_FINAL, ///< ready-to-use
5945};
5946
5947//--------------------------------------------------------------------------
5948/// Comment item preciser.
5949/// Item preciser is used to assign comments to ctree items
5950/// A ctree item may have several comments attached to it. For example,
5951/// an if-statement may have the following comments: <pre>
5952/// if ( ... ) // cmt1
5953/// { // cmt2
5954/// } // cmt3
5955/// else // cmt4
5956/// { -- usually the else block has a separate ea
5957/// } </pre>
5958/// The first 4 comments will have the same ea. In order to denote the exact
5959/// line for the comment, we store the item_preciser along with ea.
5961{
5962 // inner comments (comments within an expression)
5963 ITP_EMPTY, ///< nothing
5964 ITP_ARG1, ///< , (64 entries are reserved for 64 call arguments)
5965 ITP_ARG64 = ITP_ARG1+63, // ,
5966 ITP_BRACE1, // (
5967 ITP_INNER_LAST = ITP_BRACE1,
5968 // outer comments
5969 ITP_ASM, ///< __asm-line
5970 ITP_ELSE, ///< else-line
5971 ITP_DO, ///< do-line
5972 ITP_SEMI, ///< semicolon
5976 ITP_COLON, ///< : (label)
5977 ITP_BLOCK1, ///< opening block comment. this comment is printed before the item
5978 ///< (other comments are indented and printed after the item)
5979 ITP_BLOCK2, ///< closing block comment.
5980 ITP_CASE = 0x40000000, ///< bit for switch cases
5981 ITP_SIGN = 0x20000000, ///< if this bit is set too, then we have a negative case value
5982 // this is a hack, we better introduce special indexes for case values
5983 // case value >= ITP_CASE will be processed incorrectly
5984};
5985/// Ctree location. Used to denote comment locations.
5987{
5988 ea_t ea;
5989 item_preciser_t itp;
5990 bool operator < (const treeloc_t &r) const
5991 {
5992 return ea < r.ea
5993 || (ea == r.ea && itp < r.itp);
5994 }
5995 bool operator == (const treeloc_t &r) const
5996 {
5997 return ea == r.ea && itp == r.itp;
5998 }
5999 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
6000};
6001
6002/// Comment retrieval type.
6003/// Ctree remembers what comments have already been retrieved.
6004/// This is done because our mechanism of item_precisers is still
6005/// not perfect and in theory some listing lines cannot be told
6006/// apart. To avoid comment duplication, we remember if a comment
6007/// has already been used or not.
6009{
6010 RETRIEVE_ONCE, ///< Retrieve comment if it has not been used yet
6011 RETRIEVE_ALWAYS, ///< Retrieve comment even if it has been used
6012};
6013
6014/// Ctree item comment.
6015/// For each comment we remember its body and the fact of its retrieval
6016struct citem_cmt_t : public qstring
6017{
6018 mutable bool used = false; ///< the comment has been retrieved?
6019 citem_cmt_t() {}
6020 citem_cmt_t(const char *s) : qstring(s) {}
6021};
6022
6023// Comments are attached to tree locations:
6024typedef std::map<treeloc_t, citem_cmt_t> user_cmts_t;
6025
6026/// Generic ctree item locator. It can be used for instructions and some expression
6027/// types. However, we need more precise locators for other items (e.g. for numbers)
6029{
6030 ea_t ea; ///< citem address
6031 ctype_t op; ///< citem operation
6032 citem_locator_t() = delete;
6033public:
6034 citem_locator_t(ea_t _ea, ctype_t _op) : ea(_ea), op(_op) {}
6035 citem_locator_t(const citem_t *i);
6036 DECLARE_COMPARISONS(citem_locator_t);
6037 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
6038};
6039
6040// citem_t::iflags are attached to (ea,op) pairs
6041typedef std::map<citem_locator_t, int32> user_iflags_t;
6042
6043// union field selections
6044// they are represented as a vector of integers. each integer represents the
6045// number of union field (0 means the first union field, etc)
6046// the size of this vector is equal to the number of nested unions in the selection.
6047typedef std::map<ea_t, intvec_t> user_unions_t;
6048
6049//--------------------------------------------------------------------------
6051{
6052 int16 nbits; // total number of non-zero bits. we cannot guarantee that
6053 // they are zero. example: a random "int var" has nbits==32
6054 int16 sbits; // number of sign bits (they can be either 0 or 1, all of them)
6055 // if bits are known to be zeroes, they are not taken into account here
6056 // (in this case nbits should be reduced)
6057 // if bits are unknown and can be anything, they cannot be included
6058 // in sbits.
6059 // sbits==1 is a special case and should not be used
6060 bit_bound_t(int n=0, int s=0) : nbits(n), sbits(s) {}
6061};
6062
6063//--------------------------------------------------------------------------
6064/// Basic ctree item. This is an abstract class (but we don't use virtual
6065/// functions in ctree, so the compiler will not disallow you to create citem_t
6066/// instances). However, items of pure citem_t type must never be created.
6067/// Two classes, cexpr_t and cinsn_t are derived from it.
6069{
6070 ea_t ea = BADADDR; ///< address that corresponds to the item. may be BADADDR
6071 ctype_t op = cot_empty; ///< item type
6072 int label_num = -1; ///< label number. -1 means no label. items of the expression
6073 ///< types (cot_...) should not have labels at the final maturity
6074 ///< level, but at the intermediate levels any ctree item
6075 ///< may have a label. Labels must be unique. Usually
6076 ///< they correspond to the basic block numbers.
6077 mutable int index = -1; ///< an index in cfunc_t::treeitems.
6078 ///< meaningful only after print_func()
6079 citem_t(ctype_t o=cot_empty) : op(o) {}
6080 /// Swap two citem_t
6081 void swap(citem_t &r)
6082 {
6083 std::swap(ea, r.ea);
6084 std::swap(op, r.op);
6085 std::swap(label_num, r.label_num);
6086 }
6087 /// Is an expression?
6088 bool is_expr() const { return op <= cot_last; }
6089 /// Does the item contain an expression?
6090 bool hexapi contains_expr(const cexpr_t *e) const;
6091 /// Does the item contain a label?
6092 bool hexapi contains_label() const;
6093 /// Find parent of the specified item.
6094 /// \param sitem Item to find the parent of. The search will be performed
6095 /// among the children of the item pointed by \c this.
6096 /// \return nullptr if not found
6097 const citem_t *hexapi find_parent_of(const citem_t *sitem) const;
6098 citem_t *find_parent_of(const citem_t *item)
6099 { return CONST_CAST(citem_t*)((CONST_CAST(const citem_t*)(this))->find_parent_of(item)); }
6100 citem_t *hexapi find_closest_addr(ea_t _ea);
6101 void print1(qstring *vout, const cfunc_t *func) const;
6102 ~citem_t()
6103 {
6104 remitem(this);
6105 }
6106 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
6107};
6108DECLARE_TYPE_AS_MOVABLE(citem_t);
6109
6110/// Ctree item: expression.
6111/// Depending on the exact expression item type, various fields of this structure are used.
6112struct cexpr_t : public citem_t
6113{
6114 union
6115 {
6116 cnumber_t *n; ///< used for \ref cot_num
6117 fnumber_t *fpc; ///< used for \ref cot_fnum
6118 struct
6119 {
6120 union
6121 {
6122 var_ref_t v; ///< used for \ref cot_var
6123 ea_t obj_ea; ///< used for \ref cot_obj
6124 };
6125 int refwidth; ///< how many bytes are accessed? (-1: none)
6126 };
6127 struct
6128 {
6129 cexpr_t *x; ///< the first operand of the expression
6130 union
6131 {
6132 cexpr_t *y; ///< the second operand of the expression
6133 carglist_t *a;///< argument list (used for \ref cot_call)
6134 uint32 m; ///< member offset (used for \ref cot_memptr, \ref cot_memref)
6135 ///< for unions, the member number
6136 };
6137 union
6138 {
6139 cexpr_t *z; ///< the third operand of the expression
6140 int ptrsize; ///< memory access size (used for \ref cot_ptr, \ref cot_memptr)
6141 };
6142 };
6143 cinsn_t *insn; ///< an embedded statement, they are prohibited
6144 ///< at the final maturity stage (\ref CMAT_FINAL)
6145 char *helper; ///< helper name (used for \ref cot_helper)
6146 char *string; ///< utf8 string constant, user representation (used for \ref cot_str)
6147 };
6148 tinfo_t type; ///< expression type. must be carefully maintained
6149 uint32 exflags = 0; ///< \ref EXFL_
6150/// \defgroup EXFL_ Expression attributes
6151/// Used in cexpr_t::exflags
6152///@{
6153#define EXFL_CPADONE 0x0001 ///< pointer arithmetic correction done
6154#define EXFL_LVALUE 0x0002 ///< expression is lvalue even if it doesn't look like it
6155#define EXFL_FPOP 0x0004 ///< floating point operation
6156#define EXFL_ALONE 0x0008 ///< standalone helper
6157#define EXFL_CSTR 0x0010 ///< string literal
6158#define EXFL_PARTIAL 0x0020 ///< type of the expression is considered partial
6159#define EXFL_UNDEF 0x0040 ///< expression uses undefined value
6160#define EXFL_JUMPOUT 0x0080 ///< jump out-of-function
6161#define EXFL_VFTABLE 0x0100 ///< is ptr to vftable (used for \ref cot_memptr, \ref cot_memref)
6162#define EXFL_ALL 0x01FF ///< all currently defined bits
6163///@}
6164 /// Pointer arithmetic correction done for this expression?
6165 bool cpadone() const { return (exflags & EXFL_CPADONE) != 0; }
6166 bool is_odd_lvalue() const { return (exflags & EXFL_LVALUE) != 0; }
6167 bool is_fpop() const { return (exflags & EXFL_FPOP) != 0; }
6168 bool is_cstr() const { return (exflags & EXFL_CSTR) != 0; }
6169 bool is_type_partial() const { return (exflags & EXFL_PARTIAL) != 0; }
6170 bool is_undef_val() const { return (exflags & EXFL_UNDEF) != 0; }
6171 bool is_jumpout() const { return (exflags & EXFL_JUMPOUT) != 0; }
6172 bool is_vftable() const { return (exflags & EXFL_VFTABLE) != 0; }
6173
6174
6175 void set_cpadone() { exflags |= EXFL_CPADONE; }
6176 void set_vftable() { exflags |= EXFL_VFTABLE; }
6177 void set_type_partial(bool val = true)
6178 {
6179 if ( val )
6180 exflags |= EXFL_PARTIAL;
6181 else
6182 exflags &= ~EXFL_PARTIAL;
6183 }
6184
6185 cexpr_t() : x(nullptr), y(nullptr), z(nullptr) {}
6186 cexpr_t(ctype_t cexpr_op, cexpr_t *_x, cexpr_t *_y=nullptr, cexpr_t *_z=nullptr)
6187 : citem_t(cexpr_op), x(_x), y(_y), z(_z) {}
6188 cexpr_t(mba_t *mba, const lvar_t &v);
6189 cexpr_t(const cexpr_t &r) : citem_t() { *this = r; }
6190 void swap(cexpr_t &r) { qswap(*this, r); }
6191 cexpr_t &operator=(const cexpr_t &r) { return assign(r); }
6192 cexpr_t &hexapi assign(const cexpr_t &r);
6193 DECLARE_COMPARISONS(cexpr_t);
6194 ~cexpr_t() { cleanup(); }
6195
6196 /// Replace the expression.
6197 /// The children of the expression are abandoned (not freed).
6198 /// The expression pointed by 'r' is moved to 'this' expression
6199 /// \param r the source expression. It is deleted after being copied
6200 void hexapi replace_by(cexpr_t *r);
6201
6202 /// Cleanup the expression.
6203 /// This function properly deletes all children and sets the item type to cot_empty.
6204 void hexapi cleanup();
6205
6206 /// Assign a number to the expression.
6207 /// \param func current function
6208 /// \param value number value
6209 /// \param nbytes size of the number in bytes
6210 /// \param sign number sign
6211 void hexapi put_number(cfunc_t *func, uint64 value, int nbytes, type_sign_t sign=no_sign);
6212
6213 /// Print expression into one line.
6214 /// \param vout output buffer
6215 /// \param func parent function. This argument is used to find out the referenced variable names.
6216 void hexapi print1(qstring *vout, const cfunc_t *func) const;
6217
6218 /// Calculate the type of the expression.
6219 /// Use this function to calculate the expression type when a new expression is built
6220 /// \param recursive if true, types of all children expression will be calculated
6221 /// before calculating our type
6222 void hexapi calc_type(bool recursive);
6223
6224 /// Compare two expressions.
6225 /// This function tries to compare two expressions in an 'intelligent' manner.
6226 /// For example, it knows about commutitive operators and can ignore useless casts.
6227 /// \param r the expression to compare against the current expression
6228 /// \return true expressions can be considered equal
6229 bool hexapi equal_effect(const cexpr_t &r) const;
6230
6231 /// Verify if the specified item is our parent.
6232 /// \param parent possible parent item
6233 /// \return true if the specified item is our parent
6234 bool hexapi is_child_of(const citem_t *parent) const;
6235
6236 /// Check if the expression contains the specified operator.
6237 /// \param needed_op operator code to search for
6238 /// \param times how many times the operator code should be present
6239 /// \return true if the expression has at least TIMES children with NEEDED_OP
6240 bool hexapi contains_operator(ctype_t needed_op, int times=1) const;
6241
6242 /// Does the expression contain a comma operator?
6243 bool contains_comma(int times=1) const { return contains_operator(cot_comma, times); }
6244 /// Does the expression contain an embedded statement operator?
6245 bool contains_insn(int times=1) const { return contains_operator(cot_insn, times); }
6246 /// Does the expression contain an embedded statement operator or a label?
6247 bool contains_insn_or_label() const { return contains_insn() || contains_label(); }
6248 /// Does the expression contain a comma operator or an embedded statement operator or a label?
6249 bool contains_comma_or_insn_or_label(int maxcommas=1) const { return contains_comma(maxcommas) || contains_insn_or_label(); }
6250 /// Is nice expression?
6251 /// Nice expressions do not contain comma operators, embedded statements, or labels.
6252 bool is_nice_expr() const { return !contains_comma_or_insn_or_label(); }
6253 /// Is nice condition?.
6254 /// Nice condition is a nice expression of the boolean type.
6255 bool is_nice_cond() const { return is_nice_expr() && type.is_bool(); }
6256 /// Is call object?
6257 /// \return true if our expression is the call object of the specified parent expression.
6258 bool is_call_object_of(const citem_t *parent) const { return parent != nullptr && parent->op == cot_call && ((cexpr_t*)parent)->x == this; }
6259 /// Is call argument?
6260 /// \return true if our expression is a call argument of the specified parent expression.
6261 bool is_call_arg_of(const citem_t *parent) const { return parent != nullptr && parent->op == cot_call && ((cexpr_t*)parent)->x != this; }
6262 /// Get expression sign
6263 type_sign_t get_type_sign() const { return type.get_sign(); }
6264 /// Is expression unsigned?
6265 bool is_type_unsigned() const { return type.is_unsigned(); }
6266 /// Is expression signed?
6267 bool is_type_signed() const { return type.is_signed(); }
6268 /// Get max number of bits that can really be used by the expression.
6269 /// For example, x % 16 can yield only 4 non-zero bits, higher bits are zero
6270 bit_bound_t hexapi get_high_nbit_bound() const;
6271 /// Get min number of bits that are certainly required to represent the expression.
6272 /// For example, constant 16 always uses 5 bits: 10000.
6273 int hexapi get_low_nbit_bound() const;
6274 /// Check if the expression requires an lvalue.
6275 /// \param child The function will check if this child of our expression must be an lvalue.
6276 /// \return true if child must be an lvalue.
6277 bool hexapi requires_lvalue(const cexpr_t *child) const;
6278 /// Check if the expression has side effects.
6279 /// Calls, pre/post inc/dec, and assignments have side effects.
6280 bool hexapi has_side_effects() const;
6281 /// Does the expression look like a boolean expression?
6282 /// In other words, its possible values are only 0 and 1.
6283 bool like_boolean() const;
6284 /// Check if the expression if aliasable.
6285 /// Simple registers and non-aliasble stack slots return false.
6286 bool is_aliasable() const;
6287 /// Get numeric value of the expression.
6288 /// This function can be called only on cot_num expressions!
6289 uint64 numval() const
6290 {
6291 QASSERT(50071, op == cot_num);
6292 return n->value(type);
6293 }
6294 /// Check if the expression is a number with the specified value.
6295 bool is_const_value(uint64 _v) const
6296 {
6297 return op == cot_num && numval() == _v;
6298 }
6299 /// Check if the expression is a negative number.
6301 {
6302 return op == cot_num && int64(numval()) < 0;
6303 }
6304 /// Check if the expression is a non-negative number.
6306 {
6307 return op == cot_num && int64(numval()) >= 0;
6308 }
6309 /// Check if the expression is a non-zero number.
6311 {
6312 return op == cot_num && numval() != 0;
6313 }
6314 /// Check if the expression is a zero.
6315 bool is_zero_const() const { return is_const_value(0); }
6316 /// Does the PARENT need the expression value
6317 bool is_value_used(const citem_t *parent) const;
6318 /// Get expression value.
6319 /// \param out Pointer to the variable where the expression value is returned.
6320 /// \return true if the expression is a number.
6321 bool get_const_value(uint64 *out) const
6322 {
6323 if ( op == cot_num )
6324 {
6325 if ( out != nullptr )
6326 *out = numval();
6327 return true;
6328 }
6329 return false;
6330 }
6331 /// May the expression be a pointer?
6332 bool hexapi maybe_ptr() const;
6333
6334 /// Find pointer or array child.
6336 {
6337 if ( x->type.is_ptr_or_array() )
6338 return x;
6339 if ( y->type.is_ptr_or_array() )
6340 return y;
6341 return nullptr;
6342 }
6343 /// Find the child with the specified operator.
6344 const cexpr_t *find_op(ctype_t _op) const
6345 {
6346 if ( x->op == _op )
6347 return x;
6348 if ( y->op == _op )
6349 return y;
6350 return nullptr;
6351 }
6352 cexpr_t *find_op(ctype_t _op)
6353 {
6354 return (cexpr_t *)((const cexpr_t *)this)->find_op(_op);
6355 }
6356
6357 /// Find the operand with a numeric value
6358 const cexpr_t *find_num_op() const { return find_op(cot_num); }
6359 cexpr_t *find_num_op() { return find_op(cot_num); }
6360 /// Find the pointer operand.
6361 /// This function returns the pointer operand for binary expressions.
6362 const cexpr_t *find_ptr_or_array(bool remove_eqsize_casts) const;
6363 /// Get the other operand.
6364 /// This function returns the other operand (not the specified one)
6365 /// for binary expressions.
6366 const cexpr_t *theother(const cexpr_t *what) const { return what == x ? y : x; }
6367 cexpr_t *theother(const cexpr_t *what) { return what == x ? y : x; }
6368
6369 // these are inline functions, see below
6370 bool get_1num_op(cexpr_t **o1, cexpr_t **o2);
6371 bool get_1num_op(const cexpr_t **o1, const cexpr_t **o2) const;
6372
6373 const char *hexapi dstr() const;
6374};
6375DECLARE_TYPE_AS_MOVABLE(cexpr_t);
6376
6377/// Statement with an expression.
6378/// This is a base class for various statements with expressions.
6380{
6381 cexpr_t expr; ///< Expression of the statement
6382 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
6383};
6384DECLARE_TYPE_AS_MOVABLE(ceinsn_t);
6385
6386/// Should curly braces be printed?
6388{
6389 CALC_CURLY_BRACES, ///< print curly braces if necessary
6390 NO_CURLY_BRACES, ///< don't print curly braces
6391 USE_CURLY_BRACES, ///< print curly braces without any checks
6392};
6393
6394/// If statement
6395struct cif_t : public ceinsn_t
6396{
6397 cinsn_t *ithen = nullptr; ///< Then-branch of the if-statement
6398 cinsn_t *ielse = nullptr; ///< Else-branch of the if-statement. May be nullptr.
6399 cif_t() {}
6400 cif_t(const cif_t &r) : ceinsn_t(), ithen(nullptr), ielse(nullptr) { *this = r; }
6401 cif_t &operator=(const cif_t &r) { return assign(r); }
6402 cif_t &hexapi assign(const cif_t &r);
6403 DECLARE_COMPARISONS(cif_t);
6404 ~cif_t() { cleanup(); }
6405 void cleanup();
6406};
6407
6408/// Base class for loop statements
6409struct cloop_t : public ceinsn_t
6410{
6411 cinsn_t *body = nullptr;
6412 cloop_t(cinsn_t *b=nullptr) : body(b) {}
6413 cloop_t(const cloop_t &r) : ceinsn_t() { *this = r; }
6414 cloop_t &operator=(const cloop_t &r) { return assign(r); }
6415 cloop_t &hexapi assign(const cloop_t &r);
6416 ~cloop_t() { cleanup(); }
6417 void cleanup();
6418};
6419
6420/// For-loop
6421struct cfor_t : public cloop_t
6422{
6423 cexpr_t init; ///< Initialization expression
6424 cexpr_t step; ///< Step expression
6425 DECLARE_COMPARISONS(cfor_t);
6426};
6427
6428/// While-loop
6429struct cwhile_t : public cloop_t
6430{
6431 DECLARE_COMPARISONS(cwhile_t);
6432};
6433
6434/// Do-loop
6435struct cdo_t : public cloop_t
6436{
6437 DECLARE_COMPARISONS(cdo_t);
6438};
6439
6440/// Return statement
6441struct creturn_t : public ceinsn_t
6442{
6443 DECLARE_COMPARISONS(creturn_t);
6444};
6445
6446/// Goto statement
6448{
6449 int label_num; ///< Target label number
6450 void print(const citem_t *parent, int indent, vc_printer_t &vp) const;
6451 DECLARE_COMPARISONS(cgoto_t);
6452 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
6453};
6454
6455/// asm statement
6456struct casm_t : public eavec_t
6457{
6458 casm_t(ea_t ea) { push_back(ea); }
6459 casm_t(const casm_t &r) : eavec_t(eavec_t(r)) {}
6460 DECLARE_COMPARISONS(casm_t);
6461 void print(const citem_t *parent, int indent, vc_printer_t &vp) const;
6462 bool one_insn() const { return size() == 1; }
6463 void genasm(qstring *buf, ea_t ea) const;
6464};
6465
6466/// Vector of pointers to statements.
6467typedef qvector<cinsn_t *> cinsnptrvec_t;
6468
6469/// Ctree item: statement.
6470/// Depending on the exact statement type, various fields of the union are used.
6471struct cinsn_t : public citem_t
6472{
6473 union
6474 {
6475 cblock_t *cblock; ///< details of block-statement
6476 cexpr_t *cexpr; ///< details of expression-statement
6477 cif_t *cif; ///< details of if-statement
6478 cfor_t *cfor; ///< details of for-statement
6479 cwhile_t *cwhile; ///< details of while-statement
6480 cdo_t *cdo; ///< details of do-statement
6481 cswitch_t *cswitch; ///< details of switch-statement
6482 creturn_t *creturn; ///< details of return-statement
6483 cgoto_t *cgoto; ///< details of goto-statement
6484 casm_t *casm; ///< details of asm-statement
6485 };
6486
6487 cinsn_t() { zero(); }
6488 cinsn_t(const cinsn_t &r) : citem_t(cit_empty) { *this = r; }
6489 void swap(cinsn_t &r) { citem_t::swap(r); std::swap(cblock, r.cblock); }
6490 cinsn_t &operator=(const cinsn_t &r) { return assign(r); }
6491 cinsn_t &hexapi assign(const cinsn_t &r);
6492 DECLARE_COMPARISONS(cinsn_t);
6493 ~cinsn_t() { cleanup(); }
6494
6495 /// Replace the statement.
6496 /// The children of the statement are abandoned (not freed).
6497 /// The statement pointed by 'r' is moved to 'this' statement
6498 /// \param r the source statement. It is deleted after being copied
6499 void hexapi replace_by(cinsn_t *r);
6500
6501 /// Cleanup the statement.
6502 /// This function properly deletes all children and sets the item type to cit_empty.
6503 void hexapi cleanup();
6504
6505 /// Overwrite with zeroes without cleaning memory or deleting children
6506 void zero() { op = cit_empty; cblock = nullptr; }
6507
6508 /// Create a new statement.
6509 /// The current statement must be a block. The new statement will be appended to it.
6510 /// \param insn_ea statement address
6511 cinsn_t &hexapi new_insn(ea_t insn_ea);
6512
6513 /// Create a new if-statement.
6514 /// The current statement must be a block. The new statement will be appended to it.
6515 /// \param cnd if condition. It will be deleted after being copied.
6516 cif_t &hexapi create_if(cexpr_t *cnd);
6517
6518 /// Print the statement into many lines.
6519 /// \param indent indention (number of spaces) for the statement
6520 /// \param vp printer helper class which will receive the generated text.
6521 /// \param use_curly if the statement is a block, how should curly braces be printed.
6522 void hexapi print(int indent, vc_printer_t &vp, use_curly_t use_curly=CALC_CURLY_BRACES) const;
6523
6524 /// Print the statement into one line.
6525 /// Currently this function is not available.
6526 /// \param vout output buffer
6527 /// \param func parent function. This argument is used to find out the referenced variable names.
6528 void hexapi print1(qstring *vout, const cfunc_t *func) const;
6529
6530 /// Check if the statement passes execution to the next statement.
6531 /// \return false if the statement breaks the control flow (like goto, return, etc)
6532 bool hexapi is_ordinary_flow() const;
6533
6534 /// Check if the statement contains a statement of the specified type.
6535 /// \param type statement opcode to look for
6536 /// \param times how many times TYPE should be present
6537 /// \return true if the statement has at least TIMES children with opcode == TYPE
6538 bool hexapi contains_insn(ctype_t type, int times=1) const;
6539
6540 /// Collect free \c break statements.
6541 /// This function finds all free \c break statements within the current statement.
6542 /// A \c break statement is free if it does not have a loop or switch parent that
6543 /// that is also within the current statement.
6544 /// \param breaks pointer to the variable where the vector of all found free
6545 /// \c break statements is returned. This argument can be nullptr.
6546 /// \return true if some free \c break statements have been found
6547 bool hexapi collect_free_breaks(cinsnptrvec_t *breaks);
6548
6549 /// Collect free \c continue statements.
6550 /// This function finds all free \c continue statements within the current statement.
6551 /// A \c continue statement is free if it does not have a loop parent that
6552 /// that is also within the current statement.
6553 /// \param continues pointer to the variable where the vector of all found free
6554 /// \c continue statements is returned. This argument can be nullptr.
6555 /// \return true if some free \c continue statements have been found
6556 bool hexapi collect_free_continues(cinsnptrvec_t *continues);
6557
6558 /// Check if the statement has free \c break statements.
6559 bool contains_free_break() const { return CONST_CAST(cinsn_t*)(this)->collect_free_breaks(nullptr); }
6560 /// Check if the statement has free \c continue statements.
6561 bool contains_free_continue() const { return CONST_CAST(cinsn_t*)(this)->collect_free_continues(nullptr); }
6562
6563 const char *hexapi dstr() const;
6564};
6565DECLARE_TYPE_AS_MOVABLE(cinsn_t);
6566
6567typedef qlist<cinsn_t> cinsn_list_t;
6568
6569/// Compound statement (curly braces)
6570struct cblock_t : public cinsn_list_t // we need list to be able to manipulate
6571{ // its elements freely
6572 DECLARE_COMPARISONS(cblock_t);
6573};
6574
6575/// Function argument
6576struct carg_t : public cexpr_t
6577{
6578 bool is_vararg = false; ///< is a vararg (matches ...)
6579 tinfo_t formal_type; ///< formal parameter type (if known)
6580 void consume_cexpr(cexpr_t *e)
6581 {
6582 qswap(*(cexpr_t*)this, *e);
6583 delete e;
6584 }
6585 DECLARE_COMPARISONS(carg_t)
6586 {
6587 return cexpr_t::compare(r);
6588 }
6589};
6590DECLARE_TYPE_AS_MOVABLE(carg_t);
6591
6592/// Function argument list
6593struct carglist_t : public qvector<carg_t>
6594{
6595 tinfo_t functype; ///< function object type
6596 int flags = 0; ///< call flags
6597#define CFL_FINAL 0x0001 ///< call type is final, should not be changed
6598#define CFL_HELPER 0x0002 ///< created from a decompiler helper function
6599#define CFL_NORET 0x0004 ///< call does not return
6600 carglist_t() {}
6601 carglist_t(const tinfo_t &ftype, int fl = 0) : functype(ftype), flags(fl) {}
6602 DECLARE_COMPARISONS(carglist_t);
6603 void print(qstring *vout, const cfunc_t *func) const;
6604 int print(int curpos, vc_printer_t &vp) const;
6605};
6606
6607/// Switch case. Usually cinsn_t is a block
6608struct ccase_t : public cinsn_t
6609{
6610 uint64vec_t values; ///< List of case values.
6611 ///< if empty, then 'default' case
6612 DECLARE_COMPARISONS(ccase_t);
6613 void set_insn(cinsn_t *i); // deletes 'i'
6614 size_t size() const { return values.size(); }
6615 const uint64 &value(int i) const { return values[i]; }
6616};
6617DECLARE_TYPE_AS_MOVABLE(ccase_t);
6618
6619/// Vector of switch cases
6620struct ccases_t : public qvector<ccase_t>
6621{
6622 DECLARE_COMPARISONS(ccases_t);
6623 int find_value(uint64 v) const;
6624};
6625
6626/// Switch statement
6627struct cswitch_t : public ceinsn_t
6628{
6629 cnumber_t mvnf; ///< Maximal switch value and number format
6630 ccases_t cases; ///< Switch cases: values and instructions
6631 DECLARE_COMPARISONS(cswitch_t);
6632};
6633
6634//---------------------------------------------------------------------------
6635/// Invisible COLOR_ADDR tags in the output text are used to refer to ctree items and variables
6637{
6638 uval_t value = BADADDR;
6639#define ANCHOR_INDEX 0x1FFFFFFF
6640#define ANCHOR_MASK 0xC0000000
6641#define ANCHOR_CITEM 0x00000000 ///< c-tree item
6642#define ANCHOR_LVAR 0x40000000 ///< declaration of local variable
6643#define ANCHOR_ITP 0x80000000 ///< item type preciser
6644#define ANCHOR_BLKCMT 0x20000000 ///< block comment (for ctree items)
6645 int get_index() const { return value & ANCHOR_INDEX; }
6646 item_preciser_t get_itp() const { return item_preciser_t(value & ~ANCHOR_ITP); }
6647 bool is_valid_anchor() const { return value != BADADDR; }
6648 bool is_citem_anchor() const { return (value & ANCHOR_MASK) == ANCHOR_CITEM; }
6649 bool is_lvar_anchor() const { return (value & ANCHOR_MASK) == ANCHOR_LVAR; }
6650 bool is_itp_anchor() const { return (value & ANCHOR_ITP) != 0; }
6651 bool is_blkcmt_anchor() const { return (value & ANCHOR_BLKCMT) != 0; }
6652};
6653
6654/// Type of the cursor item.
6656{
6657 VDI_NONE, ///< undefined
6658 VDI_EXPR, ///< c-tree item
6659 VDI_LVAR, ///< declaration of local variable
6660 VDI_FUNC, ///< the function itself (the very first line with the function prototype)
6661 VDI_TAIL, ///< cursor is at (beyond) the line end (commentable line)
6662};
6663
6664/// Cursor item.
6665/// Information about the item under the cursor
6667{
6668 cursor_item_type_t citype = VDI_NONE; ///< Item type
6669 union
6670 {
6671 citem_t *it;
6672 cexpr_t *e; ///< VDI_EXPR: Expression
6673 cinsn_t *i; ///< VDI_EXPR: Statement
6674 lvar_t *l; ///< VDI_LVAR: Local variable
6675 cfunc_t *f; ///< VDI_FUNC: Function
6676 treeloc_t loc; ///< VDI_TAIL: Line tail
6677 };
6678
6679 void verify(const mba_t *mba) const;
6680
6681 /// Get pointer to structure member.
6682 /// If the current item is a structure field,
6683 /// this function will return pointer to its definition.
6684 /// \param[out] p_sptr pointer to the variable where the pointer to the
6685 /// parent structure is returned. This parameter can be nullptr.
6686 /// \return nullptr if failed
6687 /// OBSOLETE FUNCTION, do not use!
6688
6689 member_t *hexapi get_memptr(struc_t **p_sptr=nullptr) const;
6690
6691 /// Get type of a structure field.
6692 /// If the current item is a structure/union field,
6693 /// this function will return information about it.
6694 /// \param[out] udm pointer to buffer for the udt member info.
6695 /// \param[out] parent pointer to buffer for the struct/union type.
6696 /// \param[out] p_offset pointer to the offset in bits inside udt.
6697 /// \return member index or -1 if failed
6698 /// Both output parameters can be nullptr.
6699
6700 int hexapi get_udm(
6701 udm_t *udm=nullptr,
6702 tinfo_t *parent=nullptr,
6703 uint64 *p_offset=nullptr) const;
6704
6705 /// Get type of an enum member.
6706 /// If the current item is a symbolic constant,
6707 /// this function will return information about it.
6708 /// \param[out] parent pointer to buffer for the enum type.
6709 /// \return member index or -1 if failed
6710
6711 int hexapi get_edm(tinfo_t *parent) const;
6712
6713 /// Get pointer to local variable.
6714 /// If the current item is a local variable,
6715 /// this function will return pointer to its definition.
6716 /// \return nullptr if failed
6717
6718 lvar_t *hexapi get_lvar() const;
6719
6720
6721 /// Get address of the current item.
6722 /// Each ctree item has an address.
6723 /// \return BADADDR if failed
6724
6725 ea_t hexapi get_ea() const;
6726
6727
6728 /// Get label number of the current item.
6729 /// \param[in] gln_flags Combination of \ref GLN_ bits
6730 /// \return -1 if failed or no label
6731
6732 int hexapi get_label_num(int gln_flags) const;
6733/// \defgroup GLN_ get_label_num control
6734///@{
6735#define GLN_CURRENT 0x01 ///< get label of the current item
6736#define GLN_GOTO_TARGET 0x02 ///< get goto target
6737#define GLN_ALL 0x03 ///< get both
6738///@}
6739
6740 /// Is the current item is a ctree item?
6741 bool is_citem() const { return citype == VDI_EXPR; }
6742
6743 void hexapi print(qstring *vout) const;
6744 const char *hexapi dstr() const;
6745 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
6746};
6747
6748/// Unused label disposition.
6750{
6751 FORBID_UNUSED_LABELS = 0, ///< Unused labels cause interr
6752 ALLOW_UNUSED_LABELS = 1, ///< Unused labels are permitted
6753};
6754
6755typedef std::map<int, qstring> user_labels_t;
6756
6757/// Logically negate the specified expression.
6758/// The specified expression will be logically negated.
6759/// For example, "x == y" is converted into "x != y" by this function.
6760/// \param e expression to negate. After the call, e must not be used anymore
6761/// because it can be changed by the function. The function return value
6762/// must be used to refer to the expression.
6763/// \return logically negated expression.
6764
6766
6767
6768/// Create a new block-statement.
6769
6771
6772
6773/// Create a helper object.
6774/// This function creates a helper object.
6775/// The named function is not required to exist, the decompiler will only print
6776/// its name in the output. Helper functions are usually used to represent arbitrary
6777/// function or macro calls in the output.
6778/// \param standalone false:helper must be called; true:helper can be used in any expression
6779/// \param type type of the create function object
6780/// \param format printf-style format string that will be used to create the function name.
6781/// \param va additional arguments for printf
6782/// \return the created expression.
6783
6784AS_PRINTF(3, 0) cexpr_t *hexapi vcreate_helper(bool standalone, const tinfo_t &type, const char *format, va_list va);
6785
6786/// Create a helper object..
6787AS_PRINTF(3, 4) inline cexpr_t *create_helper(bool standalone, const tinfo_t &type, const char *format, ...)
6788{
6789 va_list va;
6790 va_start(va, format);
6791 cexpr_t *e = vcreate_helper(standalone, type, format, va);
6792 va_end(va);
6793 return e;
6794}
6795
6796
6797/// Create a helper call expression.
6798/// This function creates a new expression: a call of a helper function.
6799/// \param rettype type of the whole expression.
6800/// \param args helper arguments. this object will be consumed by the function.
6801/// if there are no args, this parameter may be specified as nullptr.
6802/// \param format printf-style format string that will be used to create the function name.
6803/// \param va additional arguments for printf
6804/// \return the created expression.
6805
6806AS_PRINTF(3, 0) cexpr_t *hexapi vcall_helper(const tinfo_t &rettype, carglist_t *args, const char *format, va_list va);
6807
6808/// Create a helper call.
6809AS_PRINTF(3, 4) inline cexpr_t *call_helper(
6810 const tinfo_t &rettype,
6811 carglist_t *args,
6812 const char *format, ...)
6813{
6814 va_list va;
6815 va_start(va, format);
6816 cexpr_t *e = vcall_helper(rettype, args, format, va);
6817 va_end(va);
6818 return e;
6819}
6820
6821
6822/// Create a number expression
6823/// \param n value
6824/// \param func current function
6825/// \param ea definition address of the number
6826/// \param opnum operand number of the number (in the disassembly listing)
6827/// \param sign number sign
6828/// \param size size of number in bytes
6829/// Please note that the type of the resulting expression can be anything because
6830/// it can be inherited from the disassembly listing or taken from the user
6831/// specified number representation in the pseudocode view.
6832
6833cexpr_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);
6834
6835
6836/// Create a reference.
6837/// This function performs the following conversion: "obj" => "&obj".
6838/// It can handle casts, annihilate "&*", and process other special cases.
6839
6841
6842
6843/// Dereference a pointer.
6844/// This function dereferences a pointer expression.
6845/// It performs the following conversion: "ptr" => "*ptr"
6846/// It can handle discrepancies in the pointer type and the access size.
6847/// \param e expression to deference
6848/// \param ptrsize access size
6849/// \param is_flt dereferencing for floating point access?
6850/// \return dereferenced expression
6851
6852cexpr_t *hexapi dereference(cexpr_t *e, int ptrsize, bool is_flt=false);
6853
6854
6855/// Save user defined labels into the database.
6856/// \param func_ea the entry address of the function,
6857/// ignored if FUNC != nullptr
6858/// \param user_labels collection of user defined labels
6859/// \param func pointer to current function,
6860/// if FUNC != nullptr, then save labels using a more stable
6861/// method that preserves them even when the decompiler
6862/// output drastically changes
6863
6864void hexapi save_user_labels(ea_t func_ea, const user_labels_t *user_labels); // DEPRECATED
6865void hexapi save_user_labels2(ea_t func_ea, const user_labels_t *user_labels, const cfunc_t *func=nullptr);
6866
6867
6868/// Save user defined comments into the database.
6869/// \param func_ea the entry address of the function
6870/// \param user_cmts collection of user defined comments
6871
6872void hexapi save_user_cmts(ea_t func_ea, const user_cmts_t *user_cmts);
6873
6874/// Save user defined number formats into the database.
6875/// \param func_ea the entry address of the function
6876/// \param numforms collection of user defined comments
6877
6878void hexapi save_user_numforms(ea_t func_ea, const user_numforms_t *numforms);
6879
6880
6881/// Save user defined citem iflags into the database.
6882/// \param func_ea the entry address of the function
6883/// \param iflags collection of user defined citem iflags
6884
6885void hexapi save_user_iflags(ea_t func_ea, const user_iflags_t *iflags);
6886
6887
6888/// Save user defined union field selections into the database.
6889/// \param func_ea the entry address of the function
6890/// \param unions collection of union field selections
6891
6892void hexapi save_user_unions(ea_t func_ea, const user_unions_t *unions);
6893
6894
6895/// Restore user defined labels from the database.
6896/// \param func_ea the entry address of the function,
6897/// ignored if FUNC != nullptr
6898/// \param func pointer to current function
6899/// \return collection of user defined labels.
6900/// The returned object must be deleted by the caller using delete_user_labels()
6901
6902user_labels_t *hexapi restore_user_labels(ea_t func_ea); // DEPRECATED
6903user_labels_t *hexapi restore_user_labels2(ea_t func_ea, const cfunc_t *func=nullptr);
6904
6905
6906/// Restore user defined comments from the database.
6907/// \param func_ea the entry address of the function
6908/// \return collection of user defined comments.
6909/// The returned object must be deleted by the caller using delete_user_cmts()
6910
6911user_cmts_t *hexapi restore_user_cmts(ea_t func_ea);
6912
6913
6914/// Restore user defined number formats from the database.
6915/// \param func_ea the entry address of the function
6916/// \return collection of user defined number formats.
6917/// The returned object must be deleted by the caller using delete_user_numforms()
6918
6920
6921
6922/// Restore user defined citem iflags from the database.
6923/// \param func_ea the entry address of the function
6924/// \return collection of user defined iflags.
6925/// The returned object must be deleted by the caller using delete_user_iflags()
6926
6927user_iflags_t *hexapi restore_user_iflags(ea_t func_ea);
6928
6929
6930/// Restore user defined union field selections from the database.
6931/// \param func_ea the entry address of the function
6932/// \return collection of union field selections
6933/// The returned object must be deleted by the caller using delete_user_unions()
6934
6935user_unions_t *hexapi restore_user_unions(ea_t func_ea);
6936
6937
6938typedef std::map<ea_t, cinsnptrvec_t> eamap_t;
6939// map of instruction boundaries. may contain INS_EPILOG for the epilog instructions
6940typedef std::map<cinsn_t *, rangeset_t> boundaries_t;
6941#define INS_EPILOG ((cinsn_t *)1)
6942
6943// Tags to find this location quickly: #cfunc_t #func_t
6944//-------------------------------------------------------------------------
6945/// Decompiled function. Decompilation result is kept here.
6947{
6948 ea_t entry_ea; ///< function entry address
6949 mba_t *mba; ///< underlying microcode
6950 cinsn_t body; ///< function body, must be a block
6951 intvec_t &argidx; ///< list of arguments (indexes into vars)
6952 ctree_maturity_t maturity; ///< maturity level
6953 // The following maps must be accessed using helper functions.
6954 // Example: for user_labels_t, see functions starting with "user_labels_".
6955 user_labels_t *user_labels;///< user-defined labels.
6956 user_cmts_t *user_cmts; ///< user-defined comments.
6957 user_numforms_t *numforms; ///< user-defined number formats.
6958 user_iflags_t *user_iflags;///< user-defined item flags \ref CIT_
6959 user_unions_t *user_unions;///< user-defined union field selections.
6960/// \defgroup CIT_ ctree item iflags bits
6961///@{
6962#define CIT_COLLAPSED 0x0001 ///< display ctree item in collapsed form
6963///@}
6964 int refcnt; ///< reference count to this object. use cfuncptr_t
6965 int statebits; ///< current cfunc_t state. see \ref CFS_
6966/// \defgroup CFS_ cfunc state bits
6967#define CFS_BOUNDS 0x0001 ///< 'eamap' and 'boundaries' are ready
6968#define CFS_TEXT 0x0002 ///< 'sv' is ready (and hdrlines)
6969#define CFS_LVARS_HIDDEN 0x0004 ///< local variable definitions are collapsed
6970#define CFS_LOCKED 0x0008 ///< cfunc is temporarily locked
6971 eamap_t *eamap; ///< ea->insn map. use \ref get_eamap
6972 boundaries_t *boundaries; ///< map of instruction boundaries. use \ref get_boundaries
6973 strvec_t sv; ///< decompilation output: function text. use \ref get_pseudocode
6974 int hdrlines; ///< number of lines in the declaration area
6975 mutable ctree_items_t treeitems; ///< vector of ctree items
6976
6977 // the exact size of this class is not documented, there may be more fields
6978 char reserved[];
6979
6980public:
6981 cfunc_t(mba_t *mba); // use create_cfunc()
6982 ~cfunc_t() { cleanup(); }
6983 void release() { delete this; }
6984 HEXRAYS_MEMORY_ALLOCATION_FUNCS()
6985
6986 /// Generate the function body.
6987 /// This function (re)generates the function body from the underlying microcode.
6988 void hexapi build_c_tree();
6989
6990 /// Verify the ctree.
6991 /// This function verifies the ctree. If the ctree is malformed, an internal error
6992 /// is generated. Use it to verify the ctree after your modifications.
6993 /// \param aul Are unused labels acceptable?
6994 /// \param even_without_debugger if false and there is no debugger, the verification will be skipped
6995 void hexapi verify(allow_unused_labels_t aul, bool even_without_debugger) const;
6996
6997 /// Print function prototype.
6998 /// \param vout output buffer
6999 void hexapi print_dcl(qstring *vout) const;
7000
7001 /// Print function text.
7002 /// \param vp printer helper class to receive the generated text.
7003 void hexapi print_func(vc_printer_t &vp) const;
7004
7005 /// Get the function type.
7006 /// \param type variable where the function type is returned
7007 /// \return false if failure
7008 bool hexapi get_func_type(tinfo_t *type) const;
7009
7010 /// Get vector of local variables.
7011 /// \return pointer to the vector of local variables. If you modify this vector,
7012 /// the ctree must be regenerated in order to have correct cast operators.
7013 /// Use build_c_tree() for that.
7014 /// Removing lvars should be done carefully: all references in ctree
7015 /// and microcode must be corrected after that.
7016 lvars_t *hexapi get_lvars();
7017
7018 /// Get stack offset delta.
7019 /// The local variable stack offsets retrieved by v.location.stkoff()
7020 /// should be adjusted before being used as stack frame offsets in IDA.
7021 /// \return the delta to apply.
7022 /// example: ida_stkoff = v.location.stkoff() - f->get_stkoff_delta()
7023 sval_t hexapi get_stkoff_delta();
7024
7025 /// Find the label.
7026 /// \return pointer to the ctree item with the specified label number.
7027 citem_t *hexapi find_label(int label);
7028
7029 /// Remove unused labels.
7030 /// This function checks what labels are really used by the function and
7031 /// removes the unused ones. You must call it after deleting a goto statement.
7032 void hexapi remove_unused_labels();
7033
7034 /// Retrieve a user defined comment.
7035 /// \param loc ctree location
7036 /// \param rt should already retrieved comments retrieved again?
7037 /// \return pointer to the comment string or nullptr
7038 const char *hexapi get_user_cmt(const treeloc_t &loc, cmt_retrieval_type_t rt) const;
7039
7040 /// Set a user defined comment.
7041 /// This function stores the specified comment in the cfunc_t structure.
7042 /// The save_user_cmts() function must be called after it.
7043 /// \param loc ctree location
7044 /// \param cmt new comment. if empty or nullptr, then an existing comment is deleted.
7045 void hexapi set_user_cmt(const treeloc_t &loc, const char *cmt);
7046
7047 /// Retrieve citem iflags.
7048 /// \param loc citem locator
7049 /// \return \ref CIT_ or 0
7050 int32 hexapi get_user_iflags(const citem_locator_t &loc) const;
7051
7052 /// Set citem iflags.
7053 /// \param loc citem locator
7054 /// \param iflags new iflags
7055 void hexapi set_user_iflags(const citem_locator_t &loc, int32 iflags);
7056
7057 /// Check if there are orphan comments.
7058 bool hexapi has_orphan_cmts() const;
7059
7060 /// Delete all orphan comments.
7061 /// The save_user_cmts() function must be called after this call.
7062 int hexapi del_orphan_cmts();
7063
7064 /// Retrieve a user defined union field selection.
7065 /// \param ea address
7066 /// \param path out: path describing the union selection.
7067 /// \return pointer to the path or nullptr
7068 bool hexapi get_user_union_selection(ea_t ea, intvec_t *path);
7069
7070 /// Set a union field selection.
7071 /// The save_user_unions() function must be called after calling this function.
7072 /// \param ea address
7073 /// \param path in: path describing the union selection.
7074 void hexapi set_user_union_selection(ea_t ea, const intvec_t &path);
7075
7076 /// Save user-defined labels into the database
7077 void hexapi save_user_labels() const;
7078 /// Save user-defined comments into the database
7079 void hexapi save_user_cmts() const;
7080 /// Save user-defined number formats into the database
7081 void hexapi save_user_numforms() const;
7082 /// Save user-defined iflags into the database
7083 void hexapi save_user_iflags() const;
7084 /// Save user-defined union field selections into the database
7085 void hexapi save_user_unions() const;
7086
7087 /// Get ctree item for the specified cursor position.
7088 /// \return false if failed to get the current item
7089 /// \param line line of decompilation text (element of \ref sv)
7090 /// \param x x cursor coordinate in the line
7091 /// \param is_ctree_line does the line belong to statement area? (if not, it is assumed to belong to the declaration area)
7092 /// \param phead ptr to the first item on the line (used to attach block comments). May be nullptr
7093 /// \param pitem ptr to the current item. May be nullptr
7094 /// \param ptail ptr to the last item on the line (used to attach indented comments). May be nullptr
7095 /// \sa vdui_t::get_current_item()
7096 bool hexapi get_line_item(
7097 const char *line,
7098 int x,
7099 bool is_ctree_line,
7100 ctree_item_t *phead,
7101 ctree_item_t *pitem,
7102 ctree_item_t *ptail);
7103
7104 /// Get information about decompilation warnings.
7105 /// \return reference to the vector of warnings
7106 hexwarns_t &hexapi get_warnings();
7107
7108 /// Get pointer to ea->insn map.
7109 /// This function initializes eamap if not done yet.
7110 eamap_t &hexapi get_eamap();
7111
7112 /// Get pointer to map of instruction boundaries.
7113 /// This function initializes the boundary map if not done yet.
7114 boundaries_t &hexapi get_boundaries();
7115
7116 /// Get pointer to decompilation output: the pseudocode.
7117 /// This function generates pseudocode if not done yet.
7118 const strvec_t &hexapi get_pseudocode();
7119
7120 /// Refresh ctext after a ctree modification.
7121 /// This function informs the decompiler that ctree (\ref body) have been
7122 /// modified and ctext (\ref sv) does not correspond to it anymore.
7123 /// It also refreshes the pseudocode windows if there is any.
7124 void hexapi refresh_func_ctext();
7125
7126 bool hexapi gather_derefs(const ctree_item_t &ci, udt_type_data_t *udm=nullptr) const;
7127 bool hexapi find_item_coords(const citem_t *item, int *px, int *py);
7128 bool locked() const { return (statebits & CFS_LOCKED) != 0; }
7129private:
7130 /// Cleanup.
7131 /// Properly delete all children and free memory.
7132 void hexapi cleanup();
7133 DECLARE_UNCOPYABLE(cfunc_t)
7134};
7135typedef qvector<cfuncptr_t> cfuncptrs_t;
7136
7137/// \defgroup DECOMP_ decompile() flags
7138///@{
7139#define DECOMP_NO_WAIT 0x0001 ///< do not display waitbox
7140#define DECOMP_NO_CACHE 0x0002 ///< do not use decompilation cache (snippets are never cached)
7141#define DECOMP_NO_FRAME 0x0004 ///< do not use function frame info (only snippet mode)
7142#define DECOMP_WARNINGS 0x0008 ///< display warnings in the output window
7143#define DECOMP_ALL_BLKS 0x0010 ///< generate microcode for unreachable blocks
7144#define DECOMP_NO_HIDE 0x0020 ///< do not close display waitbox. see close_hexrays_waitboxes()
7145#define DECOMP_NO_XREFS 0x0040 ///< Obsolete. Use DECOMP_GXREFS_NOUPD
7146#define DECOMP_GXREFS_DEFLT 0x0000 ///< the default behavior: do not update the
7147 ///< global xrefs cache upon decompile() call,
7148 ///< but when the pseudocode text is generated
7149 ///< (e.g., through cfunc_t.get_pseudocode())
7150#define DECOMP_GXREFS_NOUPD 0x0040 ///< do not update the global xrefs cache
7151#define DECOMP_GXREFS_FORCE 0x0080 ///< update the global xrefs cache immediately
7152#define DECOMP_VOID_MBA 0x0100 ///< return empty mba object (to be used with gen_microcode)
7153///@}
7154
7155/// Close the waitbox displayed by the decompiler.
7156/// Useful if DECOMP_NO_HIDE was used during decompilation.
7157
7159
7160
7161/// Decompile a snippet or a function.
7162/// \param mbr what to decompile
7163/// \param hf extended error information (if failed)
7164/// \param decomp_flags bitwise combination of \ref DECOMP_... bits
7165/// \return pointer to the decompilation result (a reference counted pointer).
7166/// nullptr if failed.
7167
7168cfuncptr_t hexapi decompile(
7169 const mba_ranges_t &mbr,
7170 hexrays_failure_t *hf=nullptr,
7171 int decomp_flags=0);
7172
7173
7174/// Decompile a function.
7175/// Multiple decompilations of the same function return the same object.
7176/// \param pfn pointer to function to decompile
7177/// \param hf extended error information (if failed)
7178/// \param decomp_flags bitwise combination of \ref DECOMP_... bits
7179/// \return pointer to the decompilation result (a reference counted pointer).
7180/// nullptr if failed.
7181
7182inline cfuncptr_t decompile_func(
7183 func_t *pfn,
7184 hexrays_failure_t *hf=nullptr,
7185 int decomp_flags=0)
7186{
7187 mba_ranges_t mbr(pfn);
7188 return decompile(mbr, hf, decomp_flags);
7189}
7190
7191
7192/// Decompile a snippet.
7193/// \param ranges snippet ranges. ranges[0].start_ea is the entry point
7194/// \param hf extended error information (if failed)
7195/// \param decomp_flags bitwise combination of \ref DECOMP_... bits
7196/// \return pointer to the decompilation result (a reference counted pointer).
7197/// nullptr if failed.
7198
7199inline cfuncptr_t decompile_snippet(
7200 const rangevec_t &ranges,
7201 hexrays_failure_t *hf=nullptr,
7202 int decomp_flags=0)
7203{
7204 mba_ranges_t mbr(ranges);
7205 return decompile(mbr, hf, decomp_flags);
7206}
7207
7208
7209/// Generate microcode of an arbitrary code snippet
7210/// \param mbr snippet ranges
7211/// \param hf extended error information (if failed)
7212/// \param retlist list of registers the snippet returns
7213/// \param decomp_flags bitwise combination of \ref DECOMP_... bits
7214/// \param reqmat required microcode maturity
7215/// \return pointer to the microcode, nullptr if failed.
7216
7218 const mba_ranges_t &mbr,
7219 hexrays_failure_t *hf=nullptr,
7220 const mlist_t *retlist=nullptr,
7221 int decomp_flags=0,
7223
7224/// Create an empty microcode object
7226 const mba_ranges_t &mbr,
7227 hexrays_failure_t *hf=nullptr)
7228{
7229 return gen_microcode(mbr, hf, nullptr, DECOMP_VOID_MBA);
7230}
7231
7232
7233/// Create a new cfunc_t object.
7234/// \param mba microcode object.
7235/// After creating the cfunc object it takes the ownership of MBA.
7236
7237cfuncptr_t hexapi create_cfunc(mba_t *mba);
7238
7239
7240/// Flush the cached decompilation results.
7241/// Erases a cache entry for the specified function.
7242/// \param ea function to erase from the cache
7243/// \param close_views close pseudocode windows that show the function
7244/// \return if a cache entry existed.
7245
7246bool hexapi mark_cfunc_dirty(ea_t ea, bool close_views=false);
7247
7248
7249/// Flush all cached decompilation results.
7250
7252
7253
7254/// Do we have a cached decompilation result for 'ea'?
7255
7256bool hexapi has_cached_cfunc(ea_t ea);
7257
7258//--------------------------------------------------------------------------
7259// Now cinsn_t class is defined, define the cleanup functions:
7260inline void cif_t::cleanup() { delete ithen; delete ielse; }
7261inline void cloop_t::cleanup() { delete body; }
7262
7263/// Print item into one line.
7264/// \param vout output buffer
7265/// \param func parent function. This argument is used to find out the referenced variable names.
7266/// \return length of the generated text.
7267
7268inline void citem_t::print1(qstring *vout, const cfunc_t *func) const
7269{
7270 if ( is_expr() )
7271 ((cexpr_t*)this)->print1(vout, func);
7272 else
7273 ((cinsn_t*)this)->print1(vout, func);
7274}
7275
7276/// Get pointers to operands. at last one operand should be a number
7277/// o1 will be pointer to the number
7278
7279inline bool cexpr_t::get_1num_op(cexpr_t **o1, cexpr_t **o2)
7280{
7281 if ( x->op == cot_num )
7282 {
7283 *o1 = x;
7284 *o2 = y;
7285 }
7286 else
7287 {
7288 if ( y->op != cot_num )
7289 return false;
7290 *o1 = y;
7291 *o2 = x;
7292 }
7293 return true;
7294}
7295
7296inline bool cexpr_t::get_1num_op(const cexpr_t **o1, const cexpr_t **o2) const
7297{
7298 return CONST_CAST(cexpr_t*)(this)->get_1num_op(
7299 CONST_CAST(cexpr_t**)(o1),
7300 CONST_CAST(cexpr_t**)(o2));
7301}
7302
7303inline citem_locator_t::citem_locator_t(const citem_t *i)
7304 : ea(i != nullptr ? i->ea : BADADDR),
7305 op(i != nullptr ? i->op : cot_empty)
7306{
7307}
7308
7310{
7311 cinsn_t *block = (cinsn_t *)parents.back();
7312 QASSERT(50600, block->op == cit_block);
7313 return block->cblock;
7314}
7315
7316const char *hexapi get_ctype_name(ctype_t op);
7317qstring hexapi create_field_name(const tinfo_t &type, uval_t offset=BADADDR);
7318typedef void *hexdsp_t(int code, ...);
7319const int64 HEXRAYS_API_MAGIC = 0x00DEC0DE00000003LL;
7320
7321/// Decompiler events.
7322/// Use install_hexrays_callback() to install a handler for decompiler events.
7323/// When the possible return value is not specified, your callback
7324/// must return zero.
7325enum hexrays_event_t ENUM_SIZE(int)
7326{
7327 // When a function is decompiled, the following events occur:
7328
7329 hxe_flowchart, ///< Flowchart has been generated.
7330 ///< \param fc (qflow_chart_t *)
7331
7332 hxe_stkpnts, ///< SP change points have been calculated.
7333 ///< \param mba (mba_t *)
7334 ///< \param stkpnts (stkpnts_t *)
7335 ///< return \ref MERR_ code
7336
7337 hxe_prolog, ///< Prolog analysis has been finished.
7338 ///< \param mba (mba_t *)
7339 ///< \param fc (qflow_chart_t *)
7340 ///< \param reachable_blocks (bitset_t *)
7341 ///< \param decomp_flags (int)
7342 ///< return \ref MERR_ code
7343
7344 hxe_microcode, ///< Microcode has been generated.
7345 ///< \param mba (mba_t *)
7346 ///< return \ref MERR_ code
7347
7348 hxe_preoptimized, ///< Microcode has been preoptimized.
7349 ///< \param mba (mba_t *)
7350 ///< return \ref MERR_ code
7351
7352 hxe_locopt, ///< Basic block level optimization has been finished.
7353 ///< \param mba (mba_t *)
7354 ///< return \ref MERR_ code
7355
7356 hxe_prealloc, ///< Local variables: preallocation step begins.
7357 ///< \param mba (mba_t *)
7358 ///< This event may occur several times.
7359 ///< Should return: 1 if modified microcode
7360 ///< Negative values are \ref MERR_ error codes
7361
7362 hxe_glbopt, ///< Global optimization has been finished.
7363 ///< If microcode is modified, MERR_LOOP must be returned.
7364 ///< It will cause a complete restart of the optimization.
7365 ///< \param mba (mba_t *)
7366 ///< return \ref MERR_ code
7367
7368 hxe_structural, ///< Structural analysis has been finished.
7369 ///< \param ct (control_graph_t *)
7370
7371 hxe_maturity, ///< Ctree maturity level is being changed.
7372 ///< \param cfunc (cfunc_t *)
7373 ///< \param new_maturity (ctree_maturity_t)
7374
7375 hxe_interr, ///< Internal error has occurred.
7376 ///< \param errcode (int )
7377
7378 hxe_combine, ///< Trying to combine instructions of basic block.
7379 ///< \param blk (mblock_t *)
7380 ///< \param insn (minsn_t *)
7381 ///< Should return: 1 if combined the current instruction with a preceding one
7382 /// -1 if the instruction should not be combined
7383 /// 0 else
7384
7385 hxe_print_func, ///< Printing ctree and generating text.
7386 ///< \param cfunc (cfunc_t *)
7387 ///< \param vp (vc_printer_t *)
7388 ///< Returns: 1 if text has been generated by the plugin
7389 ///< It is forbidden to modify ctree at this event.
7390
7391 hxe_func_printed, ///< Function text has been generated. Plugins may
7392 ///< modify the text in \ref cfunc_t::sv.
7393 ///< The text uses regular color codes (see lines.hpp)
7394 ///< COLOR_ADDR is used to store pointers to ctree items.
7395 ///< \param cfunc (cfunc_t *)
7396
7397 hxe_resolve_stkaddrs, ///< The optimizer is about to resolve stack addresses.
7398 ///< \param mba (mba_t *)
7399
7400 hxe_build_callinfo, ///< Analyzing a call instruction.
7401 ///< \param blk (mblock_t *) blk->tail is the call.
7402 ///< \param type (tinfo_t *) buffer for the output type.
7403 ///< \param callinfo (mcallinfo_t **) prepared callinfo.
7404 ///< The plugin should either specify the function type,
7405 ///< either allocate and return a new mcallinfo_t object.
7406
7407 hxe_callinfo_built, ///< A call instruction has been anallyzed.
7408 ///< \param blk (mblock_t *) blk->tail is the call.
7409
7410 hxe_calls_done, ///< All calls have been analyzed.
7411 ///< \param mba (mba_t *)
7412 ///< This event is generated immediately after analyzing
7413 ///< all calls, before any optimizitions, call unmerging
7414 ///< and block merging.
7415
7416 // User interface related events:
7417
7418 hxe_open_pseudocode=100,
7419 ///< New pseudocode view has been opened.
7420 ///< \param vu (vdui_t *)
7421
7422 hxe_switch_pseudocode,///< Existing pseudocode view has been reloaded
7423 ///< with a new function. Its text has not been
7424 ///< refreshed yet, only cfunc and mba pointers are ready.
7425 ///< \param vu (vdui_t *)
7426
7427 hxe_refresh_pseudocode,///< Existing pseudocode text has been refreshed.
7428 ///< Adding/removing pseudocode lines is forbidden in this event.
7429 ///< \param vu (vdui_t *)
7430 ///< See also hxe_text_ready, which happens earlier
7431
7432 hxe_close_pseudocode, ///< Pseudocode view is being closed.
7433 ///< \param vu (vdui_t *)
7434
7435 hxe_keyboard, ///< Keyboard has been hit.
7436 ///< \param vu (vdui_t *)
7437 ///< \param key_code (int) VK_...
7438 ///< \param shift_state (int)
7439 ///< Should return: 1 if the event has been handled
7440
7441 hxe_right_click, ///< Mouse right click.
7442 ///< Use hxe_populating_popup instead, in case you
7443 ///< want to add items in the popup menu.
7444 ///< \param vu (vdui_t *)
7445
7446 hxe_double_click, ///< Mouse double click.
7447 ///< \param vu (vdui_t *)
7448 ///< \param shift_state (int)
7449 ///< Should return: 1 if the event has been handled
7450
7451 hxe_curpos, ///< Current cursor position has been changed.
7452 ///< (for example, by left-clicking or using keyboard)\n
7453 ///< \param vu (vdui_t *)
7454
7455 hxe_create_hint, ///< Create a hint for the current item.
7456 ///< \see ui_get_custom_viewer_hint
7457 ///< \param vu (vdui_t *)
7458 ///< \param hint (qstring *)
7459 ///< \param important_lines (int *)
7460 ///< Possible return values:
7461 ///< \retval 0 continue collecting hints with other subscribers
7462 ///< \retval 1 stop collecting hints
7463
7464 hxe_text_ready, ///< Decompiled text is ready.
7465 ///< \param vu (vdui_t *)
7466 ///< This event can be used to modify the output text (sv).
7467 ///< Obsolete. Please use hxe_func_printed instead.
7468
7469 hxe_populating_popup, ///< Populating popup menu. We can add menu items now.
7470 ///< \param widget (TWidget *)
7471 ///< \param popup_handle (TPopupMenu *)
7472 ///< \param vu (vdui_t *)
7473
7474 lxe_lvar_name_changed,///< Local variable got renamed.
7475 ///< \param vu (vdui_t *)
7476 ///< \param v (lvar_t *)
7477 ///< \param name (const char *)
7478 ///< \param is_user_name (bool)
7479 ///< Please note that it is possible to read/write
7480 ///< user settings for lvars directly from the idb.
7481
7482 lxe_lvar_type_changed,///< Local variable type got changed.
7483 ///< \param vu (vdui_t *)
7484 ///< \param v (lvar_t *)
7485 ///< \param tinfo (const tinfo_t *)
7486 ///< Please note that it is possible to read/write
7487 ///< user settings for lvars directly from the idb.
7488
7489 lxe_lvar_cmt_changed, ///< Local variable comment got changed.
7490 ///< \param vu (vdui_t *)
7491 ///< \param v (lvar_t *)
7492 ///< \param cmt (const char *)
7493 ///< Please note that it is possible to read/write
7494 ///< user settings for lvars directly from the idb.
7495
7496 lxe_lvar_mapping_changed, ///< Local variable mapping got changed.
7497 ///< \param vu (vdui_t *)
7498 ///< \param from (lvar_t *)
7499 ///< \param to (lvar_t *)
7500 ///< Please note that it is possible to read/write
7501 ///< user settings for lvars directly from the idb.
7502
7503 hxe_cmt_changed, ///< Comment got changed.
7504 ///< \param cfunc (cfunc_t *)
7505 ///< \param loc (const treeloc_t *)
7506 ///< \param cmt (const char *)
7507};
7508
7509/// Handler of decompiler events.
7510/// \param ud user data. the value specified at the handler installation time
7511/// is passed here.
7512/// \param event decompiler event code
7513/// \param va additional arguments
7514/// \return as a rule the callback must return 0 unless specified otherwise
7515/// in the event description.
7516
7517typedef ssize_t idaapi hexrays_cb_t(void *ud, hexrays_event_t event, va_list va);
7518
7519
7520/// Install handler for decompiler events.
7521/// \param callback handler to install
7522/// \param ud user data. this pointer will be passed to your handler by the decompiler.
7523/// \return false if failed
7524
7525bool hexapi install_hexrays_callback(hexrays_cb_t *callback, void *ud);
7526
7527/// Uninstall handler for decompiler events.
7528/// \param callback handler to uninstall
7529/// \param ud user data. if nullptr, all handler corresponding to \c callback is uninstalled.
7530/// if not nullptr, only the callback instance with the specified \c ud value is uninstalled.
7531/// \return number of uninstalled handlers.
7532
7533int hexapi remove_hexrays_callback(hexrays_cb_t *callback, void *ud);
7534
7535
7536//---------------------------------------------------------------------------
7537/// \defgroup vdui User interface definitions
7538///@{
7539
7540/// Type of the input device.
7541/// How the user command has been invoked
7543{
7544 USE_KEYBOARD = 0, ///< Keyboard
7545 USE_MOUSE = 1, ///< Mouse
7546};
7547///@}
7548
7549//---------------------------------------------------------------------------
7550/// Cursor position in the output text (pseudocode).
7552{
7553 int lnnum; ///< Line number
7554 int x; ///< x coordinate of the cursor within the window
7555 int y; ///< y coordinate of the cursor within the window
7556 /// Is the cursor in the variable/type declaration area?
7557 /// \param hdrlines Number of lines of the declaration area
7558 bool in_ctree(int hdrlines) const { return lnnum >= hdrlines; }
7559 /// Comparison operators
7561 {
7562 if ( lnnum < r.lnnum ) return -1;
7563 if ( lnnum > r.lnnum ) return 1;
7564 if ( x < r.x ) return -1;
7565 if ( x > r.x ) return 1;
7566 return 0;
7567 }
7568 ctext_position_t(int _lnnum=-1, int _x=0, int _y=0)
7569 : lnnum(_lnnum), x(_x), y(_y) {}
7570};
7571
7572/// Navigation history item.
7573/// Holds information about interactive decompilation history.
7574/// Currently this is not saved in the database.
7576{
7577 ea_t ea; ///< The entry address of the decompiled function
7578 ea_t end; ///< BADADDR-decompile function; otherwise end of the range
7579 history_item_t(ea_t _ea=BADADDR, int _lnnum=-1, int _x=0, int _y=0)
7580 : ctext_position_t(_lnnum, _x, _y), ea(_ea), end(BADADDR) {}
7581 history_item_t(ea_t _ea, const ctext_position_t &p)
7582 : ctext_position_t(p), ea(_ea), end(BADADDR) {}
7583};
7584
7585/// Navigation history.
7586typedef qstack<history_item_t> history_t;
7587
7588/// Comment types
7589typedef int cmt_type_t;
7590const cmt_type_t
7591 CMT_NONE = 0x0000, ///< No comment is possible
7592 CMT_TAIL = 0x0001, ///< Indented comment
7593 CMT_BLOCK1 = 0x0002, ///< Anterioir block comment
7594 CMT_BLOCK2 = 0x0004, ///< Posterior block comment
7595 CMT_LVAR = 0x0008, ///< Local variable comment
7596 CMT_FUNC = 0x0010, ///< Function comment
7597 CMT_ALL = 0x001F; ///< All comments
7598
7599//---------------------------------------------------------------------------
7600/// Information about the pseudocode window
7602{
7603 int flags = 0; ///< \ref VDUI_
7604/// \defgroup VDUI_ Properties of pseudocode window
7605/// Used in vdui_t::flags
7606///@{
7607#define VDUI_VISIBLE 0x0001 ///< is visible?
7608#define VDUI_VALID 0x0002 ///< is valid?
7609///@}
7610
7611 /// Is the pseudocode window visible?
7612 /// if not, it might be invisible or destroyed
7613 bool visible() const { return (flags & VDUI_VISIBLE) != 0; }
7614 /// Does the pseudocode window contain valid code?
7615 /// It can become invalid if the function type gets changed in IDA.
7616 bool valid() const { return (flags & VDUI_VALID) != 0; }
7617 /// Does the pseudocode window contain valid code?
7618 /// We lock windows before modifying them, to avoid recursion due to
7619 /// the events generated by the IDA kernel.
7620 /// \retval true The window is locked and may have stale info
7621 bool locked() const { return cfunc != nullptr && cfunc->locked(); }
7622 void set_visible(bool v) { setflag(flags, VDUI_VISIBLE, v); }
7623 void set_valid(bool v) { setflag(flags, VDUI_VALID, v); }
7624 bool hexapi set_locked(bool v); // returns true-redecompiled
7625
7626 int view_idx; ///< pseudocode window index (0..)
7627 TWidget *ct = nullptr;///< pseudocode view
7628 TWidget *toplevel = nullptr;
7629
7630 mba_t *mba; ///< pointer to underlying microcode
7631 cfuncptr_t cfunc; ///< pointer to function object
7632 merror_t last_code; ///< result of the last user action. See \ref MERR_
7633
7634 // The following fields are valid after get_current_item():
7635 ctext_position_t cpos; ///< Current ctext position
7636 ctree_item_t head; ///< First ctree item on the current line (for block comments)
7637 ctree_item_t item; ///< Current ctree item
7638 ctree_item_t tail; ///< Tail ctree item on the current line (for indented comments)
7639
7640 vdui_t(); // do not create your own vdui_t objects
7641
7642 /// Refresh pseudocode window.
7643 /// This is the highest level refresh function.
7644 /// It causes the most profound refresh possible and can lead to redecompilation
7645 /// of the current function. Please consider using refresh_ctext()
7646 /// if you need a more superficial refresh.
7647 /// \param redo_mba true means to redecompile the current function\n
7648 /// false means to rebuild ctree without regenerating microcode
7649 /// \sa refresh_ctext()
7650 void hexapi refresh_view(bool redo_mba);
7651
7652 /// Refresh pseudocode window.
7653 /// This function refreshes the pseudocode window by regenerating its text
7654 /// from cfunc_t. Instead of this function use refresh_func_ctext(), which
7655 /// refreshes all pseudocode windows for the function.
7656 /// \sa refresh_view(), refresh_func_ctext()
7657 void hexapi refresh_ctext(bool activate=true); // deprecated
7658
7659 /// Display the specified pseudocode.
7660 /// This function replaces the pseudocode window contents with the
7661 /// specified cfunc_t.
7662 /// \param f pointer to the function to display.
7663 /// \param activate should the pseudocode window get focus?
7664 void hexapi switch_to(cfuncptr_t f, bool activate);
7665
7666 /// Is the current item a statement?
7667 //// \return false if the cursor is in the local variable/type declaration area\n
7668 /// true if the cursor is in the statement area
7669 bool in_ctree() const { return cpos.in_ctree(cfunc->hdrlines); }
7670
7671 /// Get current number.
7672 /// If the current item is a number, return pointer to it.
7673 /// \return nullptr if the current item is not a number
7674 /// This function returns non-null for the cases of a 'switch' statement
7675 /// Also, if the current item is a casted number, then this function will succeed.
7677
7678 /// Get current label.
7679 /// If there is a label under the cursor, return its number.
7680 /// \return -1 if there is no label under the cursor.
7681 /// prereq: get_current_item() has been called
7683
7684 /// Clear the pseudocode window.
7685 /// It deletes the current function and microcode.
7686 void hexapi clear();
7687
7688 /// Refresh the current position.
7689 /// This function refreshes the \ref cpos field.
7690 /// \return false if failed
7691 /// \param idv keyboard or mouse
7693
7694 /// Get current item.
7695 /// This function refreshes the \ref cpos, \ref item, \ref tail fields.
7696 /// \return false if failed
7697 /// \param idv keyboard or mouse
7698 /// \sa cfunc_t::get_line_item()
7700
7701 /// Rename local variable.
7702 /// This function displays a dialog box and allows the user to rename a local variable.
7703 /// \return false if failed or cancelled
7704 /// \param v pointer to local variable
7705 bool hexapi ui_rename_lvar(lvar_t *v);
7706
7707 /// Rename local variable.
7708 /// This function permanently renames a local variable.
7709 /// \return false if failed
7710 /// \param v pointer to local variable
7711 /// \param name new variable name
7712 /// \param is_user_name use true to save the new name into the database.
7713 /// use false to delete the saved name.
7714 /// \sa ::rename_lvar()
7715 bool hexapi rename_lvar(lvar_t *v, const char *name, bool is_user_name);
7716
7717 /// Set type of a function call
7718 /// This function displays a dialog box and allows the user to change
7719 /// the type of a function call
7720 /// \return false if failed or cancelled
7721 /// \param e pointer to call expression
7722 bool hexapi ui_set_call_type(const cexpr_t *e);
7723
7724 /// Set local variable type.
7725 /// This function displays a dialog box and allows the user to change
7726 /// the type of a local variable.
7727 /// \return false if failed or cancelled
7728 /// \param v pointer to local variable
7730
7731 /// Set local variable type.
7732 /// This function permanently sets a local variable type and clears
7733 /// NOPTR flag if it was set before by function 'set_noptr_lvar'
7734 /// \return false if failed
7735 /// \param v pointer to local variable
7736 /// \param type new variable type
7737 bool hexapi set_lvar_type(lvar_t *v, const tinfo_t &type);
7738
7739 /// Inform that local variable should have a non-pointer type
7740 /// This function permanently sets a corresponding variable flag (NOPTR)
7741 /// and removes type if it was set before by function 'set_lvar_type'
7742 /// \return false if failed
7743 /// \param v pointer to local variable
7744 bool hexapi set_noptr_lvar(lvar_t *v);
7745
7746 /// Set local variable comment.
7747 /// This function displays a dialog box and allows the user to edit
7748 /// the comment of a local variable.
7749 /// \return false if failed or cancelled
7750 /// \param v pointer to local variable
7752
7753 /// Set local variable comment.
7754 /// This function permanently sets a variable comment.
7755 /// \return false if failed
7756 /// \param v pointer to local variable
7757 /// \param cmt new comment
7758 bool hexapi set_lvar_cmt(lvar_t *v, const char *cmt);
7759
7760 /// Map a local variable to another.
7761 /// This function displays a variable list and allows the user to select mapping.
7762 /// \return false if failed or cancelled
7763 /// \param v pointer to local variable
7764 bool hexapi ui_map_lvar(lvar_t *v);
7765
7766 /// Unmap a local variable.
7767 /// This function displays list of variables mapped to the specified variable
7768 /// and allows the user to select a variable to unmap.
7769 /// \return false if failed or cancelled
7770 /// \param v pointer to local variable
7771 bool hexapi ui_unmap_lvar(lvar_t *v);
7772
7773 /// Map a local variable to another.
7774 /// This function permanently maps one lvar to another.
7775 /// All occurrences of the mapped variable are replaced by the new variable
7776 /// \return false if failed
7777 /// \param from the variable being mapped
7778 /// \param to the variable to map to. if nullptr, unmaps the variable
7779 bool hexapi map_lvar(lvar_t *from, lvar_t *to);
7780
7781 /// Set structure field type.
7782 /// This function displays a dialog box and allows the user to change
7783 /// the type of a structure field.
7784 /// \return false if failed or cancelled
7785 /// \param sptr pointer to structure
7786 /// \param mptr pointer to structure member
7787 /// OBSOLETE FUNCTION, do not use!
7788 bool hexapi set_strmem_type(struc_t *sptr, member_t *mptr);
7789
7790 /// Set structure field type.
7791 /// This function displays a dialog box and allows the user to change
7792 /// the type of a structure field.
7793 /// \return false if failed or cancelled
7794 /// \param udt_type structure/union type
7795 /// \param udm_idx index of the structure/union member
7796 bool hexapi set_udm_type(tinfo_t &udt_type, int udm_idx);
7797
7798 /// Rename structure field.
7799 /// This function displays a dialog box and allows the user to rename
7800 /// a structure field.
7801 /// \return false if failed or cancelled
7802 /// \param sptr pointer to structure
7803 /// \param mptr pointer to structure member
7804 /// OBSOLETE FUNCTION, do not use!
7805 bool hexapi rename_strmem(struc_t *sptr, member_t *mptr);
7806
7807 /// Rename structure field.
7808 /// This function displays a dialog box and allows the user to rename
7809 /// a structure field.
7810 /// \return false if failed or cancelled
7811 /// \param udt_type structure/union type
7812 /// \param udm_idx index of the structure/union member
7813 bool hexapi rename_udm(tinfo_t &udt_type, int udm_idx);
7814
7815 /// Set global item type.
7816 /// This function displays a dialog box and allows the user to change
7817 /// the type of a global item (data or function).
7818 /// \return false if failed or cancelled
7819 /// \param ea address of the global item
7820 bool hexapi set_global_type(ea_t ea);
7821
7822 /// Rename global item.
7823 /// This function displays a dialog box and allows the user to rename
7824 /// a global item (data or function).
7825 /// \return false if failed or cancelled
7826 /// \param ea address of the global item
7827 bool hexapi rename_global(ea_t ea);
7828
7829 /// Rename a label.
7830 /// This function displays a dialog box and allows the user to rename
7831 /// a statement label.
7832 /// \return false if failed or cancelled
7833 /// \param label label number
7834 bool hexapi rename_label(int label);
7835
7836 /// Process the Enter key.
7837 /// This function jumps to the definition of the item under the cursor.
7838 /// If the current item is a function, it will be decompiled.
7839 /// If the current item is a global data, its disassemly text will be displayed.
7840 /// \return false if failed
7841 /// \param idv what cursor must be used, the keyboard or the mouse
7842 /// \param omflags OM_NEWWIN: new pseudocode window will open, 0: reuse the existing window
7843 bool hexapi jump_enter(input_device_t idv, int omflags);
7844
7845 /// Jump to disassembly.
7846 /// This function jumps to the address in the disassembly window
7847 /// which corresponds to the current item. The current item is determined
7848 /// based on the current keyboard cursor position.
7849 /// \return false if failed
7850 bool hexapi ctree_to_disasm();
7851
7852 /// Check if the specified line can have a comment.
7853 /// Due to the coordinate system for comments:
7854 /// (https://www.hex-rays.com/blog/coordinate-system-for-hex-rays)
7855 /// some function lines cannot have comments. This function checks if a
7856 /// comment can be attached to the specified line.
7857 /// \return possible comment types
7858 /// \param lnnum line number (0 based)
7859 /// \param cmttype comment types to check
7860 cmt_type_t hexapi calc_cmt_type(size_t lnnum, cmt_type_t cmttype) const;
7861
7862 /// Edit an indented comment.
7863 /// This function displays a dialog box and allows the user to edit
7864 /// the comment for the specified ctree location.
7865 /// \return false if failed or cancelled
7866 /// \param loc comment location
7867 bool hexapi edit_cmt(const treeloc_t &loc);
7868
7869 /// Edit a function comment.
7870 /// This function displays a dialog box and allows the user to edit
7871 /// the function comment.
7872 /// \return false if failed or cancelled
7873 bool hexapi edit_func_cmt();
7874
7875 /// Delete all orphan comments.
7876 /// Delete all orphan comments and refresh the screen.
7877 /// \return true
7878 bool hexapi del_orphan_cmts();
7879
7880 /// Change number base.
7881 /// This function changes the current number representation.
7882 /// \return false if failed
7883 /// \param base number radix (10 or 16)\n
7884 /// 0 means a character constant
7885 bool hexapi set_num_radix(int base);
7886
7887 /// Convert number to symbolic constant.
7888 /// This function displays a dialog box and allows the user to select
7889 /// a symbolic constant to represent the number.
7890 /// \return false if failed or cancelled
7891 bool hexapi set_num_enum();
7892
7893 /// Convert number to structure field offset.
7894 /// Currently not implemented.
7895 /// \return false if failed or cancelled
7896 bool hexapi set_num_stroff();
7897
7898 /// Negate a number.
7899 /// This function negates the current number.
7900 /// \return false if failed.
7901 bool hexapi invert_sign();
7902
7903 /// Bitwise negate a number.
7904 /// This function inverts all bits of the current number.
7905 /// \return false if failed.
7906 bool hexapi invert_bits();
7907
7908 /// Collapse/uncollapse item.
7909 /// This function collapses the current item.
7910 /// \return false if failed.
7911 bool hexapi collapse_item(bool hide);
7912
7913 /// Collapse/uncollapse local variable declarations.
7914 /// \return false if failed.
7915 bool hexapi collapse_lvars(bool hide);
7916
7917 /// Split/unsplit item.
7918 /// This function splits the current assignment expression.
7919 /// \return false if failed.
7920 bool hexapi split_item(bool split);
7921
7922};
7923
7924//---------------------------------------------------------------------------
7925/// Select UDT for the operands using "Select offsets" widget
7926
7927/// Operand represention
7929{
7930 qstring text; ///< any text for the column "Operand" of widget
7931 uval_t offset; ///< operand offset, will be used when calculating the UDT path
7932 bool operator==(const ui_stroff_op_t &r) const
7933 {
7934 return text == r.text && offset == r.offset;
7935 }
7936 bool operator!=(const ui_stroff_op_t &r) const { return !(*this == r); }
7937};
7938DECLARE_TYPE_AS_MOVABLE(ui_stroff_op_t);
7939typedef qvector<ui_stroff_op_t> ui_stroff_ops_t;
7940
7941/// Callback to apply the selection
7942/// \return success
7944{
7945 /// \param opnum operand ordinal number, see below
7946 /// \param path path describing the union selection, maybe empty
7947 /// \param top_tif tinfo_t of the selected toplevel UDT
7948 /// \param spath selected path
7949 virtual bool idaapi apply(size_t opnum, const intvec_t &path, const tinfo_t &top_tif, const char *spath) = 0;
7950};
7951
7952/// Select UDT
7953/// \param udts list of UDT tinfo_t for the selection,
7954/// if nullptr or empty then UDTs from the "Local types" will be used
7955/// \param ops operands
7956/// \param applicator callback will be called to apply the selection for every operand
7958 const qvector<tinfo_t> *udts,
7959 const ui_stroff_ops_t &ops,
7960 ui_stroff_applicator_t &applicator);
7961
7962
7963
7964
7965//--------------------------------------------------------------------------
7966// PUBLIC HEX-RAYS API
7967//--------------------------------------------------------------------------
7968
7969/// Hex-Rays decompiler dispatcher.
7970/// All interaction with the decompiler is carried out by the intermediary of this dispatcher.
7971typedef void *hexdsp_t(int code, ...);
7972
7973#ifndef SWIG
7974//==========================================================================
7975// PLEASE REMOVE 'hexdsp' VARIABLE, IT IS OUT OF USE NOW
7976//==========================================================================
7977extern int hexdsp;
7978#endif
7979
7980/// API call numbers
7982{
7983 hx_user_numforms_begin,
7984 hx_user_numforms_end,
7985 hx_user_numforms_next,
7986 hx_user_numforms_prev,
7987 hx_user_numforms_first,
7988 hx_user_numforms_second,
7989 hx_user_numforms_find,
7990 hx_user_numforms_insert,
7991 hx_user_numforms_erase,
7992 hx_user_numforms_clear,
7993 hx_user_numforms_size,
7994 hx_user_numforms_free,
7995 hx_user_numforms_new,
7996 hx_lvar_mapping_begin,
7997 hx_lvar_mapping_end,
7998 hx_lvar_mapping_next,
7999 hx_lvar_mapping_prev,
8000 hx_lvar_mapping_first,
8001 hx_lvar_mapping_second,
8002 hx_lvar_mapping_find,
8003 hx_lvar_mapping_insert,
8004 hx_lvar_mapping_erase,
8005 hx_lvar_mapping_clear,
8006 hx_lvar_mapping_size,
8007 hx_lvar_mapping_free,
8008 hx_lvar_mapping_new,
8009 hx_udcall_map_begin,
8010 hx_udcall_map_end,
8011 hx_udcall_map_next,
8012 hx_udcall_map_prev,
8013 hx_udcall_map_first,
8014 hx_udcall_map_second,
8015 hx_udcall_map_find,
8016 hx_udcall_map_insert,
8017 hx_udcall_map_erase,
8018 hx_udcall_map_clear,
8019 hx_udcall_map_size,
8020 hx_udcall_map_free,
8021 hx_udcall_map_new,
8022 hx_user_cmts_begin,
8023 hx_user_cmts_end,
8024 hx_user_cmts_next,
8025 hx_user_cmts_prev,
8026 hx_user_cmts_first,
8027 hx_user_cmts_second,
8028 hx_user_cmts_find,
8029 hx_user_cmts_insert,
8030 hx_user_cmts_erase,
8031 hx_user_cmts_clear,
8032 hx_user_cmts_size,
8033 hx_user_cmts_free,
8034 hx_user_cmts_new,
8035 hx_user_iflags_begin,
8036 hx_user_iflags_end,
8037 hx_user_iflags_next,
8038 hx_user_iflags_prev,
8039 hx_user_iflags_first,
8040 hx_user_iflags_second,
8041 hx_user_iflags_find,
8042 hx_user_iflags_insert,
8043 hx_user_iflags_erase,
8044 hx_user_iflags_clear,
8045 hx_user_iflags_size,
8046 hx_user_iflags_free,
8047 hx_user_iflags_new,
8048 hx_user_unions_begin,
8049 hx_user_unions_end,
8050 hx_user_unions_next,
8051 hx_user_unions_prev,
8052 hx_user_unions_first,
8053 hx_user_unions_second,
8054 hx_user_unions_find,
8055 hx_user_unions_insert,
8056 hx_user_unions_erase,
8057 hx_user_unions_clear,
8058 hx_user_unions_size,
8059 hx_user_unions_free,
8060 hx_user_unions_new,
8061 hx_user_labels_begin,
8062 hx_user_labels_end,
8063 hx_user_labels_next,
8064 hx_user_labels_prev,
8065 hx_user_labels_first,
8066 hx_user_labels_second,
8067 hx_user_labels_find,
8068 hx_user_labels_insert,
8069 hx_user_labels_erase,
8070 hx_user_labels_clear,
8071 hx_user_labels_size,
8072 hx_user_labels_free,
8073 hx_user_labels_new,
8074 hx_eamap_begin,
8075 hx_eamap_end,
8076 hx_eamap_next,
8077 hx_eamap_prev,
8078 hx_eamap_first,
8079 hx_eamap_second,
8080 hx_eamap_find,
8081 hx_eamap_insert,
8082 hx_eamap_erase,
8083 hx_eamap_clear,
8084 hx_eamap_size,
8085 hx_eamap_free,
8086 hx_eamap_new,
8087 hx_boundaries_begin,
8088 hx_boundaries_end,
8089 hx_boundaries_next,
8090 hx_boundaries_prev,
8091 hx_boundaries_first,
8092 hx_boundaries_second,
8093 hx_boundaries_find,
8094 hx_boundaries_insert,
8095 hx_boundaries_erase,
8096 hx_boundaries_clear,
8097 hx_boundaries_size,
8098 hx_boundaries_free,
8099 hx_boundaries_new,
8100 hx_block_chains_begin,
8101 hx_block_chains_end,
8102 hx_block_chains_next,
8103 hx_block_chains_prev,
8104 hx_block_chains_get,
8105 hx_block_chains_find,
8106 hx_block_chains_insert,
8107 hx_block_chains_erase,
8108 hx_block_chains_clear,
8109 hx_block_chains_size,
8110 hx_block_chains_free,
8111 hx_block_chains_new,
8112 hx_valrng_t_clear,
8113 hx_valrng_t_copy,
8114 hx_valrng_t_assign,
8115 hx_valrng_t_compare,
8116 hx_valrng_t_set_eq,
8117 hx_valrng_t_set_cmp,
8118 hx_valrng_t_reduce_size,
8119 hx_valrng_t_intersect_with,
8120 hx_valrng_t_unite_with,
8121 hx_valrng_t_inverse,
8122 hx_valrng_t_has,
8123 hx_valrng_t_print,
8124 hx_valrng_t_dstr,
8125 hx_valrng_t_cvt_to_single_value,
8126 hx_valrng_t_cvt_to_cmp,
8127 hx_get_merror_desc,
8128 hx_reg2mreg,
8129 hx_mreg2reg,
8130 hx_install_optinsn_handler,
8131 hx_remove_optinsn_handler,
8132 hx_install_optblock_handler,
8133 hx_remove_optblock_handler,
8134 hx_must_mcode_close_block,
8135 hx_is_mcode_propagatable,
8136 hx_negate_mcode_relation,
8137 hx_swap_mcode_relation,
8138 hx_get_signed_mcode,
8139 hx_get_unsigned_mcode,
8140 hx_mcode_modifies_d,
8141 hx_operand_locator_t_compare,
8142 hx_vd_printer_t_print,
8143 hx_file_printer_t_print,
8144 hx_qstring_printer_t_print,
8145 hx_dstr,
8146 hx_is_type_correct,
8147 hx_is_small_udt,
8148 hx_is_nonbool_type,
8149 hx_is_bool_type,
8150 hx_partial_type_num,
8151 hx_get_float_type,
8152 hx_get_int_type_by_width_and_sign,
8153 hx_get_unk_type,
8154 hx_dummy_ptrtype,
8155 hx_get_member_type,
8156 hx_make_pointer,
8157 hx_create_typedef,
8158 hx_get_type,
8159 hx_set_type,
8160 hx_vdloc_t_dstr,
8161 hx_vdloc_t_compare,
8162 hx_vdloc_t_is_aliasable,
8163 hx_print_vdloc,
8164 hx_arglocs_overlap,
8165 hx_lvar_locator_t_compare,
8166 hx_lvar_locator_t_dstr,
8167 hx_lvar_t_dstr,
8168 hx_lvar_t_is_promoted_arg,
8169 hx_lvar_t_accepts_type,
8170 hx_lvar_t_set_lvar_type,
8171 hx_lvar_t_set_width,
8172 hx_lvar_t_append_list_,
8173 hx_lvars_t_find_stkvar,
8174 hx_lvars_t_find,
8175 hx_lvars_t_find_lvar,
8176 hx_restore_user_lvar_settings,
8177 hx_save_user_lvar_settings,
8178 hx_modify_user_lvars,
8179 hx_restore_user_defined_calls,
8180 hx_save_user_defined_calls,
8181 hx_parse_user_call,
8182 hx_convert_to_user_call,
8183 hx_install_microcode_filter,
8184 hx_udc_filter_t_init,
8185 hx_udc_filter_t_apply,
8186 hx_bitset_t_bitset_t,
8187 hx_bitset_t_copy,
8188 hx_bitset_t_add,
8189 hx_bitset_t_add_,
8190 hx_bitset_t_add__,
8191 hx_bitset_t_sub,
8192 hx_bitset_t_sub_,
8193 hx_bitset_t_sub__,
8194 hx_bitset_t_cut_at,
8195 hx_bitset_t_shift_down,
8196 hx_bitset_t_has,
8197 hx_bitset_t_has_all,
8198 hx_bitset_t_has_any,
8199 hx_bitset_t_dstr,
8200 hx_bitset_t_empty,
8201 hx_bitset_t_count,
8202 hx_bitset_t_count_,
8203 hx_bitset_t_last,
8204 hx_bitset_t_fill_with_ones,
8205 hx_bitset_t_has_common,
8206 hx_bitset_t_intersect,
8207 hx_bitset_t_is_subset_of,
8208 hx_bitset_t_compare,
8209 hx_bitset_t_goup,
8210 hx_ivl_t_dstr,
8211 hx_ivl_t_compare,
8212 hx_ivlset_t_add,
8213 hx_ivlset_t_add_,
8214 hx_ivlset_t_addmasked,
8215 hx_ivlset_t_sub,
8216 hx_ivlset_t_sub_,
8217 hx_ivlset_t_has_common,
8218 hx_ivlset_t_print,
8219 hx_ivlset_t_dstr,
8220 hx_ivlset_t_count,
8221 hx_ivlset_t_has_common_,
8222 hx_ivlset_t_contains,
8223 hx_ivlset_t_includes,
8224 hx_ivlset_t_intersect,
8225 hx_ivlset_t_compare,
8226 hx_get_mreg_name,
8227 hx_rlist_t_print,
8228 hx_rlist_t_dstr,
8229 hx_mlist_t_addmem,
8230 hx_mlist_t_print,
8231 hx_mlist_t_dstr,
8232 hx_mlist_t_compare,
8233 hx_lvar_ref_t_compare,
8234 hx_lvar_ref_t_var,
8235 hx_stkvar_ref_t_compare,
8236 hx_stkvar_ref_t_get_stkvar,
8237 hx_fnumber_t_print,
8238 hx_fnumber_t_dstr,
8239 hx_mop_t_copy,
8240 hx_mop_t_assign,
8241 hx_mop_t_swap,
8242 hx_mop_t_erase,
8243 hx_mop_t_print,
8244 hx_mop_t_dstr,
8245 hx_mop_t_create_from_mlist,
8246 hx_mop_t_create_from_ivlset,
8247 hx_mop_t_create_from_vdloc,
8248 hx_mop_t_create_from_scattered_vdloc,
8249 hx_mop_t_create_from_insn,
8250 hx_mop_t_make_number,
8251 hx_mop_t_make_fpnum,
8252 hx_mop_t_make_reg_pair,
8253 hx_mop_t_make_helper,
8254 hx_mop_t_is_bit_reg,
8255 hx_mop_t_may_use_aliased_memory,
8256 hx_mop_t_is01,
8257 hx_mop_t_is_sign_extended_from,
8258 hx_mop_t_is_zero_extended_from,
8259 hx_mop_t_equal_mops,
8260 hx_mop_t_lexcompare,
8261 hx_mop_t_for_all_ops,
8262 hx_mop_t_for_all_scattered_submops,
8263 hx_mop_t_is_constant,
8264 hx_mop_t_get_stkoff,
8265 hx_mop_t_make_low_half,
8266 hx_mop_t_make_high_half,
8267 hx_mop_t_make_first_half,
8268 hx_mop_t_make_second_half,
8269 hx_mop_t_shift_mop,
8270 hx_mop_t_change_size,
8271 hx_mop_t_preserve_side_effects,
8272 hx_mop_t_apply_ld_mcode,
8273 hx_mcallarg_t_print,
8274 hx_mcallarg_t_dstr,
8275 hx_mcallarg_t_set_regarg,
8276 hx_mcallinfo_t_lexcompare,
8277 hx_mcallinfo_t_set_type,
8278 hx_mcallinfo_t_get_type,
8279 hx_mcallinfo_t_print,
8280 hx_mcallinfo_t_dstr,
8281 hx_mcases_t_compare,
8282 hx_mcases_t_print,
8283 hx_mcases_t_dstr,
8284 hx_vivl_t_extend_to_cover,
8285 hx_vivl_t_intersect,
8286 hx_vivl_t_print,
8287 hx_vivl_t_dstr,
8288 hx_chain_t_print,
8289 hx_chain_t_dstr,
8290 hx_chain_t_append_list_,
8291 hx_block_chains_t_get_chain,
8292 hx_block_chains_t_print,
8293 hx_block_chains_t_dstr,
8294 hx_graph_chains_t_for_all_chains,
8295 hx_graph_chains_t_release,
8296 hx_minsn_t_init,
8297 hx_minsn_t_copy,
8298 hx_minsn_t_swap,
8299 hx_minsn_t_print,
8300 hx_minsn_t_dstr,
8301 hx_minsn_t_setaddr,
8302 hx_minsn_t_optimize_subtree,
8303 hx_minsn_t_for_all_ops,
8304 hx_minsn_t_for_all_insns,
8305 hx_minsn_t__make_nop,
8306 hx_minsn_t_equal_insns,
8307 hx_minsn_t_lexcompare,
8308 hx_minsn_t_is_noret_call,
8309 hx_minsn_t_is_helper,
8310 hx_minsn_t_find_call,
8311 hx_minsn_t_has_side_effects,
8312 hx_minsn_t_find_opcode,
8313 hx_minsn_t_find_ins_op,
8314 hx_minsn_t_find_num_op,
8315 hx_minsn_t_modifies_d,
8316 hx_minsn_t_is_between,
8317 hx_minsn_t_may_use_aliased_memory,
8318 hx_getf_reginsn,
8319 hx_getb_reginsn,
8320 hx_mblock_t_init,
8321 hx_mblock_t_print,
8322 hx_mblock_t_dump,
8323 hx_mblock_t_vdump_block,
8324 hx_mblock_t_insert_into_block,
8325 hx_mblock_t_remove_from_block,
8326 hx_mblock_t_for_all_insns,
8327 hx_mblock_t_for_all_ops,
8328 hx_mblock_t_for_all_uses,
8329 hx_mblock_t_optimize_insn,
8330 hx_mblock_t_optimize_block,
8331 hx_mblock_t_build_lists,
8332 hx_mblock_t_append_use_list,
8333 hx_mblock_t_append_def_list,
8334 hx_mblock_t_build_use_list,
8335 hx_mblock_t_build_def_list,
8336 hx_mblock_t_find_first_use,
8337 hx_mblock_t_find_redefinition,
8338 hx_mblock_t_is_rhs_redefined,
8339 hx_mblock_t_find_access,
8340 hx_mblock_t_get_valranges,
8341 hx_mba_t_idaloc2vd,
8342 hx_mba_t_vd2idaloc,
8343 hx_mba_t_term,
8344 hx_mba_t_optimize_local,
8345 hx_mba_t_build_graph,
8346 hx_mba_t_get_graph,
8347 hx_mba_t_analyze_calls,
8348 hx_mba_t_optimize_global,
8349 hx_mba_t_alloc_lvars,
8350 hx_mba_t_dump,
8351 hx_mba_t_vdump_mba,
8352 hx_mba_t_print,
8353 hx_mba_t_verify,
8354 hx_mba_t_mark_chains_dirty,
8355 hx_mba_t_insert_block,
8356 hx_mba_t_remove_block,
8357 hx_mba_t_remove_empty_and_unreachable_blocks,
8358 hx_mba_t_combine_blocks,
8359 hx_mba_t_for_all_ops,
8360 hx_mba_t_for_all_insns,
8361 hx_mba_t_for_all_topinsns,
8362 hx_mba_t_find_mop,
8363 hx_mba_t_arg,
8364 hx_mba_t_serialize,
8365 hx_mba_t_deserialize,
8366 hx_mbl_graph_t_is_accessed_globally,
8367 hx_mbl_graph_t_get_ud,
8368 hx_mbl_graph_t_get_du,
8369 hx_codegen_t_emit,
8370 hx_codegen_t_emit_,
8371 hx_is_kreg,
8372 hx_get_temp_regs,
8373 hx_get_hexrays_version,
8374 hx_open_pseudocode,
8375 hx_close_pseudocode,
8376 hx_get_widget_vdui,
8377 hx_decompile_many,
8378 hx_hexrays_failure_t_desc,
8379 hx_send_database,
8380 hx_gco_info_t_append_to_list,
8381 hx_get_current_operand,
8382 hx_remitem,
8383 hx_negated_relation,
8384 hx_swapped_relation,
8385 hx_get_op_signness,
8386 hx_asgop,
8387 hx_asgop_revert,
8388 hx_cnumber_t_print,
8389 hx_cnumber_t_value,
8390 hx_cnumber_t_assign,
8391 hx_cnumber_t_compare,
8392 hx_var_ref_t_compare,
8393 hx_ctree_visitor_t_apply_to,
8394 hx_ctree_visitor_t_apply_to_exprs,
8395 hx_ctree_parentee_t_recalc_parent_types,
8396 hx_cfunc_parentee_t_calc_rvalue_type,
8397 hx_citem_locator_t_compare,
8398 hx_citem_t_contains_expr,
8399 hx_citem_t_contains_label,
8400 hx_citem_t_find_parent_of,
8401 hx_citem_t_find_closest_addr,
8402 hx_cexpr_t_assign,
8403 hx_cexpr_t_compare,
8404 hx_cexpr_t_replace_by,
8405 hx_cexpr_t_cleanup,
8406 hx_cexpr_t_put_number,
8407 hx_cexpr_t_print1,
8408 hx_cexpr_t_calc_type,
8409 hx_cexpr_t_equal_effect,
8410 hx_cexpr_t_is_child_of,
8411 hx_cexpr_t_contains_operator,
8412 hx_cexpr_t_get_high_nbit_bound,
8413 hx_cexpr_t_get_low_nbit_bound,
8414 hx_cexpr_t_requires_lvalue,
8415 hx_cexpr_t_has_side_effects,
8416 hx_cif_t_assign,
8417 hx_cif_t_compare,
8418 hx_cloop_t_assign,
8419 hx_cfor_t_compare,
8420 hx_cwhile_t_compare,
8421 hx_cdo_t_compare,
8422 hx_creturn_t_compare,
8423 hx_cgoto_t_compare,
8424 hx_casm_t_compare,
8425 hx_cinsn_t_assign,
8426 hx_cinsn_t_compare,
8427 hx_cinsn_t_replace_by,
8428 hx_cinsn_t_cleanup,
8429 hx_cinsn_t_new_insn,
8430 hx_cinsn_t_create_if,
8431 hx_cinsn_t_print,
8432 hx_cinsn_t_print1,
8433 hx_cinsn_t_is_ordinary_flow,
8434 hx_cinsn_t_contains_insn,
8435 hx_cinsn_t_collect_free_breaks,
8436 hx_cinsn_t_collect_free_continues,
8437 hx_cblock_t_compare,
8438 hx_carglist_t_compare,
8439 hx_ccase_t_compare,
8440 hx_ccases_t_compare,
8441 hx_cswitch_t_compare,
8442 hx_ctree_item_t_get_memptr,
8443 hx_ctree_item_t_get_lvar,
8444 hx_ctree_item_t_get_ea,
8445 hx_ctree_item_t_get_label_num,
8446 hx_lnot,
8447 hx_new_block,
8448 hx_vcreate_helper,
8449 hx_vcall_helper,
8450 hx_make_num,
8451 hx_make_ref,
8452 hx_dereference,
8453 hx_save_user_labels,
8454 hx_save_user_cmts,
8455 hx_save_user_numforms,
8456 hx_save_user_iflags,
8457 hx_save_user_unions,
8458 hx_restore_user_labels,
8459 hx_restore_user_cmts,
8460 hx_restore_user_numforms,
8461 hx_restore_user_iflags,
8462 hx_restore_user_unions,
8463 hx_cfunc_t_build_c_tree,
8464 hx_cfunc_t_verify,
8465 hx_cfunc_t_print_dcl,
8466 hx_cfunc_t_print_func,
8467 hx_cfunc_t_get_func_type,
8468 hx_cfunc_t_get_lvars,
8469 hx_cfunc_t_get_stkoff_delta,
8470 hx_cfunc_t_find_label,
8471 hx_cfunc_t_remove_unused_labels,
8472 hx_cfunc_t_get_user_cmt,
8473 hx_cfunc_t_set_user_cmt,
8474 hx_cfunc_t_get_user_iflags,
8475 hx_cfunc_t_set_user_iflags,
8476 hx_cfunc_t_has_orphan_cmts,
8477 hx_cfunc_t_del_orphan_cmts,
8478 hx_cfunc_t_get_user_union_selection,
8479 hx_cfunc_t_set_user_union_selection,
8480 hx_cfunc_t_get_line_item,
8481 hx_cfunc_t_get_warnings,
8482 hx_cfunc_t_get_eamap,
8483 hx_cfunc_t_get_boundaries,
8484 hx_cfunc_t_get_pseudocode,
8485 hx_cfunc_t_gather_derefs,
8486 hx_cfunc_t_find_item_coords,
8487 hx_cfunc_t_cleanup,
8488 hx_decompile,
8489 hx_gen_microcode,
8490 hx_mark_cfunc_dirty,
8491 hx_clear_cached_cfuncs,
8492 hx_has_cached_cfunc,
8493 hx_get_ctype_name,
8494 hx_create_field_name,
8495 hx_install_hexrays_callback,
8496 hx_remove_hexrays_callback,
8497 hx_vdui_t_set_locked,
8498 hx_vdui_t_refresh_view,
8499 hx_vdui_t_refresh_ctext,
8500 hx_vdui_t_switch_to,
8501 hx_vdui_t_get_number,
8502 hx_vdui_t_get_current_label,
8503 hx_vdui_t_clear,
8504 hx_vdui_t_refresh_cpos,
8505 hx_vdui_t_get_current_item,
8506 hx_vdui_t_ui_rename_lvar,
8507 hx_vdui_t_rename_lvar,
8508 hx_vdui_t_ui_set_call_type,
8509 hx_vdui_t_ui_set_lvar_type,
8510 hx_vdui_t_set_lvar_type,
8511 hx_vdui_t_ui_edit_lvar_cmt,
8512 hx_vdui_t_set_lvar_cmt,
8513 hx_vdui_t_ui_map_lvar,
8514 hx_vdui_t_ui_unmap_lvar,
8515 hx_vdui_t_map_lvar,
8516 hx_vdui_t_set_strmem_type,
8517 hx_vdui_t_rename_strmem,
8518 hx_vdui_t_set_global_type,
8519 hx_vdui_t_rename_global,
8520 hx_vdui_t_rename_label,
8521 hx_vdui_t_jump_enter,
8522 hx_vdui_t_ctree_to_disasm,
8523 hx_vdui_t_calc_cmt_type,
8524 hx_vdui_t_edit_cmt,
8525 hx_vdui_t_edit_func_cmt,
8526 hx_vdui_t_del_orphan_cmts,
8527 hx_vdui_t_set_num_radix,
8528 hx_vdui_t_set_num_enum,
8529 hx_vdui_t_set_num_stroff,
8530 hx_vdui_t_invert_sign,
8531 hx_vdui_t_invert_bits,
8532 hx_vdui_t_collapse_item,
8533 hx_vdui_t_collapse_lvars,
8534 hx_vdui_t_split_item,
8535 hx_hexrays_alloc,
8536 hx_hexrays_free,
8537 hx_vdui_t_set_noptr_lvar,
8538 hx_select_udt_by_offset,
8539 hx_mblock_t_get_valranges_,
8540 hx_cfunc_t_refresh_func_ctext,
8541 hx_checkout_hexrays_license,
8542 hx_mba_t_copy_block,
8543 hx_mblock_t_optimize_useless_jump,
8544 hx_mblock_t_get_reginsn_qty,
8545 hx_modify_user_lvar_info,
8546 hx_cdg_insn_iterator_t_next,
8547 hx_restore_user_labels2,
8548 hx_save_user_labels2,
8549 hx_mba_ranges_t_range_contains,
8550 hx_close_hexrays_waitbox,
8551 hx_mba_t_map_fict_ea,
8552 hx_mba_t_alloc_fict_ea,
8553 hx_mba_t_alloc_kreg,
8554 hx_mba_t_free_kreg,
8555 hx_mba_t_idaloc2vd_,
8556 hx_mba_t_vd2idaloc_,
8557 hx_bitset_t_fill_gaps,
8558 hx_cfunc_t_save_user_labels,
8559 hx_cfunc_t_save_user_cmts,
8560 hx_cfunc_t_save_user_numforms,
8561 hx_cfunc_t_save_user_iflags,
8562 hx_cfunc_t_save_user_unions,
8563 hx_minsn_t_set_combined,
8564 hx_mba_t_save_snapshot,
8565 hx_create_cfunc,
8566 hx_mba_t_set_maturity,
8567 hx_rename_lvar,
8568 hx_locate_lvar,
8569 hx_mba_t_create_helper_call,
8570 hx_lvar_t_append_list,
8571 hx_chain_t_append_list,
8572 hx_udc_filter_t_cleanup,
8573 hx_mba_t_get_curfunc,
8574 hx_mop_t__make_gvar,
8575 hx_mop_t_make_gvar,
8576 hx_cexpr_t_maybe_ptr,
8577 hx_minsn_t_serialize,
8578 hx_minsn_t_deserialize,
8579 hx_mba_t_stkoff_vd2ida,
8580 hx_mba_t_stkoff_ida2vd,
8581 hx_cexpr_t_dstr,
8582 hx_cinsn_t_dstr,
8583 hx_ctree_item_t_print,
8584 hx_ctree_item_t_dstr,
8585 hx_mba_t_set_lvar_name,
8586 hx_change_hexrays_config,
8587 hx_mba_t_get_func_output_lists,
8588 hx_vdui_t_rename_udm,
8589 hx_vdui_t_set_udm_type,
8590 hx_ctree_item_t_get_udm,
8591 hx_ctree_item_t_get_edm,
8592};
8593
8594typedef size_t iterator_word;
8595
8596//--------------------------------------------------------------------------
8597/// Check that your plugin is compatible with hex-rays decompiler.
8598/// This function must be called before calling any other decompiler function.
8599/// \param flags reserved, must be 0
8600/// \return true if the decompiler exists and is compatible with your plugin
8601inline bool init_hexrays_plugin(int flags=0)
8602{
8603 hexdsp_t *dummy;
8604 return callui(ui_broadcast, HEXRAYS_API_MAGIC, &dummy, flags).i == (HEXRAYS_API_MAGIC >> 32);
8605}
8606
8607//--------------------------------------------------------------------------
8608/// Stop working with hex-rays decompiler.
8610{
8611}
8612
8613
8614//-------------------------------------------------------------------------
8616{
8617 iterator_word x;
8618 bool operator==(const user_numforms_iterator_t &p) const { return x == p.x; }
8619 bool operator!=(const user_numforms_iterator_t &p) const { return x != p.x; }
8620};
8621
8622//-------------------------------------------------------------------------
8623/// Get reference to the current map key
8625{
8626 return *(operand_locator_t *)HEXDSP(hx_user_numforms_first, &p);
8627}
8628
8629//-------------------------------------------------------------------------
8630/// Get reference to the current map value
8632{
8633 return *(number_format_t *)HEXDSP(hx_user_numforms_second, &p);
8634}
8635
8636//-------------------------------------------------------------------------
8637/// Find the specified key in user_numforms_t
8639{
8641 HEXDSP(hx_user_numforms_find, &p, map, &key);
8642 return p;
8643}
8644
8645//-------------------------------------------------------------------------
8646/// Insert new (operand_locator_t, number_format_t) pair into user_numforms_t
8648{
8650 HEXDSP(hx_user_numforms_insert, &p, map, &key, &val);
8651 return p;
8652}
8653
8654//-------------------------------------------------------------------------
8655/// Get iterator pointing to the beginning of user_numforms_t
8657{
8659 HEXDSP(hx_user_numforms_begin, &p, map);
8660 return p;
8661}
8662
8663//-------------------------------------------------------------------------
8664/// Get iterator pointing to the end of user_numforms_t
8666{
8668 HEXDSP(hx_user_numforms_end, &p, map);
8669 return p;
8670}
8671
8672//-------------------------------------------------------------------------
8673/// Move to the next element
8675{
8676 HEXDSP(hx_user_numforms_next, &p);
8677 return p;
8678}
8679
8680//-------------------------------------------------------------------------
8681/// Move to the previous element
8683{
8684 HEXDSP(hx_user_numforms_prev, &p);
8685 return p;
8686}
8687
8688//-------------------------------------------------------------------------
8689/// Erase current element from user_numforms_t
8691{
8692 HEXDSP(hx_user_numforms_erase, map, &p);
8693}
8694
8695//-------------------------------------------------------------------------
8696/// Clear user_numforms_t
8698{
8699 HEXDSP(hx_user_numforms_clear, map);
8700}
8701
8702//-------------------------------------------------------------------------
8703/// Get size of user_numforms_t
8705{
8706 return (size_t)HEXDSP(hx_user_numforms_size, map);
8707}
8708
8709//-------------------------------------------------------------------------
8710/// Delete user_numforms_t instance
8712{
8713 HEXDSP(hx_user_numforms_free, map);
8714}
8715
8716//-------------------------------------------------------------------------
8717/// Create a new user_numforms_t instance
8719{
8720 return (user_numforms_t *)HEXDSP(hx_user_numforms_new);
8721}
8722
8723//-------------------------------------------------------------------------
8725{
8726 iterator_word x;
8727 bool operator==(const lvar_mapping_iterator_t &p) const { return x == p.x; }
8728 bool operator!=(const lvar_mapping_iterator_t &p) const { return x != p.x; }
8729};
8730
8731//-------------------------------------------------------------------------
8732/// Get reference to the current map key
8734{
8735 return *(lvar_locator_t *)HEXDSP(hx_lvar_mapping_first, &p);
8736}
8737
8738//-------------------------------------------------------------------------
8739/// Get reference to the current map value
8741{
8742 return *(lvar_locator_t *)HEXDSP(hx_lvar_mapping_second, &p);
8743}
8744
8745//-------------------------------------------------------------------------
8746/// Find the specified key in lvar_mapping_t
8748{
8750 HEXDSP(hx_lvar_mapping_find, &p, map, &key);
8751 return p;
8752}
8753
8754//-------------------------------------------------------------------------
8755/// Insert new (lvar_locator_t, lvar_locator_t) pair into lvar_mapping_t
8757{
8759 HEXDSP(hx_lvar_mapping_insert, &p, map, &key, &val);
8760 return p;
8761}
8762
8763//-------------------------------------------------------------------------
8764/// Get iterator pointing to the beginning of lvar_mapping_t
8766{
8768 HEXDSP(hx_lvar_mapping_begin, &p, map);
8769 return p;
8770}
8771
8772//-------------------------------------------------------------------------
8773/// Get iterator pointing to the end of lvar_mapping_t
8775{
8777 HEXDSP(hx_lvar_mapping_end, &p, map);
8778 return p;
8779}
8780
8781//-------------------------------------------------------------------------
8782/// Move to the next element
8784{
8785 HEXDSP(hx_lvar_mapping_next, &p);
8786 return p;
8787}
8788
8789//-------------------------------------------------------------------------
8790/// Move to the previous element
8792{
8793 HEXDSP(hx_lvar_mapping_prev, &p);
8794 return p;
8795}
8796
8797//-------------------------------------------------------------------------
8798/// Erase current element from lvar_mapping_t
8800{
8801 HEXDSP(hx_lvar_mapping_erase, map, &p);
8802}
8803
8804//-------------------------------------------------------------------------
8805/// Clear lvar_mapping_t
8807{
8808 HEXDSP(hx_lvar_mapping_clear, map);
8809}
8810
8811//-------------------------------------------------------------------------
8812/// Get size of lvar_mapping_t
8814{
8815 return (size_t)HEXDSP(hx_lvar_mapping_size, map);
8816}
8817
8818//-------------------------------------------------------------------------
8819/// Delete lvar_mapping_t instance
8821{
8822 HEXDSP(hx_lvar_mapping_free, map);
8823}
8824
8825//-------------------------------------------------------------------------
8826/// Create a new lvar_mapping_t instance
8828{
8829 return (lvar_mapping_t *)HEXDSP(hx_lvar_mapping_new);
8830}
8831
8832//-------------------------------------------------------------------------
8834{
8835 iterator_word x;
8836 bool operator==(const udcall_map_iterator_t &p) const { return x == p.x; }
8837 bool operator!=(const udcall_map_iterator_t &p) const { return x != p.x; }
8838};
8839
8840//-------------------------------------------------------------------------
8841/// Get reference to the current map key
8843{
8844 return *(ea_t *)HEXDSP(hx_udcall_map_first, &p);
8845}
8846
8847//-------------------------------------------------------------------------
8848/// Get reference to the current map value
8850{
8851 return *(udcall_t *)HEXDSP(hx_udcall_map_second, &p);
8852}
8853
8854//-------------------------------------------------------------------------
8855/// Find the specified key in udcall_map_t
8856inline udcall_map_iterator_t udcall_map_find(const udcall_map_t *map, const ea_t &key)
8857{
8859 HEXDSP(hx_udcall_map_find, &p, map, &key);
8860 return p;
8861}
8862
8863//-------------------------------------------------------------------------
8864/// Insert new (ea_t, udcall_t) pair into udcall_map_t
8865inline udcall_map_iterator_t udcall_map_insert(udcall_map_t *map, const ea_t &key, const udcall_t &val)
8866{
8868 HEXDSP(hx_udcall_map_insert, &p, map, &key, &val);
8869 return p;
8870}
8871
8872//-------------------------------------------------------------------------
8873/// Get iterator pointing to the beginning of udcall_map_t
8874inline udcall_map_iterator_t udcall_map_begin(const udcall_map_t *map)
8875{
8877 HEXDSP(hx_udcall_map_begin, &p, map);
8878 return p;
8879}
8880
8881//-------------------------------------------------------------------------
8882/// Get iterator pointing to the end of udcall_map_t
8883inline udcall_map_iterator_t udcall_map_end(const udcall_map_t *map)
8884{
8886 HEXDSP(hx_udcall_map_end, &p, map);
8887 return p;
8888}
8889
8890//-------------------------------------------------------------------------
8891/// Move to the next element
8893{
8894 HEXDSP(hx_udcall_map_next, &p);
8895 return p;
8896}
8897
8898//-------------------------------------------------------------------------
8899/// Move to the previous element
8901{
8902 HEXDSP(hx_udcall_map_prev, &p);
8903 return p;
8904}
8905
8906//-------------------------------------------------------------------------
8907/// Erase current element from udcall_map_t
8908inline void udcall_map_erase(udcall_map_t *map, udcall_map_iterator_t p)
8909{
8910 HEXDSP(hx_udcall_map_erase, map, &p);
8911}
8912
8913//-------------------------------------------------------------------------
8914/// Clear udcall_map_t
8915inline void udcall_map_clear(udcall_map_t *map)
8916{
8917 HEXDSP(hx_udcall_map_clear, map);
8918}
8919
8920//-------------------------------------------------------------------------
8921/// Get size of udcall_map_t
8922inline size_t udcall_map_size(udcall_map_t *map)
8923{
8924 return (size_t)HEXDSP(hx_udcall_map_size, map);
8925}
8926
8927//-------------------------------------------------------------------------
8928/// Delete udcall_map_t instance
8929inline void udcall_map_free(udcall_map_t *map)
8930{
8931 HEXDSP(hx_udcall_map_free, map);
8932}
8933
8934//-------------------------------------------------------------------------
8935/// Create a new udcall_map_t instance
8936inline udcall_map_t *udcall_map_new()
8937{
8938 return (udcall_map_t *)HEXDSP(hx_udcall_map_new);
8939}
8940
8941//-------------------------------------------------------------------------
8943{
8944 iterator_word x;
8945 bool operator==(const user_cmts_iterator_t &p) const { return x == p.x; }
8946 bool operator!=(const user_cmts_iterator_t &p) const { return x != p.x; }
8947};
8948
8949//-------------------------------------------------------------------------
8950/// Get reference to the current map key
8952{
8953 return *(treeloc_t *)HEXDSP(hx_user_cmts_first, &p);
8954}
8955
8956//-------------------------------------------------------------------------
8957/// Get reference to the current map value
8959{
8960 return *(citem_cmt_t *)HEXDSP(hx_user_cmts_second, &p);
8961}
8962
8963//-------------------------------------------------------------------------
8964/// Find the specified key in user_cmts_t
8966{
8968 HEXDSP(hx_user_cmts_find, &p, map, &key);
8969 return p;
8970}
8971
8972//-------------------------------------------------------------------------
8973/// Insert new (treeloc_t, citem_cmt_t) pair into user_cmts_t
8975{
8977 HEXDSP(hx_user_cmts_insert, &p, map, &key, &val);
8978 return p;
8979}
8980
8981//-------------------------------------------------------------------------
8982/// Get iterator pointing to the beginning of user_cmts_t
8984{
8986 HEXDSP(hx_user_cmts_begin, &p, map);
8987 return p;
8988}
8989
8990//-------------------------------------------------------------------------
8991/// Get iterator pointing to the end of user_cmts_t
8993{
8995 HEXDSP(hx_user_cmts_end, &p, map);
8996 return p;
8997}
8998
8999//-------------------------------------------------------------------------
9000/// Move to the next element
9002{
9003 HEXDSP(hx_user_cmts_next, &p);
9004 return p;
9005}
9006
9007//-------------------------------------------------------------------------
9008/// Move to the previous element
9010{
9011 HEXDSP(hx_user_cmts_prev, &p);
9012 return p;
9013}
9014
9015//-------------------------------------------------------------------------
9016/// Erase current element from user_cmts_t
9018{
9019 HEXDSP(hx_user_cmts_erase, map, &p);
9020}
9021
9022//-------------------------------------------------------------------------
9023/// Clear user_cmts_t
9025{
9026 HEXDSP(hx_user_cmts_clear, map);
9027}
9028
9029//-------------------------------------------------------------------------
9030/// Get size of user_cmts_t
9031inline size_t user_cmts_size(user_cmts_t *map)
9032{
9033 return (size_t)HEXDSP(hx_user_cmts_size, map);
9034}
9035
9036//-------------------------------------------------------------------------
9037/// Delete user_cmts_t instance
9039{
9040 HEXDSP(hx_user_cmts_free, map);
9041}
9042
9043//-------------------------------------------------------------------------
9044/// Create a new user_cmts_t instance
9046{
9047 return (user_cmts_t *)HEXDSP(hx_user_cmts_new);
9048}
9049
9050//-------------------------------------------------------------------------
9052{
9053 iterator_word x;
9054 bool operator==(const user_iflags_iterator_t &p) const { return x == p.x; }
9055 bool operator!=(const user_iflags_iterator_t &p) const { return x != p.x; }
9056};
9057
9058//-------------------------------------------------------------------------
9059/// Get reference to the current map key
9061{
9062 return *(citem_locator_t *)HEXDSP(hx_user_iflags_first, &p);
9063}
9064
9065//-------------------------------------------------------------------------
9066/// Get reference to the current map value
9068{
9069 return *(int32 *)HEXDSP(hx_user_iflags_second, &p);
9070}
9071
9072//-------------------------------------------------------------------------
9073/// Find the specified key in user_iflags_t
9074inline user_iflags_iterator_t user_iflags_find(const user_iflags_t *map, const citem_locator_t &key)
9075{
9077 HEXDSP(hx_user_iflags_find, &p, map, &key);
9078 return p;
9079}
9080
9081//-------------------------------------------------------------------------
9082/// Insert new (citem_locator_t, int32) pair into user_iflags_t
9083inline user_iflags_iterator_t user_iflags_insert(user_iflags_t *map, const citem_locator_t &key, const int32 &val)
9084{
9086 HEXDSP(hx_user_iflags_insert, &p, map, &key, &val);
9087 return p;
9088}
9089
9090//-------------------------------------------------------------------------
9091/// Get iterator pointing to the beginning of user_iflags_t
9092inline user_iflags_iterator_t user_iflags_begin(const user_iflags_t *map)
9093{
9095 HEXDSP(hx_user_iflags_begin, &p, map);
9096 return p;
9097}
9098
9099//-------------------------------------------------------------------------
9100/// Get iterator pointing to the end of user_iflags_t
9101inline user_iflags_iterator_t user_iflags_end(const user_iflags_t *map)
9102{
9104 HEXDSP(hx_user_iflags_end, &p, map);
9105 return p;
9106}
9107
9108//-------------------------------------------------------------------------
9109/// Move to the next element
9111{
9112 HEXDSP(hx_user_iflags_next, &p);
9113 return p;
9114}
9115
9116//-------------------------------------------------------------------------
9117/// Move to the previous element
9119{
9120 HEXDSP(hx_user_iflags_prev, &p);
9121 return p;
9122}
9123
9124//-------------------------------------------------------------------------
9125/// Erase current element from user_iflags_t
9126inline void user_iflags_erase(user_iflags_t *map, user_iflags_iterator_t p)
9127{
9128 HEXDSP(hx_user_iflags_erase, map, &p);
9129}
9130
9131//-------------------------------------------------------------------------
9132/// Clear user_iflags_t
9133inline void user_iflags_clear(user_iflags_t *map)
9134{
9135 HEXDSP(hx_user_iflags_clear, map);
9136}
9137
9138//-------------------------------------------------------------------------
9139/// Get size of user_iflags_t
9140inline size_t user_iflags_size(user_iflags_t *map)
9141{
9142 return (size_t)HEXDSP(hx_user_iflags_size, map);
9143}
9144
9145//-------------------------------------------------------------------------
9146/// Delete user_iflags_t instance
9147inline void user_iflags_free(user_iflags_t *map)
9148{
9149 HEXDSP(hx_user_iflags_free, map);
9150}
9151
9152//-------------------------------------------------------------------------
9153/// Create a new user_iflags_t instance
9154inline user_iflags_t *user_iflags_new()
9155{
9156 return (user_iflags_t *)HEXDSP(hx_user_iflags_new);
9157}
9158
9159//-------------------------------------------------------------------------
9161{
9162 iterator_word x;
9163 bool operator==(const user_unions_iterator_t &p) const { return x == p.x; }
9164 bool operator!=(const user_unions_iterator_t &p) const { return x != p.x; }
9165};
9166
9167//-------------------------------------------------------------------------
9168/// Get reference to the current map key
9170{
9171 return *(ea_t *)HEXDSP(hx_user_unions_first, &p);
9172}
9173
9174//-------------------------------------------------------------------------
9175/// Get reference to the current map value
9177{
9178 return *(intvec_t *)HEXDSP(hx_user_unions_second, &p);
9179}
9180
9181//-------------------------------------------------------------------------
9182/// Find the specified key in user_unions_t
9183inline user_unions_iterator_t user_unions_find(const user_unions_t *map, const ea_t &key)
9184{
9186 HEXDSP(hx_user_unions_find, &p, map, &key);
9187 return p;
9188}
9189
9190//-------------------------------------------------------------------------
9191/// Insert new (ea_t, intvec_t) pair into user_unions_t
9192inline user_unions_iterator_t user_unions_insert(user_unions_t *map, const ea_t &key, const intvec_t &val)
9193{
9195 HEXDSP(hx_user_unions_insert, &p, map, &key, &val);
9196 return p;
9197}
9198
9199//-------------------------------------------------------------------------
9200/// Get iterator pointing to the beginning of user_unions_t
9201inline user_unions_iterator_t user_unions_begin(const user_unions_t *map)
9202{
9204 HEXDSP(hx_user_unions_begin, &p, map);
9205 return p;
9206}
9207
9208//-------------------------------------------------------------------------
9209/// Get iterator pointing to the end of user_unions_t
9210inline user_unions_iterator_t user_unions_end(const user_unions_t *map)
9211{
9213 HEXDSP(hx_user_unions_end, &p, map);
9214 return p;
9215}
9216
9217//-------------------------------------------------------------------------
9218/// Move to the next element
9220{
9221 HEXDSP(hx_user_unions_next, &p);
9222 return p;
9223}
9224
9225//-------------------------------------------------------------------------
9226/// Move to the previous element
9228{
9229 HEXDSP(hx_user_unions_prev, &p);
9230 return p;
9231}
9232
9233//-------------------------------------------------------------------------
9234/// Erase current element from user_unions_t
9235inline void user_unions_erase(user_unions_t *map, user_unions_iterator_t p)
9236{
9237 HEXDSP(hx_user_unions_erase, map, &p);
9238}
9239
9240//-------------------------------------------------------------------------
9241/// Clear user_unions_t
9242inline void user_unions_clear(user_unions_t *map)
9243{
9244 HEXDSP(hx_user_unions_clear, map);
9245}
9246
9247//-------------------------------------------------------------------------
9248/// Get size of user_unions_t
9249inline size_t user_unions_size(user_unions_t *map)
9250{
9251 return (size_t)HEXDSP(hx_user_unions_size, map);
9252}
9253
9254//-------------------------------------------------------------------------
9255/// Delete user_unions_t instance
9256inline void user_unions_free(user_unions_t *map)
9257{
9258 HEXDSP(hx_user_unions_free, map);
9259}
9260
9261//-------------------------------------------------------------------------
9262/// Create a new user_unions_t instance
9263inline user_unions_t *user_unions_new()
9264{
9265 return (user_unions_t *)HEXDSP(hx_user_unions_new);
9266}
9267
9268//-------------------------------------------------------------------------
9270{
9271 iterator_word x;
9272 bool operator==(const user_labels_iterator_t &p) const { return x == p.x; }
9273 bool operator!=(const user_labels_iterator_t &p) const { return x != p.x; }
9274};
9275
9276//-------------------------------------------------------------------------
9277/// Get reference to the current map key
9279{
9280 return *(int *)HEXDSP(hx_user_labels_first, &p);
9281}
9282
9283//-------------------------------------------------------------------------
9284/// Get reference to the current map value
9286{
9287 return *(qstring *)HEXDSP(hx_user_labels_second, &p);
9288}
9289
9290//-------------------------------------------------------------------------
9291/// Find the specified key in user_labels_t
9293{
9295 HEXDSP(hx_user_labels_find, &p, map, &key);
9296 return p;
9297}
9298
9299//-------------------------------------------------------------------------
9300/// Insert new (int, qstring) pair into user_labels_t
9301inline user_labels_iterator_t user_labels_insert(user_labels_t *map, const int &key, const qstring &val)
9302{
9304 HEXDSP(hx_user_labels_insert, &p, map, &key, &val);
9305 return p;
9306}
9307
9308//-------------------------------------------------------------------------
9309/// Get iterator pointing to the beginning of user_labels_t
9311{
9313 HEXDSP(hx_user_labels_begin, &p, map);
9314 return p;
9315}
9316
9317//-------------------------------------------------------------------------
9318/// Get iterator pointing to the end of user_labels_t
9320{
9322 HEXDSP(hx_user_labels_end, &p, map);
9323 return p;
9324}
9325
9326//-------------------------------------------------------------------------
9327/// Move to the next element
9329{
9330 HEXDSP(hx_user_labels_next, &p);
9331 return p;
9332}
9333
9334//-------------------------------------------------------------------------
9335/// Move to the previous element
9337{
9338 HEXDSP(hx_user_labels_prev, &p);
9339 return p;
9340}
9341
9342//-------------------------------------------------------------------------
9343/// Erase current element from user_labels_t
9345{
9346 HEXDSP(hx_user_labels_erase, map, &p);
9347}
9348
9349//-------------------------------------------------------------------------
9350/// Clear user_labels_t
9352{
9353 HEXDSP(hx_user_labels_clear, map);
9354}
9355
9356//-------------------------------------------------------------------------
9357/// Get size of user_labels_t
9359{
9360 return (size_t)HEXDSP(hx_user_labels_size, map);
9361}
9362
9363//-------------------------------------------------------------------------
9364/// Delete user_labels_t instance
9366{
9367 HEXDSP(hx_user_labels_free, map);
9368}
9369
9370//-------------------------------------------------------------------------
9371/// Create a new user_labels_t instance
9373{
9374 return (user_labels_t *)HEXDSP(hx_user_labels_new);
9375}
9376
9377//-------------------------------------------------------------------------
9379{
9380 iterator_word x;
9381 bool operator==(const eamap_iterator_t &p) const { return x == p.x; }
9382 bool operator!=(const eamap_iterator_t &p) const { return x != p.x; }
9383};
9384
9385//-------------------------------------------------------------------------
9386/// Get reference to the current map key
9387inline ea_t const &eamap_first(eamap_iterator_t p)
9388{
9389 return *(ea_t *)HEXDSP(hx_eamap_first, &p);
9390}
9391
9392//-------------------------------------------------------------------------
9393/// Get reference to the current map value
9395{
9396 return *(cinsnptrvec_t *)HEXDSP(hx_eamap_second, &p);
9397}
9398
9399//-------------------------------------------------------------------------
9400/// Find the specified key in eamap_t
9401inline eamap_iterator_t eamap_find(const eamap_t *map, const ea_t &key)
9402{
9404 HEXDSP(hx_eamap_find, &p, map, &key);
9405 return p;
9406}
9407
9408//-------------------------------------------------------------------------
9409/// Insert new (ea_t, cinsnptrvec_t) pair into eamap_t
9410inline eamap_iterator_t eamap_insert(eamap_t *map, const ea_t &key, const cinsnptrvec_t &val)
9411{
9413 HEXDSP(hx_eamap_insert, &p, map, &key, &val);
9414 return p;
9415}
9416
9417//-------------------------------------------------------------------------
9418/// Get iterator pointing to the beginning of eamap_t
9419inline eamap_iterator_t eamap_begin(const eamap_t *map)
9420{
9422 HEXDSP(hx_eamap_begin, &p, map);
9423 return p;
9424}
9425
9426//-------------------------------------------------------------------------
9427/// Get iterator pointing to the end of eamap_t
9428inline eamap_iterator_t eamap_end(const eamap_t *map)
9429{
9431 HEXDSP(hx_eamap_end, &p, map);
9432 return p;
9433}
9434
9435//-------------------------------------------------------------------------
9436/// Move to the next element
9438{
9439 HEXDSP(hx_eamap_next, &p);
9440 return p;
9441}
9442
9443//-------------------------------------------------------------------------
9444/// Move to the previous element
9446{
9447 HEXDSP(hx_eamap_prev, &p);
9448 return p;
9449}
9450
9451//-------------------------------------------------------------------------
9452/// Erase current element from eamap_t
9453inline void eamap_erase(eamap_t *map, eamap_iterator_t p)
9454{
9455 HEXDSP(hx_eamap_erase, map, &p);
9456}
9457
9458//-------------------------------------------------------------------------
9459/// Clear eamap_t
9460inline void eamap_clear(eamap_t *map)
9461{
9462 HEXDSP(hx_eamap_clear, map);
9463}
9464
9465//-------------------------------------------------------------------------
9466/// Get size of eamap_t
9467inline size_t eamap_size(eamap_t *map)
9468{
9469 return (size_t)HEXDSP(hx_eamap_size, map);
9470}
9471
9472//-------------------------------------------------------------------------
9473/// Delete eamap_t instance
9474inline void eamap_free(eamap_t *map)
9475{
9476 HEXDSP(hx_eamap_free, map);
9477}
9478
9479//-------------------------------------------------------------------------
9480/// Create a new eamap_t instance
9481inline eamap_t *eamap_new()
9482{
9483 return (eamap_t *)HEXDSP(hx_eamap_new);
9484}
9485
9486//-------------------------------------------------------------------------
9488{
9489 iterator_word x;
9490 bool operator==(const boundaries_iterator_t &p) const { return x == p.x; }
9491 bool operator!=(const boundaries_iterator_t &p) const { return x != p.x; }
9492};
9493
9494//-------------------------------------------------------------------------
9495/// Get reference to the current map key
9497{
9498 return *(cinsn_t * *)HEXDSP(hx_boundaries_first, &p);
9499}
9500
9501//-------------------------------------------------------------------------
9502/// Get reference to the current map value
9504{
9505 return *(rangeset_t *)HEXDSP(hx_boundaries_second, &p);
9506}
9507
9508//-------------------------------------------------------------------------
9509/// Find the specified key in boundaries_t
9510inline boundaries_iterator_t boundaries_find(const boundaries_t *map, const cinsn_t * &key)
9511{
9513 HEXDSP(hx_boundaries_find, &p, map, &key);
9514 return p;
9515}
9516
9517//-------------------------------------------------------------------------
9518/// Insert new (cinsn_t *, rangeset_t) pair into boundaries_t
9519inline boundaries_iterator_t boundaries_insert(boundaries_t *map, const cinsn_t * &key, const rangeset_t &val)
9520{
9522 HEXDSP(hx_boundaries_insert, &p, map, &key, &val);
9523 return p;
9524}
9525
9526//-------------------------------------------------------------------------
9527/// Get iterator pointing to the beginning of boundaries_t
9528inline boundaries_iterator_t boundaries_begin(const boundaries_t *map)
9529{
9531 HEXDSP(hx_boundaries_begin, &p, map);
9532 return p;
9533}
9534
9535//-------------------------------------------------------------------------
9536/// Get iterator pointing to the end of boundaries_t
9537inline boundaries_iterator_t boundaries_end(const boundaries_t *map)
9538{
9540 HEXDSP(hx_boundaries_end, &p, map);
9541 return p;
9542}
9543
9544//-------------------------------------------------------------------------
9545/// Move to the next element
9547{
9548 HEXDSP(hx_boundaries_next, &p);
9549 return p;
9550}
9551
9552//-------------------------------------------------------------------------
9553/// Move to the previous element
9555{
9556 HEXDSP(hx_boundaries_prev, &p);
9557 return p;
9558}
9559
9560//-------------------------------------------------------------------------
9561/// Erase current element from boundaries_t
9562inline void boundaries_erase(boundaries_t *map, boundaries_iterator_t p)
9563{
9564 HEXDSP(hx_boundaries_erase, map, &p);
9565}
9566
9567//-------------------------------------------------------------------------
9568/// Clear boundaries_t
9569inline void boundaries_clear(boundaries_t *map)
9570{
9571 HEXDSP(hx_boundaries_clear, map);
9572}
9573
9574//-------------------------------------------------------------------------
9575/// Get size of boundaries_t
9576inline size_t boundaries_size(boundaries_t *map)
9577{
9578 return (size_t)HEXDSP(hx_boundaries_size, map);
9579}
9580
9581//-------------------------------------------------------------------------
9582/// Delete boundaries_t instance
9583inline void boundaries_free(boundaries_t *map)
9584{
9585 HEXDSP(hx_boundaries_free, map);
9586}
9587
9588//-------------------------------------------------------------------------
9589/// Create a new boundaries_t instance
9590inline boundaries_t *boundaries_new()
9591{
9592 return (boundaries_t *)HEXDSP(hx_boundaries_new);
9593}
9594
9595//-------------------------------------------------------------------------
9597{
9598 iterator_word x;
9599 bool operator==(const block_chains_iterator_t &p) const { return x == p.x; }
9600 bool operator!=(const block_chains_iterator_t &p) const { return x != p.x; }
9601};
9602
9603//-------------------------------------------------------------------------
9604/// Get reference to the current set value
9606{
9607 return *(chain_t *)HEXDSP(hx_block_chains_get, &p);
9608}
9609
9610//-------------------------------------------------------------------------
9611/// Find the specified key in set block_chains_t
9613{
9615 HEXDSP(hx_block_chains_find, &p, set, &val);
9616 return p;
9617}
9618
9619//-------------------------------------------------------------------------
9620/// Insert new (chain_t) into set block_chains_t
9622{
9624 HEXDSP(hx_block_chains_insert, &p, set, &val);
9625 return p;
9626}
9627
9628//-------------------------------------------------------------------------
9629/// Get iterator pointing to the beginning of block_chains_t
9631{
9633 HEXDSP(hx_block_chains_begin, &p, set);
9634 return p;
9635}
9636
9637//-------------------------------------------------------------------------
9638/// Get iterator pointing to the end of block_chains_t
9640{
9642 HEXDSP(hx_block_chains_end, &p, set);
9643 return p;
9644}
9645
9646//-------------------------------------------------------------------------
9647/// Move to the next element
9649{
9650 HEXDSP(hx_block_chains_next, &p);
9651 return p;
9652}
9653
9654//-------------------------------------------------------------------------
9655/// Move to the previous element
9657{
9658 HEXDSP(hx_block_chains_prev, &p);
9659 return p;
9660}
9661
9662//-------------------------------------------------------------------------
9663/// Erase current element from block_chains_t
9665{
9666 HEXDSP(hx_block_chains_erase, set, &p);
9667}
9668
9669//-------------------------------------------------------------------------
9670/// Clear block_chains_t
9672{
9673 HEXDSP(hx_block_chains_clear, set);
9674}
9675
9676//-------------------------------------------------------------------------
9677/// Get size of block_chains_t
9679{
9680 return (size_t)HEXDSP(hx_block_chains_size, set);
9681}
9682
9683//-------------------------------------------------------------------------
9684/// Delete block_chains_t instance
9686{
9687 HEXDSP(hx_block_chains_free, set);
9688}
9689
9690//-------------------------------------------------------------------------
9691/// Create a new block_chains_t instance
9693{
9694 return (block_chains_t *)HEXDSP(hx_block_chains_new);
9695}
9696
9697//--------------------------------------------------------------------------
9698inline void *hexrays_alloc(size_t size)
9699{
9700 return HEXDSP(hx_hexrays_alloc, size);
9701}
9702
9703//--------------------------------------------------------------------------
9704inline void hexrays_free(void *ptr)
9705{
9706 HEXDSP(hx_hexrays_free, ptr);
9707}
9708
9709//--------------------------------------------------------------------------
9710inline void valrng_t::clear()
9711{
9712 HEXDSP(hx_valrng_t_clear, this);
9713}
9714
9715//--------------------------------------------------------------------------
9716inline void valrng_t::copy(const valrng_t &r)
9717{
9718 HEXDSP(hx_valrng_t_copy, this, &r);
9719}
9720
9721//--------------------------------------------------------------------------
9722inline valrng_t &valrng_t::assign(const valrng_t &r)
9723{
9724 return *(valrng_t *)HEXDSP(hx_valrng_t_assign, this, &r);
9725}
9726
9727//--------------------------------------------------------------------------
9728inline int valrng_t::compare(const valrng_t &r) const
9729{
9730 return (int)(size_t)HEXDSP(hx_valrng_t_compare, this, &r);
9731}
9732
9733//--------------------------------------------------------------------------
9734inline void valrng_t::set_eq(uvlr_t v)
9735{
9736 HEXDSP(hx_valrng_t_set_eq, this, v);
9737}
9738
9739//--------------------------------------------------------------------------
9740inline void valrng_t::set_cmp(cmpop_t cmp, uvlr_t _value)
9741{
9742 HEXDSP(hx_valrng_t_set_cmp, this, cmp, _value);
9743}
9744
9745//--------------------------------------------------------------------------
9746inline bool valrng_t::reduce_size(int new_size)
9747{
9748 return (uchar)(size_t)HEXDSP(hx_valrng_t_reduce_size, this, new_size) != 0;
9749}
9750
9751//--------------------------------------------------------------------------
9752inline bool valrng_t::intersect_with(const valrng_t &r)
9753{
9754 return (uchar)(size_t)HEXDSP(hx_valrng_t_intersect_with, this, &r) != 0;
9755}
9756
9757//--------------------------------------------------------------------------
9758inline bool valrng_t::unite_with(const valrng_t &r)
9759{
9760 return (uchar)(size_t)HEXDSP(hx_valrng_t_unite_with, this, &r) != 0;
9761}
9762
9763//--------------------------------------------------------------------------
9764inline void valrng_t::inverse()
9765{
9766 HEXDSP(hx_valrng_t_inverse, this);
9767}
9768
9769//--------------------------------------------------------------------------
9770inline bool valrng_t::has(uvlr_t v) const
9771{
9772 return (uchar)(size_t)HEXDSP(hx_valrng_t_has, this, v) != 0;
9773}
9774
9775//--------------------------------------------------------------------------
9776inline void valrng_t::print(qstring *vout) const
9777{
9778 HEXDSP(hx_valrng_t_print, this, vout);
9779}
9780
9781//--------------------------------------------------------------------------
9782inline const char *valrng_t::dstr() const
9783{
9784 return (const char *)HEXDSP(hx_valrng_t_dstr, this);
9785}
9786
9787//--------------------------------------------------------------------------
9788inline bool valrng_t::cvt_to_single_value(uvlr_t *v) const
9789{
9790 return (uchar)(size_t)HEXDSP(hx_valrng_t_cvt_to_single_value, this, v) != 0;
9791}
9792
9793//--------------------------------------------------------------------------
9794inline bool valrng_t::cvt_to_cmp(cmpop_t *cmp, uvlr_t *val, bool strict) const
9795{
9796 return (uchar)(size_t)HEXDSP(hx_valrng_t_cvt_to_cmp, this, cmp, val, strict) != 0;
9797}
9798
9799//--------------------------------------------------------------------------
9800inline ea_t get_merror_desc(qstring *out, merror_t code, mba_t *mba)
9801{
9802 ea_t retval;
9803 HEXDSP(hx_get_merror_desc, &retval, out, code, mba);
9804 return retval;
9805}
9806
9807//--------------------------------------------------------------------------
9808inline THREAD_SAFE bool must_mcode_close_block(mcode_t mcode, bool including_calls)
9809{
9810 return (uchar)(size_t)HEXDSP(hx_must_mcode_close_block, mcode, including_calls) != 0;
9811}
9812
9813//--------------------------------------------------------------------------
9814inline THREAD_SAFE bool is_mcode_propagatable(mcode_t mcode)
9815{
9816 return (uchar)(size_t)HEXDSP(hx_is_mcode_propagatable, mcode) != 0;
9817}
9818
9819//--------------------------------------------------------------------------
9820inline THREAD_SAFE mcode_t negate_mcode_relation(mcode_t code)
9821{
9822 return (mcode_t)(size_t)HEXDSP(hx_negate_mcode_relation, code);
9823}
9824
9825//--------------------------------------------------------------------------
9826inline THREAD_SAFE mcode_t swap_mcode_relation(mcode_t code)
9827{
9828 return (mcode_t)(size_t)HEXDSP(hx_swap_mcode_relation, code);
9829}
9830
9831//--------------------------------------------------------------------------
9832inline THREAD_SAFE mcode_t get_signed_mcode(mcode_t code)
9833{
9834 return (mcode_t)(size_t)HEXDSP(hx_get_signed_mcode, code);
9835}
9836
9837//--------------------------------------------------------------------------
9838inline THREAD_SAFE mcode_t get_unsigned_mcode(mcode_t code)
9839{
9840 return (mcode_t)(size_t)HEXDSP(hx_get_unsigned_mcode, code);
9841}
9842
9843//--------------------------------------------------------------------------
9844inline THREAD_SAFE bool mcode_modifies_d(mcode_t mcode)
9845{
9846 return (uchar)(size_t)HEXDSP(hx_mcode_modifies_d, mcode) != 0;
9847}
9848
9849//--------------------------------------------------------------------------
9850inline int operand_locator_t::compare(const operand_locator_t &r) const
9851{
9852 return (int)(size_t)HEXDSP(hx_operand_locator_t_compare, this, &r);
9853}
9854
9855//--------------------------------------------------------------------------
9856inline AS_PRINTF(3, 4) int vd_printer_t::print(int indent, const char *format, ...)
9857{
9858 va_list va;
9859 va_start(va, format);
9860 int retval = (int)(size_t)HEXDSP(hx_vd_printer_t_print, this, indent, format, va);
9861 va_end(va);
9862 return retval;
9863}
9864
9865//--------------------------------------------------------------------------
9866inline AS_PRINTF(3, 4) int file_printer_t::print(int indent, const char *format, ...)
9867{
9868 va_list va;
9869 va_start(va, format);
9870 int retval = (int)(size_t)HEXDSP(hx_file_printer_t_print, this, indent, format, va);
9871 va_end(va);
9872 return retval;
9873}
9874
9875//--------------------------------------------------------------------------
9876inline AS_PRINTF(3, 4) int qstring_printer_t::print(int indent, const char *format, ...)
9877{
9878 va_list va;
9879 va_start(va, format);
9880 int retval = (int)(size_t)HEXDSP(hx_qstring_printer_t_print, this, indent, format, va);
9881 va_end(va);
9882 return retval;
9883}
9884
9885//--------------------------------------------------------------------------
9886inline const char *dstr(const tinfo_t *tif)
9887{
9888 return (const char *)HEXDSP(hx_dstr, tif);
9889}
9890
9891//--------------------------------------------------------------------------
9892inline bool is_type_correct(const type_t *ptr)
9893{
9894 return (uchar)(size_t)HEXDSP(hx_is_type_correct, ptr) != 0;
9895}
9896
9897//--------------------------------------------------------------------------
9898inline bool is_small_udt(const tinfo_t &tif)
9899{
9900 return (uchar)(size_t)HEXDSP(hx_is_small_udt, &tif) != 0;
9901}
9902
9903//--------------------------------------------------------------------------
9904inline bool is_nonbool_type(const tinfo_t &type)
9905{
9906 return (uchar)(size_t)HEXDSP(hx_is_nonbool_type, &type) != 0;
9907}
9908
9909//--------------------------------------------------------------------------
9910inline bool is_bool_type(const tinfo_t &type)
9911{
9912 return (uchar)(size_t)HEXDSP(hx_is_bool_type, &type) != 0;
9913}
9914
9915//--------------------------------------------------------------------------
9916inline int partial_type_num(const tinfo_t &type)
9917{
9918 return (int)(size_t)HEXDSP(hx_partial_type_num, &type);
9919}
9920
9921//--------------------------------------------------------------------------
9922inline tinfo_t get_float_type(int width)
9923{
9924 tinfo_t retval;
9925 HEXDSP(hx_get_float_type, &retval, width);
9926 return retval;
9927}
9928
9929//--------------------------------------------------------------------------
9930inline tinfo_t get_int_type_by_width_and_sign(int srcwidth, type_sign_t sign)
9931{
9932 tinfo_t retval;
9933 HEXDSP(hx_get_int_type_by_width_and_sign, &retval, srcwidth, sign);
9934 return retval;
9935}
9936
9937//--------------------------------------------------------------------------
9938inline tinfo_t get_unk_type(int size)
9939{
9940 tinfo_t retval;
9941 HEXDSP(hx_get_unk_type, &retval, size);
9942 return retval;
9943}
9944
9945//--------------------------------------------------------------------------
9946inline tinfo_t dummy_ptrtype(int ptrsize, bool isfp)
9947{
9948 tinfo_t retval;
9949 HEXDSP(hx_dummy_ptrtype, &retval, ptrsize, isfp);
9950 return retval;
9951}
9952
9953//--------------------------------------------------------------------------
9954inline bool get_member_type(const member_t *mptr, tinfo_t *type)
9955{
9956 return (uchar)(size_t)HEXDSP(hx_get_member_type, mptr, type) != 0;
9957}
9958
9959//--------------------------------------------------------------------------
9960inline tinfo_t make_pointer(const tinfo_t &type)
9961{
9962 tinfo_t retval;
9963 HEXDSP(hx_make_pointer, &retval, &type);
9964 return retval;
9965}
9966
9967//--------------------------------------------------------------------------
9968inline tinfo_t create_typedef(const char *name)
9969{
9970 tinfo_t retval;
9971 HEXDSP(hx_create_typedef, &retval, name);
9972 return retval;
9973}
9974
9975//--------------------------------------------------------------------------
9976inline bool get_type(uval_t id, tinfo_t *tif, type_source_t guess)
9977{
9978 return (uchar)(size_t)HEXDSP(hx_get_type, id, tif, guess) != 0;
9979}
9980
9981//--------------------------------------------------------------------------
9982inline bool set_type(uval_t id, const tinfo_t &tif, type_source_t source, bool force)
9983{
9984 return (uchar)(size_t)HEXDSP(hx_set_type, id, &tif, source, force) != 0;
9985}
9986
9987//--------------------------------------------------------------------------
9988inline const char *vdloc_t::dstr(int width) const
9989{
9990 return (const char *)HEXDSP(hx_vdloc_t_dstr, this, width);
9991}
9992
9993//--------------------------------------------------------------------------
9994inline int vdloc_t::compare(const vdloc_t &r) const
9995{
9996 return (int)(size_t)HEXDSP(hx_vdloc_t_compare, this, &r);
9997}
9998
9999//--------------------------------------------------------------------------
10000inline bool vdloc_t::is_aliasable(const mba_t *mb, int size) const
10001{
10002 return (uchar)(size_t)HEXDSP(hx_vdloc_t_is_aliasable, this, mb, size) != 0;
10003}
10004
10005//--------------------------------------------------------------------------
10006inline void print_vdloc(qstring *vout, const vdloc_t &loc, int nbytes)
10007{
10008 HEXDSP(hx_print_vdloc, vout, &loc, nbytes);
10009}
10010
10011//--------------------------------------------------------------------------
10012inline bool arglocs_overlap(const vdloc_t &loc1, size_t w1, const vdloc_t &loc2, size_t w2)
10013{
10014 return (uchar)(size_t)HEXDSP(hx_arglocs_overlap, &loc1, w1, &loc2, w2) != 0;
10015}
10016
10017//--------------------------------------------------------------------------
10018inline int lvar_locator_t::compare(const lvar_locator_t &r) const
10019{
10020 return (int)(size_t)HEXDSP(hx_lvar_locator_t_compare, this, &r);
10021}
10022
10023//--------------------------------------------------------------------------
10024inline const char *lvar_locator_t::dstr() const
10025{
10026 return (const char *)HEXDSP(hx_lvar_locator_t_dstr, this);
10027}
10028
10029//--------------------------------------------------------------------------
10030inline const char *lvar_t::dstr() const
10031{
10032 return (const char *)HEXDSP(hx_lvar_t_dstr, this);
10033}
10034
10035//--------------------------------------------------------------------------
10036inline bool lvar_t::is_promoted_arg() const
10037{
10038 return (uchar)(size_t)HEXDSP(hx_lvar_t_is_promoted_arg, this) != 0;
10039}
10040
10041//--------------------------------------------------------------------------
10042inline bool lvar_t::accepts_type(const tinfo_t &t, bool may_change_thisarg)
10043{
10044 return (uchar)(size_t)HEXDSP(hx_lvar_t_accepts_type, this, &t, may_change_thisarg) != 0;
10045}
10046
10047//--------------------------------------------------------------------------
10048inline bool lvar_t::set_lvar_type(const tinfo_t &t, bool may_fail)
10049{
10050 return (uchar)(size_t)HEXDSP(hx_lvar_t_set_lvar_type, this, &t, may_fail) != 0;
10051}
10052
10053//--------------------------------------------------------------------------
10054inline bool lvar_t::set_width(int w, int svw_flags)
10055{
10056 return (uchar)(size_t)HEXDSP(hx_lvar_t_set_width, this, w, svw_flags) != 0;
10057}
10058
10059//--------------------------------------------------------------------------
10060inline void lvar_t::append_list(const mba_t *mba, mlist_t *lst, bool pad_if_scattered) const
10061{
10062 HEXDSP(hx_lvar_t_append_list, this, mba, lst, pad_if_scattered);
10063}
10064
10065//--------------------------------------------------------------------------
10066inline int lvars_t::find_stkvar(sval_t spoff, int width)
10067{
10068 return (int)(size_t)HEXDSP(hx_lvars_t_find_stkvar, this, spoff, width);
10069}
10070
10071//--------------------------------------------------------------------------
10073{
10074 return (lvar_t *)HEXDSP(hx_lvars_t_find, this, &ll);
10075}
10076
10077//--------------------------------------------------------------------------
10078inline int lvars_t::find_lvar(const vdloc_t &location, int width, int defblk) const
10079{
10080 return (int)(size_t)HEXDSP(hx_lvars_t_find_lvar, this, &location, width, defblk);
10081}
10082
10083//--------------------------------------------------------------------------
10084inline bool restore_user_lvar_settings(lvar_uservec_t *lvinf, ea_t func_ea)
10085{
10086 return (uchar)(size_t)HEXDSP(hx_restore_user_lvar_settings, lvinf, func_ea) != 0;
10087}
10088
10089//--------------------------------------------------------------------------
10090inline void save_user_lvar_settings(ea_t func_ea, const lvar_uservec_t &lvinf)
10091{
10092 HEXDSP(hx_save_user_lvar_settings, func_ea, &lvinf);
10093}
10094
10095//--------------------------------------------------------------------------
10096inline bool modify_user_lvars(ea_t entry_ea, user_lvar_modifier_t &mlv)
10097{
10098 return (uchar)(size_t)HEXDSP(hx_modify_user_lvars, entry_ea, &mlv) != 0;
10099}
10100
10101//--------------------------------------------------------------------------
10102inline bool modify_user_lvar_info(ea_t func_ea, uint mli_flags, const lvar_saved_info_t &info)
10103{
10104 return (uchar)(size_t)HEXDSP(hx_modify_user_lvar_info, func_ea, mli_flags, &info) != 0;
10105}
10106
10107//--------------------------------------------------------------------------
10108inline bool locate_lvar(lvar_locator_t *out, ea_t func_ea, const char *varname)
10109{
10110 return (uchar)(size_t)HEXDSP(hx_locate_lvar, out, func_ea, varname) != 0;
10111}
10112
10113//--------------------------------------------------------------------------
10114inline bool restore_user_defined_calls(udcall_map_t *udcalls, ea_t func_ea)
10115{
10116 return (uchar)(size_t)HEXDSP(hx_restore_user_defined_calls, udcalls, func_ea) != 0;
10117}
10118
10119//--------------------------------------------------------------------------
10120inline void save_user_defined_calls(ea_t func_ea, const udcall_map_t &udcalls)
10121{
10122 HEXDSP(hx_save_user_defined_calls, func_ea, &udcalls);
10123}
10124
10125//--------------------------------------------------------------------------
10126inline bool parse_user_call(udcall_t *udc, const char *decl, bool silent)
10127{
10128 return (uchar)(size_t)HEXDSP(hx_parse_user_call, udc, decl, silent) != 0;
10129}
10130
10131//--------------------------------------------------------------------------
10133{
10134 return (merror_t)(size_t)HEXDSP(hx_convert_to_user_call, &udc, &cdg);
10135}
10136
10137//--------------------------------------------------------------------------
10138inline bool install_microcode_filter(microcode_filter_t *filter, bool install)
10139{
10140 auto hrdsp = HEXDSP;
10141 return hrdsp != nullptr && (uchar)(size_t)hrdsp(hx_install_microcode_filter, filter, install) != 0;
10142}
10143
10144//--------------------------------------------------------------------------
10146{
10147 HEXDSP(hx_udc_filter_t_cleanup, this);
10148}
10149
10150//--------------------------------------------------------------------------
10151inline bool udc_filter_t::init(const char *decl)
10152{
10153 return (uchar)(size_t)HEXDSP(hx_udc_filter_t_init, this, decl) != 0;
10154}
10155
10156//--------------------------------------------------------------------------
10158{
10159 return (merror_t)(size_t)HEXDSP(hx_udc_filter_t_apply, this, &cdg);
10160}
10161
10162//--------------------------------------------------------------------------
10163inline bitset_t::bitset_t(const bitset_t &m)
10164{
10165 HEXDSP(hx_bitset_t_bitset_t, this, &m);
10166}
10167
10168//--------------------------------------------------------------------------
10169inline bitset_t &bitset_t::copy(const bitset_t &m)
10170{
10171 return *(bitset_t *)HEXDSP(hx_bitset_t_copy, this, &m);
10172}
10173
10174//--------------------------------------------------------------------------
10175inline bool bitset_t::add(int bit)
10176{
10177 return (uchar)(size_t)HEXDSP(hx_bitset_t_add, this, bit) != 0;
10178}
10179
10180//--------------------------------------------------------------------------
10181inline bool bitset_t::add(int bit, int width)
10182{
10183 return (uchar)(size_t)HEXDSP(hx_bitset_t_add_, this, bit, width) != 0;
10184}
10185
10186//--------------------------------------------------------------------------
10187inline bool bitset_t::add(const bitset_t &ml)
10188{
10189 return (uchar)(size_t)HEXDSP(hx_bitset_t_add__, this, &ml) != 0;
10190}
10191
10192//--------------------------------------------------------------------------
10193inline bool bitset_t::sub(int bit)
10194{
10195 return (uchar)(size_t)HEXDSP(hx_bitset_t_sub, this, bit) != 0;
10196}
10197
10198//--------------------------------------------------------------------------
10199inline bool bitset_t::sub(int bit, int width)
10200{
10201 return (uchar)(size_t)HEXDSP(hx_bitset_t_sub_, this, bit, width) != 0;
10202}
10203
10204//--------------------------------------------------------------------------
10205inline bool bitset_t::sub(const bitset_t &ml)
10206{
10207 return (uchar)(size_t)HEXDSP(hx_bitset_t_sub__, this, &ml) != 0;
10208}
10209
10210//--------------------------------------------------------------------------
10211inline bool bitset_t::cut_at(int maxbit)
10212{
10213 return (uchar)(size_t)HEXDSP(hx_bitset_t_cut_at, this, maxbit) != 0;
10214}
10215
10216//--------------------------------------------------------------------------
10217inline void bitset_t::shift_down(int shift)
10218{
10219 HEXDSP(hx_bitset_t_shift_down, this, shift);
10220}
10221
10222//--------------------------------------------------------------------------
10223inline bool bitset_t::has(int bit) const
10224{
10225 return (uchar)(size_t)HEXDSP(hx_bitset_t_has, this, bit) != 0;
10226}
10227
10228//--------------------------------------------------------------------------
10229inline bool bitset_t::has_all(int bit, int width) const
10230{
10231 return (uchar)(size_t)HEXDSP(hx_bitset_t_has_all, this, bit, width) != 0;
10232}
10233
10234//--------------------------------------------------------------------------
10235inline bool bitset_t::has_any(int bit, int width) const
10236{
10237 return (uchar)(size_t)HEXDSP(hx_bitset_t_has_any, this, bit, width) != 0;
10238}
10239
10240//--------------------------------------------------------------------------
10241inline const char *bitset_t::dstr() const
10242{
10243 return (const char *)HEXDSP(hx_bitset_t_dstr, this);
10244}
10245
10246//--------------------------------------------------------------------------
10247inline bool bitset_t::empty() const
10248{
10249 return (uchar)(size_t)HEXDSP(hx_bitset_t_empty, this) != 0;
10250}
10251
10252//--------------------------------------------------------------------------
10253inline int bitset_t::count() const
10254{
10255 return (int)(size_t)HEXDSP(hx_bitset_t_count, this);
10256}
10257
10258//--------------------------------------------------------------------------
10259inline int bitset_t::count(int bit) const
10260{
10261 return (int)(size_t)HEXDSP(hx_bitset_t_count_, this, bit);
10262}
10263
10264//--------------------------------------------------------------------------
10265inline int bitset_t::last() const
10266{
10267 return (int)(size_t)HEXDSP(hx_bitset_t_last, this);
10268}
10269
10270//--------------------------------------------------------------------------
10271inline void bitset_t::fill_with_ones(int maxbit)
10272{
10273 HEXDSP(hx_bitset_t_fill_with_ones, this, maxbit);
10274}
10275
10276//--------------------------------------------------------------------------
10277inline bool bitset_t::fill_gaps(int total_nbits)
10278{
10279 return (uchar)(size_t)HEXDSP(hx_bitset_t_fill_gaps, this, total_nbits) != 0;
10280}
10281
10282//--------------------------------------------------------------------------
10283inline bool bitset_t::has_common(const bitset_t &ml) const
10284{
10285 return (uchar)(size_t)HEXDSP(hx_bitset_t_has_common, this, &ml) != 0;
10286}
10287
10288//--------------------------------------------------------------------------
10289inline bool bitset_t::intersect(const bitset_t &ml)
10290{
10291 return (uchar)(size_t)HEXDSP(hx_bitset_t_intersect, this, &ml) != 0;
10292}
10293
10294//--------------------------------------------------------------------------
10295inline bool bitset_t::is_subset_of(const bitset_t &ml) const
10296{
10297 return (uchar)(size_t)HEXDSP(hx_bitset_t_is_subset_of, this, &ml) != 0;
10298}
10299
10300//--------------------------------------------------------------------------
10301inline int bitset_t::compare(const bitset_t &r) const
10302{
10303 return (int)(size_t)HEXDSP(hx_bitset_t_compare, this, &r);
10304}
10305
10306//--------------------------------------------------------------------------
10307inline int bitset_t::goup(int reg) const
10308{
10309 return (int)(size_t)HEXDSP(hx_bitset_t_goup, this, reg);
10310}
10311
10312//--------------------------------------------------------------------------
10313inline const char *ivl_t::dstr() const
10314{
10315 return (const char *)HEXDSP(hx_ivl_t_dstr, this);
10316}
10317
10318//--------------------------------------------------------------------------
10319inline int ivl_t::compare(const ivl_t &r) const
10320{
10321 return (int)(size_t)HEXDSP(hx_ivl_t_compare, this, &r);
10322}
10323
10324//--------------------------------------------------------------------------
10325inline bool ivlset_t::add(const ivl_t &ivl)
10326{
10327 return (uchar)(size_t)HEXDSP(hx_ivlset_t_add, this, &ivl) != 0;
10328}
10329
10330//--------------------------------------------------------------------------
10331inline bool ivlset_t::add(const ivlset_t &ivs)
10332{
10333 return (uchar)(size_t)HEXDSP(hx_ivlset_t_add_, this, &ivs) != 0;
10334}
10335
10336//--------------------------------------------------------------------------
10337inline bool ivlset_t::addmasked(const ivlset_t &ivs, const ivl_t &mask)
10338{
10339 return (uchar)(size_t)HEXDSP(hx_ivlset_t_addmasked, this, &ivs, &mask) != 0;
10340}
10341
10342//--------------------------------------------------------------------------
10343inline bool ivlset_t::sub(const ivl_t &ivl)
10344{
10345 return (uchar)(size_t)HEXDSP(hx_ivlset_t_sub, this, &ivl) != 0;
10346}
10347
10348//--------------------------------------------------------------------------
10349inline bool ivlset_t::sub(const ivlset_t &ivs)
10350{
10351 return (uchar)(size_t)HEXDSP(hx_ivlset_t_sub_, this, &ivs) != 0;
10352}
10353
10354//--------------------------------------------------------------------------
10355inline bool ivlset_t::has_common(const ivl_t &ivl, bool strict) const
10356{
10357 return (uchar)(size_t)HEXDSP(hx_ivlset_t_has_common, this, &ivl, strict) != 0;
10358}
10359
10360//--------------------------------------------------------------------------
10361inline void ivlset_t::print(qstring *vout) const
10362{
10363 HEXDSP(hx_ivlset_t_print, this, vout);
10364}
10365
10366//--------------------------------------------------------------------------
10367inline const char *ivlset_t::dstr() const
10368{
10369 return (const char *)HEXDSP(hx_ivlset_t_dstr, this);
10370}
10371
10372//--------------------------------------------------------------------------
10373inline asize_t ivlset_t::count() const
10374{
10375 asize_t retval;
10376 HEXDSP(hx_ivlset_t_count, &retval, this);
10377 return retval;
10378}
10379
10380//--------------------------------------------------------------------------
10381inline bool ivlset_t::has_common(const ivlset_t &ivs) const
10382{
10383 return (uchar)(size_t)HEXDSP(hx_ivlset_t_has_common_, this, &ivs) != 0;
10384}
10385
10386//--------------------------------------------------------------------------
10387inline bool ivlset_t::contains(uval_t off) const
10388{
10389 return (uchar)(size_t)HEXDSP(hx_ivlset_t_contains, this, off) != 0;
10390}
10391
10392//--------------------------------------------------------------------------
10393inline bool ivlset_t::includes(const ivlset_t &ivs) const
10394{
10395 return (uchar)(size_t)HEXDSP(hx_ivlset_t_includes, this, &ivs) != 0;
10396}
10397
10398//--------------------------------------------------------------------------
10399inline bool ivlset_t::intersect(const ivlset_t &ivs)
10400{
10401 return (uchar)(size_t)HEXDSP(hx_ivlset_t_intersect, this, &ivs) != 0;
10402}
10403
10404//--------------------------------------------------------------------------
10405inline int ivlset_t::compare(const ivlset_t &r) const
10406{
10407 return (int)(size_t)HEXDSP(hx_ivlset_t_compare, this, &r);
10408}
10409
10410//--------------------------------------------------------------------------
10411inline void rlist_t::print(qstring *vout) const
10412{
10413 HEXDSP(hx_rlist_t_print, this, vout);
10414}
10415
10416//--------------------------------------------------------------------------
10417inline const char *rlist_t::dstr() const
10418{
10419 return (const char *)HEXDSP(hx_rlist_t_dstr, this);
10420}
10421
10422//--------------------------------------------------------------------------
10423inline bool mlist_t::addmem(ea_t ea, asize_t size)
10424{
10425 return (uchar)(size_t)HEXDSP(hx_mlist_t_addmem, this, ea, size) != 0;
10426}
10427
10428//--------------------------------------------------------------------------
10429inline void mlist_t::print(qstring *vout) const
10430{
10431 HEXDSP(hx_mlist_t_print, this, vout);
10432}
10433
10434//--------------------------------------------------------------------------
10435inline const char *mlist_t::dstr() const
10436{
10437 return (const char *)HEXDSP(hx_mlist_t_dstr, this);
10438}
10439
10440//--------------------------------------------------------------------------
10441inline int mlist_t::compare(const mlist_t &r) const
10442{
10443 return (int)(size_t)HEXDSP(hx_mlist_t_compare, this, &r);
10444}
10445
10446//--------------------------------------------------------------------------
10447inline const mlist_t &get_temp_regs()
10448{
10449 return *(const mlist_t *)HEXDSP(hx_get_temp_regs);
10450}
10451
10452//--------------------------------------------------------------------------
10453inline bool is_kreg(mreg_t r)
10454{
10455 return (uchar)(size_t)HEXDSP(hx_is_kreg, r) != 0;
10456}
10457
10458//--------------------------------------------------------------------------
10459inline mreg_t reg2mreg(int reg)
10460{
10461 return (mreg_t)(size_t)HEXDSP(hx_reg2mreg, reg);
10462}
10463
10464//--------------------------------------------------------------------------
10465inline int mreg2reg(mreg_t reg, int width)
10466{
10467 return (int)(size_t)HEXDSP(hx_mreg2reg, reg, width);
10468}
10469
10470//--------------------------------------------------------------------------
10471inline int get_mreg_name(qstring *out, mreg_t reg, int width, void *ud)
10472{
10473 return (int)(size_t)HEXDSP(hx_get_mreg_name, out, reg, width, ud);
10474}
10475
10476//--------------------------------------------------------------------------
10478{
10479 HEXDSP(hx_install_optinsn_handler, opt);
10480}
10481
10482//--------------------------------------------------------------------------
10484{
10485 auto hrdsp = HEXDSP;
10486 return hrdsp != nullptr && (uchar)(size_t)hrdsp(hx_remove_optinsn_handler, opt) != 0;
10487}
10488
10489//--------------------------------------------------------------------------
10491{
10492 HEXDSP(hx_install_optblock_handler, opt);
10493}
10494
10495//--------------------------------------------------------------------------
10497{
10498 auto hrdsp = HEXDSP;
10499 return hrdsp != nullptr && (uchar)(size_t)hrdsp(hx_remove_optblock_handler, opt) != 0;
10500}
10501
10502//--------------------------------------------------------------------------
10503inline int lvar_ref_t::compare(const lvar_ref_t &r) const
10504{
10505 return (int)(size_t)HEXDSP(hx_lvar_ref_t_compare, this, &r);
10506}
10507
10508//--------------------------------------------------------------------------
10510{
10511 return *(lvar_t *)HEXDSP(hx_lvar_ref_t_var, this);
10512}
10513
10514//--------------------------------------------------------------------------
10515inline int stkvar_ref_t::compare(const stkvar_ref_t &r) const
10516{
10517 return (int)(size_t)HEXDSP(hx_stkvar_ref_t_compare, this, &r);
10518}
10519
10520//--------------------------------------------------------------------------
10521inline member_t *stkvar_ref_t::get_stkvar(uval_t *p_off) const
10522{
10523 return (member_t *)HEXDSP(hx_stkvar_ref_t_get_stkvar, this, p_off);
10524}
10525
10526//--------------------------------------------------------------------------
10527inline void fnumber_t::print(qstring *vout) const
10528{
10529 HEXDSP(hx_fnumber_t_print, this, vout);
10530}
10531
10532//--------------------------------------------------------------------------
10533inline const char *fnumber_t::dstr() const
10534{
10535 return (const char *)HEXDSP(hx_fnumber_t_dstr, this);
10536}
10537
10538//--------------------------------------------------------------------------
10539inline void mop_t::copy(const mop_t &rop)
10540{
10541 HEXDSP(hx_mop_t_copy, this, &rop);
10542}
10543
10544//--------------------------------------------------------------------------
10545inline mop_t &mop_t::assign(const mop_t &rop)
10546{
10547 return *(mop_t *)HEXDSP(hx_mop_t_assign, this, &rop);
10548}
10549
10550//--------------------------------------------------------------------------
10551inline void mop_t::swap(mop_t &rop)
10552{
10553 HEXDSP(hx_mop_t_swap, this, &rop);
10554}
10555
10556//--------------------------------------------------------------------------
10557inline void mop_t::erase()
10558{
10559 HEXDSP(hx_mop_t_erase, this);
10560}
10561
10562//--------------------------------------------------------------------------
10563inline void mop_t::print(qstring *vout, int shins_flags) const
10564{
10565 HEXDSP(hx_mop_t_print, this, vout, shins_flags);
10566}
10567
10568//--------------------------------------------------------------------------
10569inline const char *mop_t::dstr() const
10570{
10571 return (const char *)HEXDSP(hx_mop_t_dstr, this);
10572}
10573
10574//--------------------------------------------------------------------------
10575inline bool mop_t::create_from_mlist(mba_t *mba, const mlist_t &lst, sval_t fullsize)
10576{
10577 return (uchar)(size_t)HEXDSP(hx_mop_t_create_from_mlist, this, mba, &lst, fullsize) != 0;
10578}
10579
10580//--------------------------------------------------------------------------
10581inline bool mop_t::create_from_ivlset(mba_t *mba, const ivlset_t &ivs, sval_t fullsize)
10582{
10583 return (uchar)(size_t)HEXDSP(hx_mop_t_create_from_ivlset, this, mba, &ivs, fullsize) != 0;
10584}
10585
10586//--------------------------------------------------------------------------
10587inline void mop_t::create_from_vdloc(mba_t *mba, const vdloc_t &loc, int _size)
10588{
10589 HEXDSP(hx_mop_t_create_from_vdloc, this, mba, &loc, _size);
10590}
10591
10592//--------------------------------------------------------------------------
10593inline void mop_t::create_from_scattered_vdloc(mba_t *mba, const char *name, tinfo_t type, const vdloc_t &loc)
10594{
10595 HEXDSP(hx_mop_t_create_from_scattered_vdloc, this, mba, name, &type, &loc);
10596}
10597
10598//--------------------------------------------------------------------------
10600{
10601 HEXDSP(hx_mop_t_create_from_insn, this, m);
10602}
10603
10604//--------------------------------------------------------------------------
10605inline void mop_t::make_number(uint64 _value, int _size, ea_t _ea, int opnum)
10606{
10607 HEXDSP(hx_mop_t_make_number, this, _value, _size, _ea, opnum);
10608}
10609
10610//--------------------------------------------------------------------------
10611inline bool mop_t::make_fpnum(const void *bytes, size_t _size)
10612{
10613 return (uchar)(size_t)HEXDSP(hx_mop_t_make_fpnum, this, bytes, _size) != 0;
10614}
10615
10616//--------------------------------------------------------------------------
10617inline void mop_t::_make_gvar(ea_t ea)
10618{
10619 HEXDSP(hx_mop_t__make_gvar, this, ea);
10620}
10621
10622//--------------------------------------------------------------------------
10623inline void mop_t::make_gvar(ea_t ea)
10624{
10625 HEXDSP(hx_mop_t_make_gvar, this, ea);
10626}
10627
10628//--------------------------------------------------------------------------
10629inline void mop_t::make_reg_pair(int loreg, int hireg, int halfsize)
10630{
10631 HEXDSP(hx_mop_t_make_reg_pair, this, loreg, hireg, halfsize);
10632}
10633
10634//--------------------------------------------------------------------------
10635inline void mop_t::make_helper(const char *name)
10636{
10637 HEXDSP(hx_mop_t_make_helper, this, name);
10638}
10639
10640//--------------------------------------------------------------------------
10642{
10643 return (uchar)(size_t)HEXDSP(hx_mop_t_is_bit_reg, reg) != 0;
10644}
10645
10646//--------------------------------------------------------------------------
10648{
10649 return (uchar)(size_t)HEXDSP(hx_mop_t_may_use_aliased_memory, this) != 0;
10650}
10651
10652//--------------------------------------------------------------------------
10653inline bool mop_t::is01() const
10654{
10655 return (uchar)(size_t)HEXDSP(hx_mop_t_is01, this) != 0;
10656}
10657
10658//--------------------------------------------------------------------------
10659inline bool mop_t::is_sign_extended_from(int nbytes) const
10660{
10661 return (uchar)(size_t)HEXDSP(hx_mop_t_is_sign_extended_from, this, nbytes) != 0;
10662}
10663
10664//--------------------------------------------------------------------------
10665inline bool mop_t::is_zero_extended_from(int nbytes) const
10666{
10667 return (uchar)(size_t)HEXDSP(hx_mop_t_is_zero_extended_from, this, nbytes) != 0;
10668}
10669
10670//--------------------------------------------------------------------------
10671inline bool mop_t::equal_mops(const mop_t &rop, int eqflags) const
10672{
10673 return (uchar)(size_t)HEXDSP(hx_mop_t_equal_mops, this, &rop, eqflags) != 0;
10674}
10675
10676//--------------------------------------------------------------------------
10677inline int mop_t::lexcompare(const mop_t &rop) const
10678{
10679 return (int)(size_t)HEXDSP(hx_mop_t_lexcompare, this, &rop);
10680}
10681
10682//--------------------------------------------------------------------------
10683inline int mop_t::for_all_ops(mop_visitor_t &mv, const tinfo_t *type, bool is_target)
10684{
10685 return (int)(size_t)HEXDSP(hx_mop_t_for_all_ops, this, &mv, type, is_target);
10686}
10687
10688//--------------------------------------------------------------------------
10690{
10691 return (int)(size_t)HEXDSP(hx_mop_t_for_all_scattered_submops, this, &sv);
10692}
10693
10694//--------------------------------------------------------------------------
10695inline bool mop_t::is_constant(uint64 *out, bool is_signed) const
10696{
10697 return (uchar)(size_t)HEXDSP(hx_mop_t_is_constant, this, out, is_signed) != 0;
10698}
10699
10700//--------------------------------------------------------------------------
10701inline bool mop_t::get_stkoff(sval_t *p_off) const
10702{
10703 return (uchar)(size_t)HEXDSP(hx_mop_t_get_stkoff, this, p_off) != 0;
10704}
10705
10706//--------------------------------------------------------------------------
10707inline bool mop_t::make_low_half(int width)
10708{
10709 return (uchar)(size_t)HEXDSP(hx_mop_t_make_low_half, this, width) != 0;
10710}
10711
10712//--------------------------------------------------------------------------
10713inline bool mop_t::make_high_half(int width)
10714{
10715 return (uchar)(size_t)HEXDSP(hx_mop_t_make_high_half, this, width) != 0;
10716}
10717
10718//--------------------------------------------------------------------------
10719inline bool mop_t::make_first_half(int width)
10720{
10721 return (uchar)(size_t)HEXDSP(hx_mop_t_make_first_half, this, width) != 0;
10722}
10723
10724//--------------------------------------------------------------------------
10725inline bool mop_t::make_second_half(int width)
10726{
10727 return (uchar)(size_t)HEXDSP(hx_mop_t_make_second_half, this, width) != 0;
10728}
10729
10730//--------------------------------------------------------------------------
10731inline bool mop_t::shift_mop(int offset)
10732{
10733 return (uchar)(size_t)HEXDSP(hx_mop_t_shift_mop, this, offset) != 0;
10734}
10735
10736//--------------------------------------------------------------------------
10737inline bool mop_t::change_size(int nsize, side_effect_t sideff)
10738{
10739 return (uchar)(size_t)HEXDSP(hx_mop_t_change_size, this, nsize, sideff) != 0;
10740}
10741
10742//--------------------------------------------------------------------------
10743inline bool mop_t::preserve_side_effects(mblock_t *blk, minsn_t *top, bool *moved_calls)
10744{
10745 return (uchar)(size_t)HEXDSP(hx_mop_t_preserve_side_effects, this, blk, top, moved_calls) != 0;
10746}
10747
10748//--------------------------------------------------------------------------
10749inline void mop_t::apply_ld_mcode(mcode_t mcode, ea_t ea, int newsize)
10750{
10751 HEXDSP(hx_mop_t_apply_ld_mcode, this, mcode, ea, newsize);
10752}
10753
10754//--------------------------------------------------------------------------
10755inline void mcallarg_t::print(qstring *vout, int shins_flags) const
10756{
10757 HEXDSP(hx_mcallarg_t_print, this, vout, shins_flags);
10758}
10759
10760//--------------------------------------------------------------------------
10761inline const char *mcallarg_t::dstr() const
10762{
10763 return (const char *)HEXDSP(hx_mcallarg_t_dstr, this);
10764}
10765
10766//--------------------------------------------------------------------------
10767inline void mcallarg_t::set_regarg(mreg_t mr, int sz, const tinfo_t &tif)
10768{
10769 HEXDSP(hx_mcallarg_t_set_regarg, this, mr, sz, &tif);
10770}
10771
10772//--------------------------------------------------------------------------
10773inline int mcallinfo_t::lexcompare(const mcallinfo_t &f) const
10774{
10775 return (int)(size_t)HEXDSP(hx_mcallinfo_t_lexcompare, this, &f);
10776}
10777
10778//--------------------------------------------------------------------------
10779inline bool mcallinfo_t::set_type(const tinfo_t &type)
10780{
10781 return (uchar)(size_t)HEXDSP(hx_mcallinfo_t_set_type, this, &type) != 0;
10782}
10783
10784//--------------------------------------------------------------------------
10785inline tinfo_t mcallinfo_t::get_type() const
10786{
10787 tinfo_t retval;
10788 HEXDSP(hx_mcallinfo_t_get_type, &retval, this);
10789 return retval;
10790}
10791
10792//--------------------------------------------------------------------------
10793inline void mcallinfo_t::print(qstring *vout, int size, int shins_flags) const
10794{
10795 HEXDSP(hx_mcallinfo_t_print, this, vout, size, shins_flags);
10796}
10797
10798//--------------------------------------------------------------------------
10799inline const char *mcallinfo_t::dstr() const
10800{
10801 return (const char *)HEXDSP(hx_mcallinfo_t_dstr, this);
10802}
10803
10804//--------------------------------------------------------------------------
10805inline int mcases_t::compare(const mcases_t &r) const
10806{
10807 return (int)(size_t)HEXDSP(hx_mcases_t_compare, this, &r);
10808}
10809
10810//--------------------------------------------------------------------------
10811inline void mcases_t::print(qstring *vout) const
10812{
10813 HEXDSP(hx_mcases_t_print, this, vout);
10814}
10815
10816//--------------------------------------------------------------------------
10817inline const char *mcases_t::dstr() const
10818{
10819 return (const char *)HEXDSP(hx_mcases_t_dstr, this);
10820}
10821
10822//--------------------------------------------------------------------------
10823inline bool vivl_t::extend_to_cover(const vivl_t &r)
10824{
10825 return (uchar)(size_t)HEXDSP(hx_vivl_t_extend_to_cover, this, &r) != 0;
10826}
10827
10828//--------------------------------------------------------------------------
10829inline uval_t vivl_t::intersect(const vivl_t &r)
10830{
10831 uval_t retval;
10832 HEXDSP(hx_vivl_t_intersect, &retval, this, &r);
10833 return retval;
10834}
10835
10836//--------------------------------------------------------------------------
10837inline void vivl_t::print(qstring *vout) const
10838{
10839 HEXDSP(hx_vivl_t_print, this, vout);
10840}
10841
10842//--------------------------------------------------------------------------
10843inline const char *vivl_t::dstr() const
10844{
10845 return (const char *)HEXDSP(hx_vivl_t_dstr, this);
10846}
10847
10848//--------------------------------------------------------------------------
10849inline void chain_t::print(qstring *vout) const
10850{
10851 HEXDSP(hx_chain_t_print, this, vout);
10852}
10853
10854//--------------------------------------------------------------------------
10855inline const char *chain_t::dstr() const
10856{
10857 return (const char *)HEXDSP(hx_chain_t_dstr, this);
10858}
10859
10860//--------------------------------------------------------------------------
10861inline void chain_t::append_list(const mba_t *mba, mlist_t *list) const
10862{
10863 HEXDSP(hx_chain_t_append_list, this, mba, list);
10864}
10865
10866//--------------------------------------------------------------------------
10867inline const chain_t *block_chains_t::get_chain(const chain_t &ch) const
10868{
10869 return (const chain_t *)HEXDSP(hx_block_chains_t_get_chain, this, &ch);
10870}
10871
10872//--------------------------------------------------------------------------
10873inline void block_chains_t::print(qstring *vout) const
10874{
10875 HEXDSP(hx_block_chains_t_print, this, vout);
10876}
10877
10878//--------------------------------------------------------------------------
10879inline const char *block_chains_t::dstr() const
10880{
10881 return (const char *)HEXDSP(hx_block_chains_t_dstr, this);
10882}
10883
10884//--------------------------------------------------------------------------
10886{
10887 return (int)(size_t)HEXDSP(hx_graph_chains_t_for_all_chains, this, &cv, gca_flags);
10888}
10889
10890//--------------------------------------------------------------------------
10892{
10893 HEXDSP(hx_graph_chains_t_release, this);
10894}
10895
10896//--------------------------------------------------------------------------
10897inline void minsn_t::init(ea_t _ea)
10898{
10899 HEXDSP(hx_minsn_t_init, this, _ea);
10900}
10901
10902//--------------------------------------------------------------------------
10903inline void minsn_t::copy(const minsn_t &m)
10904{
10905 HEXDSP(hx_minsn_t_copy, this, &m);
10906}
10907
10908//--------------------------------------------------------------------------
10909inline void minsn_t::set_combined()
10910{
10911 HEXDSP(hx_minsn_t_set_combined, this);
10912}
10913
10914//--------------------------------------------------------------------------
10915inline void minsn_t::swap(minsn_t &m)
10916{
10917 HEXDSP(hx_minsn_t_swap, this, &m);
10918}
10919
10920//--------------------------------------------------------------------------
10921inline void minsn_t::print(qstring *vout, int shins_flags) const
10922{
10923 HEXDSP(hx_minsn_t_print, this, vout, shins_flags);
10924}
10925
10926//--------------------------------------------------------------------------
10927inline const char *minsn_t::dstr() const
10928{
10929 return (const char *)HEXDSP(hx_minsn_t_dstr, this);
10930}
10931
10932//--------------------------------------------------------------------------
10933inline void minsn_t::setaddr(ea_t new_ea)
10934{
10935 HEXDSP(hx_minsn_t_setaddr, this, new_ea);
10936}
10937
10938//--------------------------------------------------------------------------
10939inline int minsn_t::optimize_subtree(mblock_t *blk, minsn_t *top, minsn_t *parent, ea_t *converted_call, int optflags)
10940{
10941 return (int)(size_t)HEXDSP(hx_minsn_t_optimize_subtree, this, blk, top, parent, converted_call, optflags);
10942}
10943
10944//--------------------------------------------------------------------------
10946{
10947 return (int)(size_t)HEXDSP(hx_minsn_t_for_all_ops, this, &mv);
10948}
10949
10950//--------------------------------------------------------------------------
10952{
10953 return (int)(size_t)HEXDSP(hx_minsn_t_for_all_insns, this, &mv);
10954}
10955
10956//--------------------------------------------------------------------------
10958{
10959 HEXDSP(hx_minsn_t__make_nop, this);
10960}
10961
10962//--------------------------------------------------------------------------
10963inline bool minsn_t::equal_insns(const minsn_t &m, int eqflags) const
10964{
10965 return (uchar)(size_t)HEXDSP(hx_minsn_t_equal_insns, this, &m, eqflags) != 0;
10966}
10967
10968//--------------------------------------------------------------------------
10969inline int minsn_t::lexcompare(const minsn_t &ri) const
10970{
10971 return (int)(size_t)HEXDSP(hx_minsn_t_lexcompare, this, &ri);
10972}
10973
10974//--------------------------------------------------------------------------
10975inline bool minsn_t::is_noret_call(int flags)
10976{
10977 return (uchar)(size_t)HEXDSP(hx_minsn_t_is_noret_call, this, flags) != 0;
10978}
10979
10980//--------------------------------------------------------------------------
10981inline bool minsn_t::is_helper(const char *name) const
10982{
10983 return (uchar)(size_t)HEXDSP(hx_minsn_t_is_helper, this, name) != 0;
10984}
10985
10986//--------------------------------------------------------------------------
10987inline minsn_t *minsn_t::find_call(bool with_helpers) const
10988{
10989 return (minsn_t *)HEXDSP(hx_minsn_t_find_call, this, with_helpers);
10990}
10991
10992//--------------------------------------------------------------------------
10993inline bool minsn_t::has_side_effects(bool include_ldx_and_divs) const
10994{
10995 return (uchar)(size_t)HEXDSP(hx_minsn_t_has_side_effects, this, include_ldx_and_divs) != 0;
10996}
10997
10998//--------------------------------------------------------------------------
10999inline minsn_t *minsn_t::find_opcode(mcode_t mcode)
11000{
11001 return (minsn_t *)HEXDSP(hx_minsn_t_find_opcode, this, mcode);
11002}
11003
11004//--------------------------------------------------------------------------
11005inline const minsn_t *minsn_t::find_ins_op(const mop_t **other, mcode_t op) const
11006{
11007 return (const minsn_t *)HEXDSP(hx_minsn_t_find_ins_op, this, other, op);
11008}
11009
11010//--------------------------------------------------------------------------
11011inline const mop_t *minsn_t::find_num_op(const mop_t **other) const
11012{
11013 return (const mop_t *)HEXDSP(hx_minsn_t_find_num_op, this, other);
11014}
11015
11016//--------------------------------------------------------------------------
11017inline bool minsn_t::modifies_d() const
11018{
11019 return (uchar)(size_t)HEXDSP(hx_minsn_t_modifies_d, this) != 0;
11020}
11021
11022//--------------------------------------------------------------------------
11023inline bool minsn_t::is_between(const minsn_t *m1, const minsn_t *m2) const
11024{
11025 return (uchar)(size_t)HEXDSP(hx_minsn_t_is_between, this, m1, m2) != 0;
11026}
11027
11028//--------------------------------------------------------------------------
11030{
11031 return (uchar)(size_t)HEXDSP(hx_minsn_t_may_use_aliased_memory, this) != 0;
11032}
11033
11034//--------------------------------------------------------------------------
11035inline int minsn_t::serialize(bytevec_t *b) const
11036{
11037 return (int)(size_t)HEXDSP(hx_minsn_t_serialize, this, b);
11038}
11039
11040//--------------------------------------------------------------------------
11041inline bool minsn_t::deserialize(const uchar *bytes, size_t nbytes, int format_version)
11042{
11043 return (uchar)(size_t)HEXDSP(hx_minsn_t_deserialize, this, bytes, nbytes, format_version) != 0;
11044}
11045
11046//--------------------------------------------------------------------------
11047inline const minsn_t *getf_reginsn(const minsn_t *ins)
11048{
11049 return (const minsn_t *)HEXDSP(hx_getf_reginsn, ins);
11050}
11051
11052//--------------------------------------------------------------------------
11053inline const minsn_t *getb_reginsn(const minsn_t *ins)
11054{
11055 return (const minsn_t *)HEXDSP(hx_getb_reginsn, ins);
11056}
11057
11058//--------------------------------------------------------------------------
11059inline void mblock_t::init()
11060{
11061 HEXDSP(hx_mblock_t_init, this);
11062}
11063
11064//--------------------------------------------------------------------------
11065inline void mblock_t::print(vd_printer_t &vp) const
11066{
11067 HEXDSP(hx_mblock_t_print, this, &vp);
11068}
11069
11070//--------------------------------------------------------------------------
11071inline void mblock_t::dump() const
11072{
11073 HEXDSP(hx_mblock_t_dump, this);
11074}
11075
11076//--------------------------------------------------------------------------
11077inline AS_PRINTF(2, 0) void mblock_t::vdump_block(const char *title, va_list va) const
11078{
11079 HEXDSP(hx_mblock_t_vdump_block, this, title, va);
11080}
11081
11082//--------------------------------------------------------------------------
11084{
11085 return (minsn_t *)HEXDSP(hx_mblock_t_insert_into_block, this, nm, om);
11086}
11087
11088//--------------------------------------------------------------------------
11090{
11091 return (minsn_t *)HEXDSP(hx_mblock_t_remove_from_block, this, m);
11092}
11093
11094//--------------------------------------------------------------------------
11096{
11097 return (int)(size_t)HEXDSP(hx_mblock_t_for_all_insns, this, &mv);
11098}
11099
11100//--------------------------------------------------------------------------
11102{
11103 return (int)(size_t)HEXDSP(hx_mblock_t_for_all_ops, this, &mv);
11104}
11105
11106//--------------------------------------------------------------------------
11108{
11109 return (int)(size_t)HEXDSP(hx_mblock_t_for_all_uses, this, list, i1, i2, &mmv);
11110}
11111
11112//--------------------------------------------------------------------------
11113inline int mblock_t::optimize_insn(minsn_t *m, int optflags)
11114{
11115 return (int)(size_t)HEXDSP(hx_mblock_t_optimize_insn, this, m, optflags);
11116}
11117
11118//--------------------------------------------------------------------------
11120{
11121 return (int)(size_t)HEXDSP(hx_mblock_t_optimize_block, this);
11122}
11123
11124//--------------------------------------------------------------------------
11125inline int mblock_t::build_lists(bool kill_deads)
11126{
11127 return (int)(size_t)HEXDSP(hx_mblock_t_build_lists, this, kill_deads);
11128}
11129
11130//--------------------------------------------------------------------------
11132{
11133 return (int)(size_t)HEXDSP(hx_mblock_t_optimize_useless_jump, this);
11134}
11135
11136//--------------------------------------------------------------------------
11137inline void mblock_t::append_use_list(mlist_t *list, const mop_t &op, maymust_t maymust, bitrange_t mask) const
11138{
11139 HEXDSP(hx_mblock_t_append_use_list, this, list, &op, maymust, &mask);
11140}
11141
11142//--------------------------------------------------------------------------
11143inline void mblock_t::append_def_list(mlist_t *list, const mop_t &op, maymust_t maymust) const
11144{
11145 HEXDSP(hx_mblock_t_append_def_list, this, list, &op, maymust);
11146}
11147
11148//--------------------------------------------------------------------------
11149inline mlist_t mblock_t::build_use_list(const minsn_t &ins, maymust_t maymust) const
11150{
11151 mlist_t retval;
11152 HEXDSP(hx_mblock_t_build_use_list, &retval, this, &ins, maymust);
11153 return retval;
11154}
11155
11156//--------------------------------------------------------------------------
11157inline mlist_t mblock_t::build_def_list(const minsn_t &ins, maymust_t maymust) const
11158{
11159 mlist_t retval;
11160 HEXDSP(hx_mblock_t_build_def_list, &retval, this, &ins, maymust);
11161 return retval;
11162}
11163
11164//--------------------------------------------------------------------------
11165inline const minsn_t *mblock_t::find_first_use(mlist_t *list, const minsn_t *i1, const minsn_t *i2, maymust_t maymust) const
11166{
11167 return (const minsn_t *)HEXDSP(hx_mblock_t_find_first_use, this, list, i1, i2, maymust);
11168}
11169
11170//--------------------------------------------------------------------------
11171inline const minsn_t *mblock_t::find_redefinition(const mlist_t &list, const minsn_t *i1, const minsn_t *i2, maymust_t maymust) const
11172{
11173 return (const minsn_t *)HEXDSP(hx_mblock_t_find_redefinition, this, &list, i1, i2, maymust);
11174}
11175
11176//--------------------------------------------------------------------------
11177inline bool mblock_t::is_rhs_redefined(const minsn_t *ins, const minsn_t *i1, const minsn_t *i2) const
11178{
11179 return (uchar)(size_t)HEXDSP(hx_mblock_t_is_rhs_redefined, this, ins, i1, i2) != 0;
11180}
11181
11182//--------------------------------------------------------------------------
11183inline minsn_t *mblock_t::find_access(const mop_t &op, minsn_t **parent, const minsn_t *mend, int fdflags) const
11184{
11185 return (minsn_t *)HEXDSP(hx_mblock_t_find_access, this, &op, parent, mend, fdflags);
11186}
11187
11188//--------------------------------------------------------------------------
11189inline bool mblock_t::get_valranges(valrng_t *res, const vivl_t &vivl, int vrflags) const
11190{
11191 return (uchar)(size_t)HEXDSP(hx_mblock_t_get_valranges, this, res, &vivl, vrflags) != 0;
11192}
11193
11194//--------------------------------------------------------------------------
11195inline bool mblock_t::get_valranges(valrng_t *res, const vivl_t &vivl, const minsn_t *m, int vrflags) const
11196{
11197 return (uchar)(size_t)HEXDSP(hx_mblock_t_get_valranges_, this, res, &vivl, m, vrflags) != 0;
11198}
11199
11200//--------------------------------------------------------------------------
11201inline size_t mblock_t::get_reginsn_qty() const
11202{
11203 return (size_t)HEXDSP(hx_mblock_t_get_reginsn_qty, this);
11204}
11205
11206//--------------------------------------------------------------------------
11207inline bool mba_ranges_t::range_contains(ea_t ea) const
11208{
11209 return (uchar)(size_t)HEXDSP(hx_mba_ranges_t_range_contains, this, ea) != 0;
11210}
11211
11212//--------------------------------------------------------------------------
11213inline sval_t mba_t::stkoff_vd2ida(sval_t off) const
11214{
11215 sval_t retval;
11216 HEXDSP(hx_mba_t_stkoff_vd2ida, &retval, this, off);
11217 return retval;
11218}
11219
11220//--------------------------------------------------------------------------
11221inline sval_t mba_t::stkoff_ida2vd(sval_t off) const
11222{
11223 sval_t retval;
11224 HEXDSP(hx_mba_t_stkoff_ida2vd, &retval, this, off);
11225 return retval;
11226}
11227
11228//--------------------------------------------------------------------------
11229inline vdloc_t mba_t::idaloc2vd(const argloc_t &loc, int width, sval_t spd)
11230{
11231 vdloc_t retval;
11232 HEXDSP(hx_mba_t_idaloc2vd, &retval, &loc, width, spd);
11233 return retval;
11234}
11235
11236//--------------------------------------------------------------------------
11237inline vdloc_t mba_t::idaloc2vd(const argloc_t &loc, int width) const
11238{
11239 vdloc_t retval;
11240 HEXDSP(hx_mba_t_idaloc2vd_, &retval, this, &loc, width);
11241 return retval;
11242}
11243
11244//--------------------------------------------------------------------------
11245inline argloc_t mba_t::vd2idaloc(const vdloc_t &loc, int width, sval_t spd)
11246{
11247 argloc_t retval;
11248 HEXDSP(hx_mba_t_vd2idaloc, &retval, &loc, width, spd);
11249 return retval;
11250}
11251
11252//--------------------------------------------------------------------------
11253inline argloc_t mba_t::vd2idaloc(const vdloc_t &loc, int width) const
11254{
11255 argloc_t retval;
11256 HEXDSP(hx_mba_t_vd2idaloc_, &retval, this, &loc, width);
11257 return retval;
11258}
11259
11260//--------------------------------------------------------------------------
11261inline void mba_t::term()
11262{
11263 HEXDSP(hx_mba_t_term, this);
11264}
11265
11266//--------------------------------------------------------------------------
11267inline func_t *mba_t::get_curfunc() const
11268{
11269 return (func_t *)HEXDSP(hx_mba_t_get_curfunc, this);
11270}
11271
11272//--------------------------------------------------------------------------
11274{
11275 return (uchar)(size_t)HEXDSP(hx_mba_t_set_maturity, this, mat) != 0;
11276}
11277
11278//--------------------------------------------------------------------------
11279inline int mba_t::optimize_local(int locopt_bits)
11280{
11281 return (int)(size_t)HEXDSP(hx_mba_t_optimize_local, this, locopt_bits);
11282}
11283
11284//--------------------------------------------------------------------------
11286{
11287 return (merror_t)(size_t)HEXDSP(hx_mba_t_build_graph, this);
11288}
11289
11290//--------------------------------------------------------------------------
11292{
11293 return (mbl_graph_t *)HEXDSP(hx_mba_t_get_graph, this);
11294}
11295
11296//--------------------------------------------------------------------------
11297inline int mba_t::analyze_calls(int acflags)
11298{
11299 return (int)(size_t)HEXDSP(hx_mba_t_analyze_calls, this, acflags);
11300}
11301
11302//--------------------------------------------------------------------------
11304{
11305 return (merror_t)(size_t)HEXDSP(hx_mba_t_optimize_global, this);
11306}
11307
11308//--------------------------------------------------------------------------
11310{
11311 HEXDSP(hx_mba_t_alloc_lvars, this);
11312}
11313
11314//--------------------------------------------------------------------------
11315inline void mba_t::dump() const
11316{
11317 HEXDSP(hx_mba_t_dump, this);
11318}
11319
11320//--------------------------------------------------------------------------
11321inline AS_PRINTF(3, 0) void mba_t::vdump_mba(bool _verify, const char *title, va_list va) const
11322{
11323 HEXDSP(hx_mba_t_vdump_mba, this, _verify, title, va);
11324}
11325
11326//--------------------------------------------------------------------------
11327inline void mba_t::print(vd_printer_t &vp) const
11328{
11329 HEXDSP(hx_mba_t_print, this, &vp);
11330}
11331
11332//--------------------------------------------------------------------------
11333inline void mba_t::verify(bool always) const
11334{
11335 HEXDSP(hx_mba_t_verify, this, always);
11336}
11337
11338//--------------------------------------------------------------------------
11340{
11341 HEXDSP(hx_mba_t_mark_chains_dirty, this);
11342}
11343
11344//--------------------------------------------------------------------------
11346{
11347 return (mblock_t *)HEXDSP(hx_mba_t_insert_block, this, bblk);
11348}
11349
11350//--------------------------------------------------------------------------
11352{
11353 return (uchar)(size_t)HEXDSP(hx_mba_t_remove_block, this, blk) != 0;
11354}
11355
11356//--------------------------------------------------------------------------
11357inline mblock_t *mba_t::copy_block(mblock_t *blk, int new_serial, int cpblk_flags)
11358{
11359 return (mblock_t *)HEXDSP(hx_mba_t_copy_block, this, blk, new_serial, cpblk_flags);
11360}
11361
11362//--------------------------------------------------------------------------
11364{
11365 return (uchar)(size_t)HEXDSP(hx_mba_t_remove_empty_and_unreachable_blocks, this) != 0;
11366}
11367
11368//--------------------------------------------------------------------------
11370{
11371 return (uchar)(size_t)HEXDSP(hx_mba_t_combine_blocks, this) != 0;
11372}
11373
11374//--------------------------------------------------------------------------
11376{
11377 return (int)(size_t)HEXDSP(hx_mba_t_for_all_ops, this, &mv);
11378}
11379
11380//--------------------------------------------------------------------------
11382{
11383 return (int)(size_t)HEXDSP(hx_mba_t_for_all_insns, this, &mv);
11384}
11385
11386//--------------------------------------------------------------------------
11388{
11389 return (int)(size_t)HEXDSP(hx_mba_t_for_all_topinsns, this, &mv);
11390}
11391
11392//--------------------------------------------------------------------------
11393inline mop_t *mba_t::find_mop(op_parent_info_t *ctx, ea_t ea, bool is_dest, const mlist_t &list)
11394{
11395 return (mop_t *)HEXDSP(hx_mba_t_find_mop, this, ctx, ea, is_dest, &list);
11396}
11397
11398//--------------------------------------------------------------------------
11399inline 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)
11400{
11401 return (minsn_t *)HEXDSP(hx_mba_t_create_helper_call, this, ea, helper, rettype, callargs, out);
11402}
11403
11404//--------------------------------------------------------------------------
11405inline void mba_t::get_func_output_lists(mlist_t *return_regs, mlist_t *spoiled, const tinfo_t &type, ea_t call_ea, bool tail_call)
11406{
11407 HEXDSP(hx_mba_t_get_func_output_lists, this, return_regs, spoiled, &type, call_ea, tail_call);
11408}
11409
11410//--------------------------------------------------------------------------
11411inline lvar_t &mba_t::arg(int n)
11412{
11413 return *(lvar_t *)HEXDSP(hx_mba_t_arg, this, n);
11414}
11415
11416//--------------------------------------------------------------------------
11417inline ea_t mba_t::alloc_fict_ea(ea_t real_ea)
11418{
11419 ea_t retval;
11420 HEXDSP(hx_mba_t_alloc_fict_ea, &retval, this, real_ea);
11421 return retval;
11422}
11423
11424//--------------------------------------------------------------------------
11425inline ea_t mba_t::map_fict_ea(ea_t fict_ea) const
11426{
11427 ea_t retval;
11428 HEXDSP(hx_mba_t_map_fict_ea, &retval, this, fict_ea);
11429 return retval;
11430}
11431
11432//--------------------------------------------------------------------------
11433inline void mba_t::serialize(bytevec_t &vout) const
11434{
11435 HEXDSP(hx_mba_t_serialize, this, &vout);
11436}
11437
11438//--------------------------------------------------------------------------
11439inline WARN_UNUSED_RESULT mba_t *mba_t::deserialize(const uchar *bytes, size_t nbytes)
11440{
11441 return (mba_t *)HEXDSP(hx_mba_t_deserialize, bytes, nbytes);
11442}
11443
11444//--------------------------------------------------------------------------
11445inline void mba_t::save_snapshot(const char *description)
11446{
11447 HEXDSP(hx_mba_t_save_snapshot, this, description);
11448}
11449
11450//--------------------------------------------------------------------------
11451inline mreg_t mba_t::alloc_kreg(size_t size, bool check_size)
11452{
11453 return (mreg_t)(size_t)HEXDSP(hx_mba_t_alloc_kreg, this, size, check_size);
11454}
11455
11456//--------------------------------------------------------------------------
11457inline void mba_t::free_kreg(mreg_t reg, size_t size)
11458{
11459 HEXDSP(hx_mba_t_free_kreg, this, reg, size);
11460}
11461
11462//--------------------------------------------------------------------------
11463inline bool mba_t::set_lvar_name(lvar_t &v, const char *name, int flagbits)
11464{
11465 return (uchar)(size_t)HEXDSP(hx_mba_t_set_lvar_name, this, &v, name, flagbits) != 0;
11466}
11467
11468//--------------------------------------------------------------------------
11469inline 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
11470{
11471 return (uchar)(size_t)HEXDSP(hx_mbl_graph_t_is_accessed_globally, this, &list, b1, b2, m1, m2, access_type, maymust) != 0;
11472}
11473
11474//--------------------------------------------------------------------------
11476{
11477 return (graph_chains_t *)HEXDSP(hx_mbl_graph_t_get_ud, this, gctype);
11478}
11479
11480//--------------------------------------------------------------------------
11482{
11483 return (graph_chains_t *)HEXDSP(hx_mbl_graph_t_get_du, this, gctype);
11484}
11485
11486//--------------------------------------------------------------------------
11487inline merror_t cdg_insn_iterator_t::next(insn_t *ins)
11488{
11489 return (merror_t)(size_t)HEXDSP(hx_cdg_insn_iterator_t_next, this, ins);
11490}
11491
11492//--------------------------------------------------------------------------
11493inline minsn_t *codegen_t::emit(mcode_t code, int width, uval_t l, uval_t r, uval_t d, int offsize)
11494{
11495 return (minsn_t *)HEXDSP(hx_codegen_t_emit, this, code, width, l, r, d, offsize);
11496}
11497
11498//--------------------------------------------------------------------------
11499inline minsn_t *codegen_t::emit(mcode_t code, const mop_t *l, const mop_t *r, const mop_t *d)
11500{
11501 return (minsn_t *)HEXDSP(hx_codegen_t_emit_, this, code, l, r, d);
11502}
11503
11504//--------------------------------------------------------------------------
11505inline bool change_hexrays_config(const char *directive)
11506{
11507 return (uchar)(size_t)HEXDSP(hx_change_hexrays_config, directive) != 0;
11508}
11509
11510//--------------------------------------------------------------------------
11511inline const char *get_hexrays_version()
11512{
11513 return (const char *)HEXDSP(hx_get_hexrays_version);
11514}
11515
11516//--------------------------------------------------------------------------
11517inline bool checkout_hexrays_license(bool silent)
11518{
11519 return (uchar)(size_t)HEXDSP(hx_checkout_hexrays_license, silent) != 0;
11520}
11521
11522//--------------------------------------------------------------------------
11523inline vdui_t *open_pseudocode(ea_t ea, int flags)
11524{
11525 return (vdui_t *)HEXDSP(hx_open_pseudocode, ea, flags);
11526}
11527
11528//--------------------------------------------------------------------------
11530{
11531 return (uchar)(size_t)HEXDSP(hx_close_pseudocode, f) != 0;
11532}
11533
11534//--------------------------------------------------------------------------
11536{
11537 return (vdui_t *)HEXDSP(hx_get_widget_vdui, f);
11538}
11539
11540//--------------------------------------------------------------------------
11541inline bool decompile_many(const char *outfile, const eavec_t *funcaddrs, int flags)
11542{
11543 return (uchar)(size_t)HEXDSP(hx_decompile_many, outfile, funcaddrs, flags) != 0;
11544}
11545
11546//--------------------------------------------------------------------------
11547inline qstring hexrays_failure_t::desc() const
11548{
11549 qstring retval;
11550 HEXDSP(hx_hexrays_failure_t_desc, &retval, this);
11551 return retval;
11552}
11553
11554//--------------------------------------------------------------------------
11555inline void send_database(const hexrays_failure_t &err, bool silent)
11556{
11557 HEXDSP(hx_send_database, &err, silent);
11558}
11559
11560//--------------------------------------------------------------------------
11561inline bool gco_info_t::append_to_list(mlist_t *list, const mba_t *mba) const
11562{
11563 return (uchar)(size_t)HEXDSP(hx_gco_info_t_append_to_list, this, list, mba) != 0;
11564}
11565
11566//--------------------------------------------------------------------------
11568{
11569 return (uchar)(size_t)HEXDSP(hx_get_current_operand, out) != 0;
11570}
11571
11572//--------------------------------------------------------------------------
11573inline void remitem(const citem_t *e)
11574{
11575 HEXDSP(hx_remitem, e);
11576}
11577
11578//--------------------------------------------------------------------------
11580{
11581 return (ctype_t)(size_t)HEXDSP(hx_negated_relation, op);
11582}
11583
11584//--------------------------------------------------------------------------
11586{
11587 return (ctype_t)(size_t)HEXDSP(hx_swapped_relation, op);
11588}
11589
11590//--------------------------------------------------------------------------
11591inline type_sign_t get_op_signness(ctype_t op)
11592{
11593 return (type_sign_t)(size_t)HEXDSP(hx_get_op_signness, op);
11594}
11595
11596//--------------------------------------------------------------------------
11598{
11599 return (ctype_t)(size_t)HEXDSP(hx_asgop, cop);
11600}
11601
11602//--------------------------------------------------------------------------
11604{
11605 return (ctype_t)(size_t)HEXDSP(hx_asgop_revert, cop);
11606}
11607
11608//--------------------------------------------------------------------------
11609inline void cnumber_t::print(qstring *vout, const tinfo_t &type, const citem_t *parent, bool *nice_stroff) const
11610{
11611 HEXDSP(hx_cnumber_t_print, this, vout, &type, parent, nice_stroff);
11612}
11613
11614//--------------------------------------------------------------------------
11615inline uint64 cnumber_t::value(const tinfo_t &type) const
11616{
11617 uint64 retval;
11618 HEXDSP(hx_cnumber_t_value, &retval, this, &type);
11619 return retval;
11620}
11621
11622//--------------------------------------------------------------------------
11623inline void cnumber_t::assign(uint64 v, int nbytes, type_sign_t sign)
11624{
11625 HEXDSP(hx_cnumber_t_assign, this, v, nbytes, sign);
11626}
11627
11628//--------------------------------------------------------------------------
11629inline int cnumber_t::compare(const cnumber_t &r) const
11630{
11631 return (int)(size_t)HEXDSP(hx_cnumber_t_compare, this, &r);
11632}
11633
11634//--------------------------------------------------------------------------
11635inline int var_ref_t::compare(const var_ref_t &r) const
11636{
11637 return (int)(size_t)HEXDSP(hx_var_ref_t_compare, this, &r);
11638}
11639
11640//--------------------------------------------------------------------------
11642{
11643 return (int)(size_t)HEXDSP(hx_ctree_visitor_t_apply_to, this, item, parent);
11644}
11645
11646//--------------------------------------------------------------------------
11648{
11649 return (int)(size_t)HEXDSP(hx_ctree_visitor_t_apply_to_exprs, this, item, parent);
11650}
11651
11652//--------------------------------------------------------------------------
11654{
11655 return (uchar)(size_t)HEXDSP(hx_ctree_parentee_t_recalc_parent_types, this) != 0;
11656}
11657
11658//--------------------------------------------------------------------------
11659inline bool cfunc_parentee_t::calc_rvalue_type(tinfo_t *target, const cexpr_t *e)
11660{
11661 return (uchar)(size_t)HEXDSP(hx_cfunc_parentee_t_calc_rvalue_type, this, target, e) != 0;
11662}
11663
11664//--------------------------------------------------------------------------
11665inline int citem_locator_t::compare(const citem_locator_t &r) const
11666{
11667 return (int)(size_t)HEXDSP(hx_citem_locator_t_compare, this, &r);
11668}
11669
11670//--------------------------------------------------------------------------
11671inline bool citem_t::contains_expr(const cexpr_t *e) const
11672{
11673 return (uchar)(size_t)HEXDSP(hx_citem_t_contains_expr, this, e) != 0;
11674}
11675
11676//--------------------------------------------------------------------------
11677inline bool citem_t::contains_label() const
11678{
11679 return (uchar)(size_t)HEXDSP(hx_citem_t_contains_label, this) != 0;
11680}
11681
11682//--------------------------------------------------------------------------
11683inline const citem_t *citem_t::find_parent_of(const citem_t *sitem) const
11684{
11685 return (const citem_t *)HEXDSP(hx_citem_t_find_parent_of, this, sitem);
11686}
11687
11688//--------------------------------------------------------------------------
11689inline citem_t *citem_t::find_closest_addr(ea_t _ea)
11690{
11691 return (citem_t *)HEXDSP(hx_citem_t_find_closest_addr, this, _ea);
11692}
11693
11694//--------------------------------------------------------------------------
11695inline cexpr_t &cexpr_t::assign(const cexpr_t &r)
11696{
11697 return *(cexpr_t *)HEXDSP(hx_cexpr_t_assign, this, &r);
11698}
11699
11700//--------------------------------------------------------------------------
11701inline int cexpr_t::compare(const cexpr_t &r) const
11702{
11703 return (int)(size_t)HEXDSP(hx_cexpr_t_compare, this, &r);
11704}
11705
11706//--------------------------------------------------------------------------
11708{
11709 HEXDSP(hx_cexpr_t_replace_by, this, r);
11710}
11711
11712//--------------------------------------------------------------------------
11713inline void cexpr_t::cleanup()
11714{
11715 HEXDSP(hx_cexpr_t_cleanup, this);
11716}
11717
11718//--------------------------------------------------------------------------
11719inline void cexpr_t::put_number(cfunc_t *func, uint64 value, int nbytes, type_sign_t sign)
11720{
11721 HEXDSP(hx_cexpr_t_put_number, this, func, value, nbytes, sign);
11722}
11723
11724//--------------------------------------------------------------------------
11725inline void cexpr_t::print1(qstring *vout, const cfunc_t *func) const
11726{
11727 HEXDSP(hx_cexpr_t_print1, this, vout, func);
11728}
11729
11730//--------------------------------------------------------------------------
11731inline void cexpr_t::calc_type(bool recursive)
11732{
11733 HEXDSP(hx_cexpr_t_calc_type, this, recursive);
11734}
11735
11736//--------------------------------------------------------------------------
11737inline bool cexpr_t::equal_effect(const cexpr_t &r) const
11738{
11739 return (uchar)(size_t)HEXDSP(hx_cexpr_t_equal_effect, this, &r) != 0;
11740}
11741
11742//--------------------------------------------------------------------------
11743inline bool cexpr_t::is_child_of(const citem_t *parent) const
11744{
11745 return (uchar)(size_t)HEXDSP(hx_cexpr_t_is_child_of, this, parent) != 0;
11746}
11747
11748//--------------------------------------------------------------------------
11749inline bool cexpr_t::contains_operator(ctype_t needed_op, int times) const
11750{
11751 return (uchar)(size_t)HEXDSP(hx_cexpr_t_contains_operator, this, needed_op, times) != 0;
11752}
11753
11754//--------------------------------------------------------------------------
11756{
11757 bit_bound_t retval;
11758 HEXDSP(hx_cexpr_t_get_high_nbit_bound, &retval, this);
11759 return retval;
11760}
11761
11762//--------------------------------------------------------------------------
11764{
11765 return (int)(size_t)HEXDSP(hx_cexpr_t_get_low_nbit_bound, this);
11766}
11767
11768//--------------------------------------------------------------------------
11769inline bool cexpr_t::requires_lvalue(const cexpr_t *child) const
11770{
11771 return (uchar)(size_t)HEXDSP(hx_cexpr_t_requires_lvalue, this, child) != 0;
11772}
11773
11774//--------------------------------------------------------------------------
11775inline bool cexpr_t::has_side_effects() const
11776{
11777 return (uchar)(size_t)HEXDSP(hx_cexpr_t_has_side_effects, this) != 0;
11778}
11779
11780//--------------------------------------------------------------------------
11781inline bool cexpr_t::maybe_ptr() const
11782{
11783 return (uchar)(size_t)HEXDSP(hx_cexpr_t_maybe_ptr, this) != 0;
11784}
11785
11786//--------------------------------------------------------------------------
11787inline const char *cexpr_t::dstr() const
11788{
11789 return (const char *)HEXDSP(hx_cexpr_t_dstr, this);
11790}
11791
11792//--------------------------------------------------------------------------
11793inline cif_t &cif_t::assign(const cif_t &r)
11794{
11795 return *(cif_t *)HEXDSP(hx_cif_t_assign, this, &r);
11796}
11797
11798//--------------------------------------------------------------------------
11799inline int cif_t::compare(const cif_t &r) const
11800{
11801 return (int)(size_t)HEXDSP(hx_cif_t_compare, this, &r);
11802}
11803
11804//--------------------------------------------------------------------------
11805inline cloop_t &cloop_t::assign(const cloop_t &r)
11806{
11807 return *(cloop_t *)HEXDSP(hx_cloop_t_assign, this, &r);
11808}
11809
11810//--------------------------------------------------------------------------
11811inline int cfor_t::compare(const cfor_t &r) const
11812{
11813 return (int)(size_t)HEXDSP(hx_cfor_t_compare, this, &r);
11814}
11815
11816//--------------------------------------------------------------------------
11817inline int cwhile_t::compare(const cwhile_t &r) const
11818{
11819 return (int)(size_t)HEXDSP(hx_cwhile_t_compare, this, &r);
11820}
11821
11822//--------------------------------------------------------------------------
11823inline int cdo_t::compare(const cdo_t &r) const
11824{
11825 return (int)(size_t)HEXDSP(hx_cdo_t_compare, this, &r);
11826}
11827
11828//--------------------------------------------------------------------------
11829inline int creturn_t::compare(const creturn_t &r) const
11830{
11831 return (int)(size_t)HEXDSP(hx_creturn_t_compare, this, &r);
11832}
11833
11834//--------------------------------------------------------------------------
11835inline int cgoto_t::compare(const cgoto_t &r) const
11836{
11837 return (int)(size_t)HEXDSP(hx_cgoto_t_compare, this, &r);
11838}
11839
11840//--------------------------------------------------------------------------
11841inline int casm_t::compare(const casm_t &r) const
11842{
11843 return (int)(size_t)HEXDSP(hx_casm_t_compare, this, &r);
11844}
11845
11846//--------------------------------------------------------------------------
11847inline cinsn_t &cinsn_t::assign(const cinsn_t &r)
11848{
11849 return *(cinsn_t *)HEXDSP(hx_cinsn_t_assign, this, &r);
11850}
11851
11852//--------------------------------------------------------------------------
11853inline int cinsn_t::compare(const cinsn_t &r) const
11854{
11855 return (int)(size_t)HEXDSP(hx_cinsn_t_compare, this, &r);
11856}
11857
11858//--------------------------------------------------------------------------
11860{
11861 HEXDSP(hx_cinsn_t_replace_by, this, r);
11862}
11863
11864//--------------------------------------------------------------------------
11865inline void cinsn_t::cleanup()
11866{
11867 HEXDSP(hx_cinsn_t_cleanup, this);
11868}
11869
11870//--------------------------------------------------------------------------
11871inline cinsn_t &cinsn_t::new_insn(ea_t insn_ea)
11872{
11873 return *(cinsn_t *)HEXDSP(hx_cinsn_t_new_insn, this, insn_ea);
11874}
11875
11876//--------------------------------------------------------------------------
11878{
11879 return *(cif_t *)HEXDSP(hx_cinsn_t_create_if, this, cnd);
11880}
11881
11882//--------------------------------------------------------------------------
11883inline void cinsn_t::print(int indent, vc_printer_t &vp, use_curly_t use_curly) const
11884{
11885 HEXDSP(hx_cinsn_t_print, this, indent, &vp, use_curly);
11886}
11887
11888//--------------------------------------------------------------------------
11889inline void cinsn_t::print1(qstring *vout, const cfunc_t *func) const
11890{
11891 HEXDSP(hx_cinsn_t_print1, this, vout, func);
11892}
11893
11894//--------------------------------------------------------------------------
11895inline bool cinsn_t::is_ordinary_flow() const
11896{
11897 return (uchar)(size_t)HEXDSP(hx_cinsn_t_is_ordinary_flow, this) != 0;
11898}
11899
11900//--------------------------------------------------------------------------
11901inline bool cinsn_t::contains_insn(ctype_t type, int times) const
11902{
11903 return (uchar)(size_t)HEXDSP(hx_cinsn_t_contains_insn, this, type, times) != 0;
11904}
11905
11906//--------------------------------------------------------------------------
11908{
11909 return (uchar)(size_t)HEXDSP(hx_cinsn_t_collect_free_breaks, this, breaks) != 0;
11910}
11911
11912//--------------------------------------------------------------------------
11914{
11915 return (uchar)(size_t)HEXDSP(hx_cinsn_t_collect_free_continues, this, continues) != 0;
11916}
11917
11918//--------------------------------------------------------------------------
11919inline const char *cinsn_t::dstr() const
11920{
11921 return (const char *)HEXDSP(hx_cinsn_t_dstr, this);
11922}
11923
11924//--------------------------------------------------------------------------
11925inline int cblock_t::compare(const cblock_t &r) const
11926{
11927 return (int)(size_t)HEXDSP(hx_cblock_t_compare, this, &r);
11928}
11929
11930//--------------------------------------------------------------------------
11931inline int carglist_t::compare(const carglist_t &r) const
11932{
11933 return (int)(size_t)HEXDSP(hx_carglist_t_compare, this, &r);
11934}
11935
11936//--------------------------------------------------------------------------
11937inline int ccase_t::compare(const ccase_t &r) const
11938{
11939 return (int)(size_t)HEXDSP(hx_ccase_t_compare, this, &r);
11940}
11941
11942//--------------------------------------------------------------------------
11943inline int ccases_t::compare(const ccases_t &r) const
11944{
11945 return (int)(size_t)HEXDSP(hx_ccases_t_compare, this, &r);
11946}
11947
11948//--------------------------------------------------------------------------
11949inline int cswitch_t::compare(const cswitch_t &r) const
11950{
11951 return (int)(size_t)HEXDSP(hx_cswitch_t_compare, this, &r);
11952}
11953
11954//--------------------------------------------------------------------------
11955inline member_t *ctree_item_t::get_memptr(struc_t **p_sptr) const
11956{
11957 return (member_t *)HEXDSP(hx_ctree_item_t_get_memptr, this, p_sptr);
11958}
11959
11960//--------------------------------------------------------------------------
11961inline int ctree_item_t::get_udm(udm_t *udm, tinfo_t *parent, uint64 *p_offset) const
11962{
11963 return (int)(size_t)HEXDSP(hx_ctree_item_t_get_udm, this, udm, parent, p_offset);
11964}
11965
11966//--------------------------------------------------------------------------
11967inline int ctree_item_t::get_edm(tinfo_t *parent) const
11968{
11969 return (int)(size_t)HEXDSP(hx_ctree_item_t_get_edm, this, parent);
11970}
11971
11972//--------------------------------------------------------------------------
11974{
11975 return (lvar_t *)HEXDSP(hx_ctree_item_t_get_lvar, this);
11976}
11977
11978//--------------------------------------------------------------------------
11979inline ea_t ctree_item_t::get_ea() const
11980{
11981 ea_t retval;
11982 HEXDSP(hx_ctree_item_t_get_ea, &retval, this);
11983 return retval;
11984}
11985
11986//--------------------------------------------------------------------------
11987inline int ctree_item_t::get_label_num(int gln_flags) const
11988{
11989 return (int)(size_t)HEXDSP(hx_ctree_item_t_get_label_num, this, gln_flags);
11990}
11991
11992//--------------------------------------------------------------------------
11993inline void ctree_item_t::print(qstring *vout) const
11994{
11995 HEXDSP(hx_ctree_item_t_print, this, vout);
11996}
11997
11998//--------------------------------------------------------------------------
11999inline const char *ctree_item_t::dstr() const
12000{
12001 return (const char *)HEXDSP(hx_ctree_item_t_dstr, this);
12002}
12003
12004//--------------------------------------------------------------------------
12006{
12007 return (cexpr_t *)HEXDSP(hx_lnot, e);
12008}
12009
12010//--------------------------------------------------------------------------
12012{
12013 return (cinsn_t *)HEXDSP(hx_new_block);
12014}
12015
12016//--------------------------------------------------------------------------
12017inline AS_PRINTF(3, 0) cexpr_t *vcreate_helper(bool standalone, const tinfo_t &type, const char *format, va_list va)
12018{
12019 return (cexpr_t *)HEXDSP(hx_vcreate_helper, standalone, &type, format, va);
12020}
12021
12022//--------------------------------------------------------------------------
12023inline AS_PRINTF(3, 0) cexpr_t *vcall_helper(const tinfo_t &rettype, carglist_t *args, const char *format, va_list va)
12024{
12025 return (cexpr_t *)HEXDSP(hx_vcall_helper, &rettype, args, format, va);
12026}
12027
12028//--------------------------------------------------------------------------
12029inline cexpr_t *make_num(uint64 n, cfunc_t *func, ea_t ea, int opnum, type_sign_t sign, int size)
12030{
12031 return (cexpr_t *)HEXDSP(hx_make_num, n, func, ea, opnum, sign, size);
12032}
12033
12034//--------------------------------------------------------------------------
12036{
12037 return (cexpr_t *)HEXDSP(hx_make_ref, e);
12038}
12039
12040//--------------------------------------------------------------------------
12041inline cexpr_t *dereference(cexpr_t *e, int ptrsize, bool is_flt)
12042{
12043 return (cexpr_t *)HEXDSP(hx_dereference, e, ptrsize, is_flt);
12044}
12045
12046//--------------------------------------------------------------------------
12047inline void save_user_labels(ea_t func_ea, const user_labels_t *user_labels)
12048{
12049 HEXDSP(hx_save_user_labels, func_ea, user_labels);
12050}
12051
12052//--------------------------------------------------------------------------
12053inline void save_user_labels2(ea_t func_ea, const user_labels_t *user_labels, const cfunc_t *func)
12054{
12055 HEXDSP(hx_save_user_labels2, func_ea, user_labels, func);
12056}
12057
12058//--------------------------------------------------------------------------
12059inline void save_user_cmts(ea_t func_ea, const user_cmts_t *user_cmts)
12060{
12061 HEXDSP(hx_save_user_cmts, func_ea, user_cmts);
12062}
12063
12064//--------------------------------------------------------------------------
12065inline void save_user_numforms(ea_t func_ea, const user_numforms_t *numforms)
12066{
12067 HEXDSP(hx_save_user_numforms, func_ea, numforms);
12068}
12069
12070//--------------------------------------------------------------------------
12071inline void save_user_iflags(ea_t func_ea, const user_iflags_t *iflags)
12072{
12073 HEXDSP(hx_save_user_iflags, func_ea, iflags);
12074}
12075
12076//--------------------------------------------------------------------------
12077inline void save_user_unions(ea_t func_ea, const user_unions_t *unions)
12078{
12079 HEXDSP(hx_save_user_unions, func_ea, unions);
12080}
12081
12082//--------------------------------------------------------------------------
12084{
12085 return (user_labels_t *)HEXDSP(hx_restore_user_labels, func_ea);
12086}
12087
12088//--------------------------------------------------------------------------
12089inline user_labels_t *restore_user_labels2(ea_t func_ea, const cfunc_t *func)
12090{
12091 return (user_labels_t *)HEXDSP(hx_restore_user_labels2, func_ea, func);
12092}
12093
12094//--------------------------------------------------------------------------
12095inline user_cmts_t *restore_user_cmts(ea_t func_ea)
12096{
12097 return (user_cmts_t *)HEXDSP(hx_restore_user_cmts, func_ea);
12098}
12099
12100//--------------------------------------------------------------------------
12102{
12103 return (user_numforms_t *)HEXDSP(hx_restore_user_numforms, func_ea);
12104}
12105
12106//--------------------------------------------------------------------------
12107inline user_iflags_t *restore_user_iflags(ea_t func_ea)
12108{
12109 return (user_iflags_t *)HEXDSP(hx_restore_user_iflags, func_ea);
12110}
12111
12112//--------------------------------------------------------------------------
12113inline user_unions_t *restore_user_unions(ea_t func_ea)
12114{
12115 return (user_unions_t *)HEXDSP(hx_restore_user_unions, func_ea);
12116}
12117
12118//--------------------------------------------------------------------------
12120{
12121 HEXDSP(hx_cfunc_t_build_c_tree, this);
12122}
12123
12124//--------------------------------------------------------------------------
12125inline void cfunc_t::verify(allow_unused_labels_t aul, bool even_without_debugger) const
12126{
12127 HEXDSP(hx_cfunc_t_verify, this, aul, even_without_debugger);
12128}
12129
12130//--------------------------------------------------------------------------
12131inline void cfunc_t::print_dcl(qstring *vout) const
12132{
12133 HEXDSP(hx_cfunc_t_print_dcl, this, vout);
12134}
12135
12136//--------------------------------------------------------------------------
12137inline void cfunc_t::print_func(vc_printer_t &vp) const
12138{
12139 HEXDSP(hx_cfunc_t_print_func, this, &vp);
12140}
12141
12142//--------------------------------------------------------------------------
12143inline bool cfunc_t::get_func_type(tinfo_t *type) const
12144{
12145 return (uchar)(size_t)HEXDSP(hx_cfunc_t_get_func_type, this, type) != 0;
12146}
12147
12148//--------------------------------------------------------------------------
12150{
12151 return (lvars_t *)HEXDSP(hx_cfunc_t_get_lvars, this);
12152}
12153
12154//--------------------------------------------------------------------------
12156{
12157 sval_t retval;
12158 HEXDSP(hx_cfunc_t_get_stkoff_delta, &retval, this);
12159 return retval;
12160}
12161
12162//--------------------------------------------------------------------------
12164{
12165 return (citem_t *)HEXDSP(hx_cfunc_t_find_label, this, label);
12166}
12167
12168//--------------------------------------------------------------------------
12170{
12171 HEXDSP(hx_cfunc_t_remove_unused_labels, this);
12172}
12173
12174//--------------------------------------------------------------------------
12175inline const char *cfunc_t::get_user_cmt(const treeloc_t &loc, cmt_retrieval_type_t rt) const
12176{
12177 return (const char *)HEXDSP(hx_cfunc_t_get_user_cmt, this, &loc, rt);
12178}
12179
12180//--------------------------------------------------------------------------
12181inline void cfunc_t::set_user_cmt(const treeloc_t &loc, const char *cmt)
12182{
12183 HEXDSP(hx_cfunc_t_set_user_cmt, this, &loc, cmt);
12184}
12185
12186//--------------------------------------------------------------------------
12187inline int32 cfunc_t::get_user_iflags(const citem_locator_t &loc) const
12188{
12189 return (int32)(size_t)HEXDSP(hx_cfunc_t_get_user_iflags, this, &loc);
12190}
12191
12192//--------------------------------------------------------------------------
12193inline void cfunc_t::set_user_iflags(const citem_locator_t &loc, int32 iflags)
12194{
12195 HEXDSP(hx_cfunc_t_set_user_iflags, this, &loc, iflags);
12196}
12197
12198//--------------------------------------------------------------------------
12199inline bool cfunc_t::has_orphan_cmts() const
12200{
12201 return (uchar)(size_t)HEXDSP(hx_cfunc_t_has_orphan_cmts, this) != 0;
12202}
12203
12204//--------------------------------------------------------------------------
12206{
12207 return (int)(size_t)HEXDSP(hx_cfunc_t_del_orphan_cmts, this);
12208}
12209
12210//--------------------------------------------------------------------------
12211inline bool cfunc_t::get_user_union_selection(ea_t ea, intvec_t *path)
12212{
12213 return (uchar)(size_t)HEXDSP(hx_cfunc_t_get_user_union_selection, this, ea, path) != 0;
12214}
12215
12216//--------------------------------------------------------------------------
12217inline void cfunc_t::set_user_union_selection(ea_t ea, const intvec_t &path)
12218{
12219 HEXDSP(hx_cfunc_t_set_user_union_selection, this, ea, &path);
12220}
12221
12222//--------------------------------------------------------------------------
12223inline void cfunc_t::save_user_labels() const
12224{
12225 HEXDSP(hx_cfunc_t_save_user_labels, this);
12226}
12227
12228//--------------------------------------------------------------------------
12229inline void cfunc_t::save_user_cmts() const
12230{
12231 HEXDSP(hx_cfunc_t_save_user_cmts, this);
12232}
12233
12234//--------------------------------------------------------------------------
12236{
12237 HEXDSP(hx_cfunc_t_save_user_numforms, this);
12238}
12239
12240//--------------------------------------------------------------------------
12241inline void cfunc_t::save_user_iflags() const
12242{
12243 HEXDSP(hx_cfunc_t_save_user_iflags, this);
12244}
12245
12246//--------------------------------------------------------------------------
12247inline void cfunc_t::save_user_unions() const
12248{
12249 HEXDSP(hx_cfunc_t_save_user_unions, this);
12250}
12251
12252//--------------------------------------------------------------------------
12253inline 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)
12254{
12255 return (uchar)(size_t)HEXDSP(hx_cfunc_t_get_line_item, this, line, x, is_ctree_line, phead, pitem, ptail) != 0;
12256}
12257
12258//--------------------------------------------------------------------------
12259inline hexwarns_t &cfunc_t::get_warnings()
12260{
12261 return *(hexwarns_t *)HEXDSP(hx_cfunc_t_get_warnings, this);
12262}
12263
12264//--------------------------------------------------------------------------
12265inline eamap_t &cfunc_t::get_eamap()
12266{
12267 return *(eamap_t *)HEXDSP(hx_cfunc_t_get_eamap, this);
12268}
12269
12270//--------------------------------------------------------------------------
12271inline boundaries_t &cfunc_t::get_boundaries()
12272{
12273 return *(boundaries_t *)HEXDSP(hx_cfunc_t_get_boundaries, this);
12274}
12275
12276//--------------------------------------------------------------------------
12278{
12279 return *(const strvec_t *)HEXDSP(hx_cfunc_t_get_pseudocode, this);
12280}
12281
12282//--------------------------------------------------------------------------
12284{
12285 HEXDSP(hx_cfunc_t_refresh_func_ctext, this);
12286}
12287
12288//--------------------------------------------------------------------------
12289inline bool cfunc_t::gather_derefs(const ctree_item_t &ci, udt_type_data_t *udm) const
12290{
12291 return (uchar)(size_t)HEXDSP(hx_cfunc_t_gather_derefs, this, &ci, udm) != 0;
12292}
12293
12294//--------------------------------------------------------------------------
12295inline bool cfunc_t::find_item_coords(const citem_t *item, int *px, int *py)
12296{
12297 return (uchar)(size_t)HEXDSP(hx_cfunc_t_find_item_coords, this, item, px, py) != 0;
12298}
12299
12300//--------------------------------------------------------------------------
12301inline void cfunc_t::cleanup()
12302{
12303 HEXDSP(hx_cfunc_t_cleanup, this);
12304}
12305
12306//--------------------------------------------------------------------------
12308{
12309 HEXDSP(hx_close_hexrays_waitbox);
12310}
12311
12312//--------------------------------------------------------------------------
12313inline cfuncptr_t decompile(const mba_ranges_t &mbr, hexrays_failure_t *hf, int decomp_flags)
12314{
12315 return cfuncptr_t((cfunc_t *)HEXDSP(hx_decompile, &mbr, hf, decomp_flags));
12316}
12317
12318//--------------------------------------------------------------------------
12319inline mba_t *gen_microcode(const mba_ranges_t &mbr, hexrays_failure_t *hf, const mlist_t *retlist, int decomp_flags, mba_maturity_t reqmat)
12320{
12321 return (mba_t *)HEXDSP(hx_gen_microcode, &mbr, hf, retlist, decomp_flags, reqmat);
12322}
12323
12324//--------------------------------------------------------------------------
12325inline cfuncptr_t create_cfunc(mba_t *mba)
12326{
12327 return cfuncptr_t((cfunc_t *)HEXDSP(hx_create_cfunc, mba));
12328}
12329
12330//--------------------------------------------------------------------------
12331inline bool mark_cfunc_dirty(ea_t ea, bool close_views)
12332{
12333 return (uchar)(size_t)HEXDSP(hx_mark_cfunc_dirty, ea, close_views) != 0;
12334}
12335
12336//--------------------------------------------------------------------------
12338{
12339 HEXDSP(hx_clear_cached_cfuncs);
12340}
12341
12342//--------------------------------------------------------------------------
12343inline bool has_cached_cfunc(ea_t ea)
12344{
12345 return (uchar)(size_t)HEXDSP(hx_has_cached_cfunc, ea) != 0;
12346}
12347
12348//--------------------------------------------------------------------------
12349inline const char *get_ctype_name(ctype_t op)
12350{
12351 return (const char *)HEXDSP(hx_get_ctype_name, op);
12352}
12353
12354//--------------------------------------------------------------------------
12355inline qstring create_field_name(const tinfo_t &type, uval_t offset)
12356{
12357 qstring retval;
12358 HEXDSP(hx_create_field_name, &retval, &type, offset);
12359 return retval;
12360}
12361
12362//--------------------------------------------------------------------------
12363inline bool install_hexrays_callback(hexrays_cb_t *callback, void *ud)
12364{
12365 return (uchar)(size_t)HEXDSP(hx_install_hexrays_callback, callback, ud) != 0;
12366}
12367
12368//--------------------------------------------------------------------------
12369inline int remove_hexrays_callback(hexrays_cb_t *callback, void *ud)
12370{
12371 auto hrdsp = HEXDSP;
12372 return hrdsp == nullptr ? 0 : (int)(size_t)hrdsp(hx_remove_hexrays_callback, callback, ud);
12373}
12374
12375//--------------------------------------------------------------------------
12376inline bool vdui_t::set_locked(bool v)
12377{
12378 return (uchar)(size_t)HEXDSP(hx_vdui_t_set_locked, this, v) != 0;
12379}
12380
12381//--------------------------------------------------------------------------
12382inline void vdui_t::refresh_view(bool redo_mba)
12383{
12384 HEXDSP(hx_vdui_t_refresh_view, this, redo_mba);
12385}
12386
12387//--------------------------------------------------------------------------
12388inline void vdui_t::refresh_ctext(bool activate)
12389{
12390 HEXDSP(hx_vdui_t_refresh_ctext, this, activate);
12391}
12392
12393//--------------------------------------------------------------------------
12394inline void vdui_t::switch_to(cfuncptr_t f, bool activate)
12395{
12396 HEXDSP(hx_vdui_t_switch_to, this, &f, activate);
12397}
12398
12399//--------------------------------------------------------------------------
12401{
12402 return (cnumber_t *)HEXDSP(hx_vdui_t_get_number, this);
12403}
12404
12405//--------------------------------------------------------------------------
12407{
12408 return (int)(size_t)HEXDSP(hx_vdui_t_get_current_label, this);
12409}
12410
12411//--------------------------------------------------------------------------
12412inline void vdui_t::clear()
12413{
12414 HEXDSP(hx_vdui_t_clear, this);
12415}
12416
12417//--------------------------------------------------------------------------
12419{
12420 return (uchar)(size_t)HEXDSP(hx_vdui_t_refresh_cpos, this, idv) != 0;
12421}
12422
12423//--------------------------------------------------------------------------
12425{
12426 return (uchar)(size_t)HEXDSP(hx_vdui_t_get_current_item, this, idv) != 0;
12427}
12428
12429//--------------------------------------------------------------------------
12431{
12432 return (uchar)(size_t)HEXDSP(hx_vdui_t_ui_rename_lvar, this, v) != 0;
12433}
12434
12435//--------------------------------------------------------------------------
12436inline bool vdui_t::rename_lvar(lvar_t *v, const char *name, bool is_user_name)
12437{
12438 return (uchar)(size_t)HEXDSP(hx_vdui_t_rename_lvar, this, v, name, is_user_name) != 0;
12439}
12440
12441//--------------------------------------------------------------------------
12443{
12444 return (uchar)(size_t)HEXDSP(hx_vdui_t_ui_set_call_type, this, e) != 0;
12445}
12446
12447//--------------------------------------------------------------------------
12449{
12450 return (uchar)(size_t)HEXDSP(hx_vdui_t_ui_set_lvar_type, this, v) != 0;
12451}
12452
12453//--------------------------------------------------------------------------
12454inline bool vdui_t::set_lvar_type(lvar_t *v, const tinfo_t &type)
12455{
12456 return (uchar)(size_t)HEXDSP(hx_vdui_t_set_lvar_type, this, v, &type) != 0;
12457}
12458
12459//--------------------------------------------------------------------------
12461{
12462 return (uchar)(size_t)HEXDSP(hx_vdui_t_set_noptr_lvar, this, v) != 0;
12463}
12464
12465//--------------------------------------------------------------------------
12467{
12468 return (uchar)(size_t)HEXDSP(hx_vdui_t_ui_edit_lvar_cmt, this, v) != 0;
12469}
12470
12471//--------------------------------------------------------------------------
12472inline bool vdui_t::set_lvar_cmt(lvar_t *v, const char *cmt)
12473{
12474 return (uchar)(size_t)HEXDSP(hx_vdui_t_set_lvar_cmt, this, v, cmt) != 0;
12475}
12476
12477//--------------------------------------------------------------------------
12479{
12480 return (uchar)(size_t)HEXDSP(hx_vdui_t_ui_map_lvar, this, v) != 0;
12481}
12482
12483//--------------------------------------------------------------------------
12485{
12486 return (uchar)(size_t)HEXDSP(hx_vdui_t_ui_unmap_lvar, this, v) != 0;
12487}
12488
12489//--------------------------------------------------------------------------
12490inline bool vdui_t::map_lvar(lvar_t *from, lvar_t *to)
12491{
12492 return (uchar)(size_t)HEXDSP(hx_vdui_t_map_lvar, this, from, to) != 0;
12493}
12494
12495//--------------------------------------------------------------------------
12496inline bool vdui_t::set_strmem_type(struc_t *sptr, member_t *mptr)
12497{
12498 return (uchar)(size_t)HEXDSP(hx_vdui_t_set_strmem_type, this, sptr, mptr) != 0;
12499}
12500
12501//--------------------------------------------------------------------------
12502inline bool vdui_t::set_udm_type(tinfo_t &udt_type, int udm_idx)
12503{
12504 return (uchar)(size_t)HEXDSP(hx_vdui_t_set_udm_type, this, &udt_type, udm_idx) != 0;
12505}
12506
12507//--------------------------------------------------------------------------
12508inline bool vdui_t::rename_strmem(struc_t *sptr, member_t *mptr)
12509{
12510 return (uchar)(size_t)HEXDSP(hx_vdui_t_rename_strmem, this, sptr, mptr) != 0;
12511}
12512
12513//--------------------------------------------------------------------------
12514inline bool vdui_t::rename_udm(tinfo_t &udt_type, int udm_idx)
12515{
12516 return (uchar)(size_t)HEXDSP(hx_vdui_t_rename_udm, this, &udt_type, udm_idx) != 0;
12517}
12518
12519//--------------------------------------------------------------------------
12520inline bool vdui_t::set_global_type(ea_t ea)
12521{
12522 return (uchar)(size_t)HEXDSP(hx_vdui_t_set_global_type, this, ea) != 0;
12523}
12524
12525//--------------------------------------------------------------------------
12526inline bool vdui_t::rename_global(ea_t ea)
12527{
12528 return (uchar)(size_t)HEXDSP(hx_vdui_t_rename_global, this, ea) != 0;
12529}
12530
12531//--------------------------------------------------------------------------
12532inline bool vdui_t::rename_label(int label)
12533{
12534 return (uchar)(size_t)HEXDSP(hx_vdui_t_rename_label, this, label) != 0;
12535}
12536
12537//--------------------------------------------------------------------------
12538inline bool vdui_t::jump_enter(input_device_t idv, int omflags)
12539{
12540 return (uchar)(size_t)HEXDSP(hx_vdui_t_jump_enter, this, idv, omflags) != 0;
12541}
12542
12543//--------------------------------------------------------------------------
12545{
12546 return (uchar)(size_t)HEXDSP(hx_vdui_t_ctree_to_disasm, this) != 0;
12547}
12548
12549//--------------------------------------------------------------------------
12550inline cmt_type_t vdui_t::calc_cmt_type(size_t lnnum, cmt_type_t cmttype) const
12551{
12552 return (cmt_type_t)(size_t)HEXDSP(hx_vdui_t_calc_cmt_type, this, lnnum, cmttype);
12553}
12554
12555//--------------------------------------------------------------------------
12556inline bool vdui_t::edit_cmt(const treeloc_t &loc)
12557{
12558 return (uchar)(size_t)HEXDSP(hx_vdui_t_edit_cmt, this, &loc) != 0;
12559}
12560
12561//--------------------------------------------------------------------------
12563{
12564 return (uchar)(size_t)HEXDSP(hx_vdui_t_edit_func_cmt, this) != 0;
12565}
12566
12567//--------------------------------------------------------------------------
12569{
12570 return (uchar)(size_t)HEXDSP(hx_vdui_t_del_orphan_cmts, this) != 0;
12571}
12572
12573//--------------------------------------------------------------------------
12574inline bool vdui_t::set_num_radix(int base)
12575{
12576 return (uchar)(size_t)HEXDSP(hx_vdui_t_set_num_radix, this, base) != 0;
12577}
12578
12579//--------------------------------------------------------------------------
12581{
12582 return (uchar)(size_t)HEXDSP(hx_vdui_t_set_num_enum, this) != 0;
12583}
12584
12585//--------------------------------------------------------------------------
12587{
12588 return (uchar)(size_t)HEXDSP(hx_vdui_t_set_num_stroff, this) != 0;
12589}
12590
12591//--------------------------------------------------------------------------
12593{
12594 return (uchar)(size_t)HEXDSP(hx_vdui_t_invert_sign, this) != 0;
12595}
12596
12597//--------------------------------------------------------------------------
12599{
12600 return (uchar)(size_t)HEXDSP(hx_vdui_t_invert_bits, this) != 0;
12601}
12602
12603//--------------------------------------------------------------------------
12604inline bool vdui_t::collapse_item(bool hide)
12605{
12606 return (uchar)(size_t)HEXDSP(hx_vdui_t_collapse_item, this, hide) != 0;
12607}
12608
12609//--------------------------------------------------------------------------
12610inline bool vdui_t::collapse_lvars(bool hide)
12611{
12612 return (uchar)(size_t)HEXDSP(hx_vdui_t_collapse_lvars, this, hide) != 0;
12613}
12614
12615//--------------------------------------------------------------------------
12616inline bool vdui_t::split_item(bool split)
12617{
12618 return (uchar)(size_t)HEXDSP(hx_vdui_t_split_item, this, split) != 0;
12619}
12620
12621//--------------------------------------------------------------------------
12622inline int select_udt_by_offset(const qvector<tinfo_t> *udts, const ui_stroff_ops_t &ops, ui_stroff_applicator_t &applicator)
12623{
12624 return (int)(size_t)HEXDSP(hx_select_udt_by_offset, udts, &ops, &applicator);
12625}
12626
12627#ifdef __NT__
12628#pragma warning(pop)
12629#endif
12630#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:3380
const chain_t * get_stk_chain(sval_t off, int width=1) const
Get chain for the specified stack offset.
Definition: hexrays.hpp:3394
const chain_t * get_reg_chain(mreg_t reg, int width=1) const
Get chain for the specified register.
Definition: hexrays.hpp:3386
const chain_t * get_chain(const voff_t &k, int width=1) const
Get chain for the specified value offset.
Definition: hexrays.hpp:3402
Convenience class to release graph chains automatically.
Definition: hexrays.hpp:5032
ud (use->def) and du (def->use) chain.
Definition: hexrays.hpp:3306
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:10861
int width
size of the value in bytes
Definition: hexrays.hpp:3311
uchar flags
combination Chain properties bits
Definition: hexrays.hpp:3313
int varnum
allocated variable index (-1 - not allocated yet)
Definition: hexrays.hpp:3312
Helper class to generate the initial microcode.
Definition: hexrays.hpp:5163
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:5249
virtual merror_t prepare_gen_micro()
Setup internal data to handle new instruction.
Definition: hexrays.hpp:5210
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:11493
virtual void microgen_completed()
This method is called when the microcode generation is done.
Definition: hexrays.hpp:5201
void release()
Unlock the chains.
Definition: hexrays.hpp:10891
bool is_locked() const
Are the chains locked? It is a good idea to lock the chains before using them.
Definition: hexrays.hpp:3451
int for_all_chains(chain_visitor_t &cv, int gca_flags)
Visit all chains.
Definition: hexrays.hpp:10885
void acquire()
Lock the chains.
Definition: hexrays.hpp:3453
Definition of a local variable (register or stack) #var #lvar.
Definition: hexrays.hpp:1163
bool is_spoiled_var() const
Is spoiled var? (meaningful only during lvar allocation)
Definition: hexrays.hpp:1254
bool is_arg_var() const
Is the function argument?
Definition: hexrays.hpp:1244
bool typed() const
Has the variable a type?
Definition: hexrays.hpp:1224
tinfo_t tif
variable type
Definition: hexrays.hpp:1207
bool is_partialy_typed() const
Variable type should be handled as a partial one.
Definition: hexrays.hpp:1256
bool is_shared() const
Is lvar mapped to several chains.
Definition: hexrays.hpp:1280
bool is_aliasable(const mba_t *mba) const
Is the variable aliasable?
Definition: hexrays.hpp:1384
qstring cmt
variable comment string
Definition: hexrays.hpp:1206
void append_list(const mba_t *mba, mlist_t *lst, bool pad_if_scattered=false) const
Append local variable to mlist.
Definition: hexrays.hpp:10060
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:10048
bool is_promoted_arg() const
Is the promoted function argument?
Definition: hexrays.hpp:10036
bool is_automapped() const
Was the variable automatically mapped to another variable?
Definition: hexrays.hpp:1274
bool has_common_bit(const vdloc_t &loc, asize_t width2) const
Does the variable overlap with the specified location?
Definition: hexrays.hpp:1333
bool has_regname() const
Has a register name? (like _RAX)
Definition: hexrays.hpp:1266
bool mreg_done() const
Have corresponding microregs been replaced by references to this variable?
Definition: hexrays.hpp:1226
bool is_used_byref() const
Was the address of the variable taken?
Definition: hexrays.hpp:1276
bool has_common(const lvar_t &v) const
Do variables overlap?
Definition: hexrays.hpp:1328
bool used() const
Is the variable used in the code?
Definition: hexrays.hpp:1222
bool has_user_type() const
Has user-defined type?
Definition: hexrays.hpp:1240
bool is_decl_unused() const
Was declared as __unused by the user? See CVAR_UNUSED.
Definition: hexrays.hpp:1278
bool is_fake_var() const
Is fake return variable?
Definition: hexrays.hpp:1248
qstring name
variable name.
Definition: hexrays.hpp:1203
bool set_width(int w, int svw_flags=0)
Change the variable width.
Definition: hexrays.hpp:10054
bool is_dummy_arg() const
Is a dummy argument (added to fill a hole in the argument list)
Definition: hexrays.hpp:1270
bool is_unknown_width() const
Do we know the width of the variable?
Definition: hexrays.hpp:1230
bool in_asm() const
Is variable used in an instruction translated into __asm?
Definition: hexrays.hpp:1268
bool is_overlapped_var() const
Is overlapped variable?
Definition: hexrays.hpp:1250
bool accepts_type(const tinfo_t &t, bool may_change_thisarg=false)
Check if the variable accept the specified type.
Definition: hexrays.hpp:10042
bool has_user_name() const
Has user-defined name?
Definition: hexrays.hpp:1238
bool has_user_info() const
Has any user-defined information?
Definition: hexrays.hpp:1232
bool is_floating_var() const
Used by a fpu insn?
Definition: hexrays.hpp:1252
bool is_notarg() const
Is a local variable? (local variable cannot be an input argument)
Definition: hexrays.hpp:1272
bool has_nice_name() const
Does the variable have a nice name?
Definition: hexrays.hpp:1228
bool is_thisarg() const
Is 'this' argument of a C++ member function?
Definition: hexrays.hpp:1262
bool is_result_var() const
Is the function result?
Definition: hexrays.hpp:1242
bool is_split_var() const
Is a split variable?
Definition: hexrays.hpp:1264
int width
variable size in bytes
Definition: hexrays.hpp:1208
bool is_noptr_var() const
Variable type should not be a pointer.
Definition: hexrays.hpp:1258
const tinfo_t & type() const
Get variable type.
Definition: hexrays.hpp:1338
bool is_mapdst_var() const
Other variable(s) map to this var?
Definition: hexrays.hpp:1260
void set_final_lvar_type(const tinfo_t &t)
Set final variable type.
Definition: hexrays.hpp:1357
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:11375
mblock_t * copy_block(mblock_t *blk, int new_serial, int cpblk_flags=3)
Make a copy of a block.
Definition: hexrays.hpp:11357
void dump() const
Dump microcode to a file.
Definition: hexrays.hpp:11315
mreg_t alloc_kreg(size_t size, bool check_size=true)
Allocate a kernel register.
Definition: hexrays.hpp:11451
mbl_graph_t * get_graph()
Get control graph.
Definition: hexrays.hpp:11291
ea_t map_fict_ea(ea_t fict_ea) const
Resolve a fictional address.
Definition: hexrays.hpp:11425
bool remove_empty_and_unreachable_blocks()
Delete all empty and unreachable blocks.
Definition: hexrays.hpp:11363
ea_t alloc_fict_ea(ea_t real_ea)
Allocate a fictional address.
Definition: hexrays.hpp:11417
merror_t optimize_global()
Optimize microcode globally.
Definition: hexrays.hpp:11303
mlist_t spoiled_list
MBA_SPLINFO && !final_type: info in vd format.
Definition: hexrays.hpp:4707
int for_all_topinsns(minsn_visitor_t &mv)
Visit all top level instructions.
Definition: hexrays.hpp:11387
lvars_t vars
local variables
Definition: hexrays.hpp:4716
reginfovec_t idb_spoiled
MBA_SPLINFO && final_type: info in ida format.
Definition: hexrays.hpp:4706
ivl_with_name_t std_ivls[6]
we treat memory as consisting of 6 parts see memreg_index_t
Definition: hexrays.hpp:4727
void get_func_output_lists(mlist_t *return_regs, mlist_t *spoiled, const tinfo_t &type, ea_t call_ea=BADADDR, bool tail_call=false)
Prepare the lists of registers & memory that are defined/killed by a function.
Definition: hexrays.hpp:11405
sval_t fullsize
Full stack size including incoming args.
Definition: hexrays.hpp:4680
int optimize_local(int locopt_bits)
Optimize each basic block locally.
Definition: hexrays.hpp:11279
void alloc_lvars()
Allocate local variables.
Definition: hexrays.hpp:11309
void free_kreg(mreg_t reg, size_t size)
Free a kernel register.
Definition: hexrays.hpp:11457
void print(vd_printer_t &vp) const
Print microcode to any destination.
Definition: hexrays.hpp:11327
qstring label
name of the function or pattern (colored)
Definition: hexrays.hpp:4715
rlist_t consumed_argregs
registers converted into stack arguments, should not be used as arguments
Definition: hexrays.hpp:4699
void save_snapshot(const char *description)
Create and save microcode snapshot.
Definition: hexrays.hpp:11445
const ivl_t & get_std_region(memreg_index_t idx) const
Get information about various memory regions.
Definition: hexrays.hpp:5335
bool remove_block(mblock_t *blk)
Delete a block.
Definition: hexrays.hpp:11351
tinfo_t idb_type
function type as retrieved from the database
Definition: hexrays.hpp:4705
merror_t build_graph()
Build control flow graph.
Definition: hexrays.hpp:11285
bool combine_blocks()
Combine blocks.
Definition: hexrays.hpp:11369
void mark_chains_dirty()
Mark the microcode use-def chains dirty.
Definition: hexrays.hpp:11339
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:11399
intvec_t argidx
input arguments (indexes into 'vars')
Definition: hexrays.hpp:4717
bool set_maturity(mba_maturity_t mat)
Set maturity level.
Definition: hexrays.hpp:11273
static WARN_UNUSED_RESULT mba_t * deserialize(const uchar *bytes, size_t nbytes)
Deserialize a byte sequence into mbl array.
Definition: hexrays.hpp:11439
void verify(bool always) const
Verify microcode consistency.
Definition: hexrays.hpp:11333
int for_all_insns(minsn_visitor_t &mv)
Visit all instructions.
Definition: hexrays.hpp:11381
netnode deprecated_idb_node
netnode with additional decompiler info.
Definition: hexrays.hpp:4710
int analyze_calls(int acflags)
Analyze calls and determine calling conventions.
Definition: hexrays.hpp:11297
const mblock_t * get_mblock(int n) const
Get basic block by its serial number.
Definition: hexrays.hpp:4856
mblock_t * insert_block(int bblk)
Insert a block in the middle of the mbl array.
Definition: hexrays.hpp:11345
void serialize(bytevec_t &vout) const
Serialize mbl array into a sequence of bytes.
Definition: hexrays.hpp:11433
mlist_t nodel_memory
global dead elimination may not delete references to this area
Definition: hexrays.hpp:4698
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:11393
ivlset_t gotoff_stkvars
stkvars that hold .got offsets. considered to be unaliasable
Definition: hexrays.hpp:4695
lvar_t & arg(int n)
Get input argument of the decompiled function.
Definition: hexrays.hpp:11411
Control flow graph of microcode.
Definition: hexrays.hpp:5063
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:5120
graph_chains_t * get_ud(gctype_t gctype)
Get use-def chains.
Definition: hexrays.hpp:11475
graph_chains_t * get_du(gctype_t gctype)
Get def-use chains.
Definition: hexrays.hpp:11481
bool is_ud_chain_dirty(gctype_t gctype)
Is the use-def chain of the specified kind dirty?
Definition: hexrays.hpp:5099
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:5124
bool is_du_chain_dirty(gctype_t gctype)
Is the def-use chain of the specified kind dirty?
Definition: hexrays.hpp:5106
Microcode of one basic block.
Definition: hexrays.hpp:3805
ea_t end
end address note: we cannot rely on start/end addresses very much because instructions are propagated...
Definition: hexrays.hpp:3836
mlist_t dnu
data that is defined but not used in the block
Definition: hexrays.hpp:3851
sval_t minbargref
the same for arguments
Definition: hexrays.hpp:3857
minsn_t * head
pointer to the first instruction of the block
Definition: hexrays.hpp:3840
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:11137
minsn_t * tail
pointer to the last instruction of the block
Definition: hexrays.hpp:3841
minsn_t * insert_into_block(minsn_t *nm, minsn_t *om)
Insert instruction into the doubly linked list.
Definition: hexrays.hpp:11083
mblock_type_t type
block type (BLT_NONE - not computed yet)
Definition: hexrays.hpp:3844
int serial
block number
Definition: hexrays.hpp:3843
intvec_t succset
control flow graph: list of our successors use nsucc() and succ() to access it
Definition: hexrays.hpp:3861
void print(vd_printer_t &vp) const
Print block contents.
Definition: hexrays.hpp:11065
void dump() const
Dump block info.
Definition: hexrays.hpp:11071
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:11171
int optimize_insn(minsn_t *m, int optflags=OPTI_MINSTKREF|OPTI_COMBINSNS)
Optimize one instruction in the context of the block.
Definition: hexrays.hpp:11113
int for_all_ops(mop_visitor_t &mv)
Visit all operands.
Definition: hexrays.hpp:11101
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:4067
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:11165
mblock_t * prevb
previous block in the doubly linked list
Definition: hexrays.hpp:3811
mlist_t mustbuse
data that must be used by the block
Definition: hexrays.hpp:3847
intvec_t predset
control flow graph: list of our predecessors use npred() and pred() to access it
Definition: hexrays.hpp:3859
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:11183
mlist_t maybuse
data that may be used by the block
Definition: hexrays.hpp:3848
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:11177
mlist_t build_def_list(const minsn_t &ins, maymust_t maymust) const
Build def-list of an instruction.
Definition: hexrays.hpp:11157
mlist_t maybdef
data that may be defined by the block
Definition: hexrays.hpp:3850
int npred() const
Get number of block predecessors.
Definition: hexrays.hpp:3881
mlist_t dead_at_start
data that is dead at the block entry
Definition: hexrays.hpp:3846
int optimize_useless_jump()
Remove a jump at the end of the block if it is useless.
Definition: hexrays.hpp:11131
bool get_valranges(valrng_t *res, const vivl_t &vivl, int vrflags) const
Find possible values for a block.
Definition: hexrays.hpp:11189
mlist_t mustbdef
data that must be defined by the block
Definition: hexrays.hpp:3849
int for_all_insns(minsn_visitor_t &mv)
Visit all instructions.
Definition: hexrays.hpp:11095
sval_t maxbsp
maximal sp value in the block (0...stacksize)
Definition: hexrays.hpp:3853
uint32 flags
combination of Basic block properties bits
Definition: hexrays.hpp:3812
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:4097
void append_def_list(mlist_t *list, const mop_t &op, maymust_t maymust) const
Append def-list of an operand.
Definition: hexrays.hpp:11143
int nsucc() const
Get number of block successors.
Definition: hexrays.hpp:3883
void make_nop(minsn_t *m)
Erase the instruction (convert it to nop) and mark the lists dirty.
Definition: hexrays.hpp:4220
int optimize_block()
Optimize a basic block.
Definition: hexrays.hpp:11119
sval_t minbstkref
lowest stack location accessible with indirect addressing (offset from the stack bottom) initially it...
Definition: hexrays.hpp:3854
mba_t * mba
the parent micro block array
Definition: hexrays.hpp:3842
minsn_t * remove_from_block(minsn_t *m)
Remove instruction from the doubly linked list.
Definition: hexrays.hpp:11089
mblock_t * nextb
next block in the doubly linked list
Definition: hexrays.hpp:3810
int build_lists(bool kill_deads)
Build def-use lists and eliminate deads.
Definition: hexrays.hpp:11125
mlist_t build_use_list(const minsn_t &ins, maymust_t maymust) const
Build use-list of an instruction.
Definition: hexrays.hpp:11149
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:11107
size_t get_reginsn_qty() const
Calculate number of regular instructions in the block.
Definition: hexrays.hpp:11201
A call argument.
Definition: hexrays.hpp:3011
tinfo_t type
formal argument type
Definition: hexrays.hpp:3015
argloc_t argloc
ida argloc
Definition: hexrays.hpp:3017
qstring name
formal argument name
Definition: hexrays.hpp:3016
Information about a call.
Definition: hexrays.hpp:3126
mcallargs_t args
call arguments
Definition: hexrays.hpp:3134
mlist_t return_regs
list of values returned by the function
Definition: hexrays.hpp:3140
ivlset_t visible_memory
what memory is visible to the call?
Definition: hexrays.hpp:3144
mlist_t spoiled
list of spoiled locations (includes return_regs)
Definition: hexrays.hpp:3141
ea_t callee
address of the called function, if known
Definition: hexrays.hpp:3128
type_attrs_t fti_attrs
extended function attributes
Definition: hexrays.hpp:3171
mlist_t dead_regs
registers defined by the function but never used.
Definition: hexrays.hpp:3145
mopvec_t retregs
return register(s) (e.g., AX, AX:DX, etc.) this vector is built from return_regs
Definition: hexrays.hpp:3135
funcrole_t role
function role
Definition: hexrays.hpp:3170
tinfo_t return_type
type of the returned value
Definition: hexrays.hpp:3137
argloc_t return_argloc
location of the returned value
Definition: hexrays.hpp:3138
int solid_args
number of solid args.
Definition: hexrays.hpp:3129
mlist_t pass_regs
passthrough registers: registers that depend on input values (subset of spoiled)
Definition: hexrays.hpp:3142
List of switch cases and targets.
Definition: hexrays.hpp:3188
casevec_t values
expression values for each target
Definition: hexrays.hpp:3190
intvec_t targets
target block numbers
Definition: hexrays.hpp:3191
Microinstruction class #insn.
Definition: hexrays.hpp:3465
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:10939
mop_t r
right operand
Definition: hexrays.hpp:3475
minsn_t * prev
prev insn in doubly linked list. check also previ()
Definition: hexrays.hpp:3472
bool is_noret_call(int flags=0)
Is a non-returing call?
Definition: hexrays.hpp:10975
bool may_use_aliased_memory() const
Is it possible for the instruction to use aliased memory?
Definition: hexrays.hpp:11029
bool contains_opcode(mcode_t mcode) const
Does the instruction have the specified opcode? This function searches subinstructions as well.
Definition: hexrays.hpp:3715
minsn_t * next
next insn in doubly linked list. check also nexti()
Definition: hexrays.hpp:3471
bool contains_call(bool with_helpers=false) const
Does the instruction contain a call?
Definition: hexrays.hpp:3693
int for_all_insns(minsn_visitor_t &mv)
Visit all instructions.
Definition: hexrays.hpp:10951
bool has_side_effects(bool include_ldx_and_divs=false) const
Does the instruction have a side effect?
Definition: hexrays.hpp:10993
funcrole_t get_role() const
Get the function role of a call.
Definition: hexrays.hpp:3702
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:11005
void setaddr(ea_t new_ea)
Change the instruction address.
Definition: hexrays.hpp:10933
ea_t ea
instruction address
Definition: hexrays.hpp:3473
void print(qstring *vout, int shins_flags=SHINS_SHORT|SHINS_VALNUM) const
Generate insn text into the buffer.
Definition: hexrays.hpp:10921
bool modifies_d() const
Does the instruction modify its 'd' operand? Some instructions (e.g.
Definition: hexrays.hpp:11017
minsn_t(ea_t _ea)
Constructor.
Definition: hexrays.hpp:3580
mop_t l
left operand
Definition: hexrays.hpp:3474
int optimize_solo(int optflags=0)
Optimize one instruction without context.
Definition: hexrays.hpp:3609
bool is_between(const minsn_t *m1, const minsn_t *m2) const
Is the instruction in the specified range of instructions?
Definition: hexrays.hpp:11023
const mop_t * find_num_op(const mop_t **other) const
Find a numeric operand of the current instruction.
Definition: hexrays.hpp:11011
int for_all_ops(mop_visitor_t &mv)
Visit all instruction operands.
Definition: hexrays.hpp:10945
bool is_after(const minsn_t *m) const
Is the instruction after the specified one?
Definition: hexrays.hpp:3756
void swap(minsn_t &m)
Swap two instructions.
Definition: hexrays.hpp:10915
int serialize(bytevec_t *b) const
Serialize an instruction.
Definition: hexrays.hpp:11035
mop_t d
destination operand
Definition: hexrays.hpp:3476
bool is_unknown_call() const
Is an unknown call? Unknown calls are calls without the argument list (mcallinfo_t).
Definition: hexrays.hpp:3679
minsn_t * find_call(bool with_helpers=false) const
Find a call instruction.
Definition: hexrays.hpp:10987
bool equal_insns(const minsn_t &m, int eqflags) const
Compare instructions.
Definition: hexrays.hpp:10963
const minsn_t * find_opcode(mcode_t mcode) const
Find a (sub)insruction with the specified opcode.
Definition: hexrays.hpp:3719
const char * dstr() const
Get displayable text without tags in a static buffer.
Definition: hexrays.hpp:10927
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:10981
void _make_nop()
Convert instruction to nop.
Definition: hexrays.hpp:10957
mcode_t opcode
instruction opcode
Definition: hexrays.hpp:3469
bool deserialize(const uchar *bytes, size_t nbytes, int format_version)
Deserialize an instruction.
Definition: hexrays.hpp:11041
int iprops
combination of instruction property bits bits
Definition: hexrays.hpp:3470
Address of an operand (mop_l, mop_v, mop_S, mop_r)
Definition: hexrays.hpp:2981
Pair of operands.
Definition: hexrays.hpp:2972
mop_t lop
low operand
Definition: hexrays.hpp:2974
mop_t hop
high operand
Definition: hexrays.hpp:2975
A microinstruction operand.
Definition: hexrays.hpp:2441
void _make_gvar(ea_t ea)
Create a global variable operand without erasing previous data.
Definition: hexrays.hpp:10617
member_t * get_stkvar(uval_t *p_off) const
Retrieve the referenced stack variable.
Definition: hexrays.hpp:2872
bool has_side_effects(bool include_ldx_and_divs=false) const
Has any side effects?
Definition: hexrays.hpp:5280
uint8 oprops
Operand properties.
Definition: hexrays.hpp:2448
bool is_insn() const
Is a sub-instruction?
Definition: hexrays.hpp:2754
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:10683
bool is_constant(uint64 *out=nullptr, bool is_signed=true) const
Retrieve value of a constant integer operand.
Definition: hexrays.hpp:10695
bool is_zero_extended_from(int nbytes) const
Does the high part of the operand consist of zero bytes?
Definition: hexrays.hpp:10665
mopt_t t
Operand type.
Definition: hexrays.hpp:2445
bool is_reg() const
Is a register operand? See also get_mreg_name()
Definition: hexrays.hpp:2728
void create_from_insn(const minsn_t *m)
Create operand from an instruction.
Definition: hexrays.hpp:10599
bool create_from_mlist(mba_t *mba, const mlist_t &lst, sval_t fullsize)
Create operand from mlist_t.
Definition: hexrays.hpp:10575
void make_reg_pair(int loreg, int hireg, int halfsize)
Create pair of registers.
Definition: hexrays.hpp:10629
bool get_stkoff(sval_t *p_off) const
Get the referenced stack offset.
Definition: hexrays.hpp:10701
bool is_mob(int serial) const
Is a block reference to the specified block?
Definition: hexrays.hpp:2744
void _make_lvar(mba_t *mba, int idx, sval_t off=0)
Create a local variable operand.
Definition: hexrays.hpp:2624
bool make_low_half(int width)
Make the low part of the operand.
Definition: hexrays.hpp:10707
uint16 valnum
Value number.
Definition: hexrays.hpp:2461
void _make_blkref(int blknum)
Create a block reference operand without erasing previous data.
Definition: hexrays.hpp:2669
int size
Operand size.
Definition: hexrays.hpp:2465
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:10743
bool equal_mops(const mop_t &rop, int eqflags) const
Compare operands.
Definition: hexrays.hpp:10671
bool change_size(int nsize, side_effect_t sideff=WITH_SIDEFF)
Change the operand size.
Definition: hexrays.hpp:10737
bool is_reg(mreg_t _r) const
Is the specified register?
Definition: hexrays.hpp:2730
const minsn_t * get_insn(mcode_t code) const
Get subinstruction of the operand.
Definition: hexrays.hpp:5294
bool make_fpnum(const void *bytes, size_t _size)
Create a floating point constant operand.
Definition: hexrays.hpp:10611
void _make_cases(mcases_t *_cases)
Create a 'switch cases' operand without erasing previous data.
Definition: hexrays.hpp:2707
void make_insn(minsn_t *ins)
Create a nested instruction.
Definition: hexrays.hpp:2663
void make_number(uint64 _value, int _size, ea_t _ea=BADADDR, int opnum=0)
Create an integer constant operand.
Definition: hexrays.hpp:10605
bool is_arglist() const
Is a list of arguments?
Definition: hexrays.hpp:2734
bool make_first_half(int width)
Make the first part of the operand.
Definition: hexrays.hpp:10719
bool is_sign_extended_from(int nbytes) const
Does the high part of the operand consist of the sign bytes?
Definition: hexrays.hpp:10659
bool make_high_half(int width)
Make the high part of the operand.
Definition: hexrays.hpp:10713
uint64 value(bool is_signed) const
Retrieve value of a constant integer operand.
Definition: hexrays.hpp:2834
bool is_glbaddr() const
Is address of a global memory cell?
Definition: hexrays.hpp:5304
void _make_reg(mreg_t reg)
Create a register operand without erasing previous data.
Definition: hexrays.hpp:2603
bool is_scattered() const
Is a scattered operand?
Definition: hexrays.hpp:2746
void _make_insn(minsn_t *ins)
Create a nested instruction without erasing previous data.
Definition: hexrays.hpp:5274
void _make_strlit(const char *str)
Create a constant string operand.
Definition: hexrays.hpp:2683
bool is_kreg() const
Is a kernel register?
Definition: hexrays.hpp:5285
bool is_cc() const
Is a condition code?
Definition: hexrays.hpp:2736
bool is_reg(mreg_t _r, int _size) const
Is the specified register of the specified size?
Definition: hexrays.hpp:2732
int for_all_scattered_submops(scif_visitor_t &sv) const
Visit all sub-operands of a scattered operand.
Definition: hexrays.hpp:10689
static bool is_bit_reg(mreg_t reg)
Is a bit register? This includes condition codes and eventually other bit registers.
Definition: hexrays.hpp:10641
bool create_from_ivlset(mba_t *mba, const ivlset_t &ivs, sval_t fullsize)
Create operand from ivlset_t.
Definition: hexrays.hpp:10581
void make_reg(mreg_t reg)
Create a register operand.
Definition: hexrays.hpp:2615
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:2783
bool shift_mop(int offset)
Shift the operand.
Definition: hexrays.hpp:10731
void _make_stkvar(mba_t *mba, sval_t off)
Create a stack variable operand.
Definition: hexrays.hpp:2643
bool is_stkaddr() const
Is address of a stack variable?
Definition: hexrays.hpp:5314
bool is01() const
Are the possible values of the operand only 0 and 1? This function returns true for 0/1 constants,...
Definition: hexrays.hpp:10653
void make_helper(const char *name)
Create a helper operand.
Definition: hexrays.hpp:10635
void create_from_vdloc(mba_t *mba, const vdloc_t &loc, int _size)
Create operand from vdloc_t.
Definition: hexrays.hpp:10587
void make_blkref(int blknum)
Create a global variable operand.
Definition: hexrays.hpp:2675
void _make_callinfo(mcallinfo_t *fi)
Create a call info operand without erasing previous data.
Definition: hexrays.hpp:2698
bool make_second_half(int width)
Make the second part of the operand.
Definition: hexrays.hpp:10725
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:10593
void apply_ld_mcode(mcode_t mcode, ea_t ea, int newsize)
Apply a unary opcode to the operand.
Definition: hexrays.hpp:10749
void make_gvar(ea_t ea)
Create a global variable operand.
Definition: hexrays.hpp:10623
void _make_pair(mop_pair_t *_pair)
Create a pair operand without erasing previous data.
Definition: hexrays.hpp:2716
bool may_use_aliased_memory() const
Is it possible for the operand to use aliased memory?
Definition: hexrays.hpp:10647
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
void cleanup()
Cleanup the filter This function properly clears type information associated to this filter.
Definition: hexrays.hpp:10145
virtual merror_t apply(codegen_t &cdg) override
generate microcode for an instruction
Definition: hexrays.hpp:10157
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
#define CHF_REPLACED
chain operands have been replaced?
Definition: hexrays.hpp:3317
#define CHF_OVER
overlapped chain
Definition: hexrays.hpp:3318
#define CHF_FAKE
fake chain created by widen_chains()
Definition: hexrays.hpp:3319
#define CHF_INITED
is chain initialized? (valid only after lvar allocation)
Definition: hexrays.hpp:3316
#define CHF_PASSTHRU
pass-thru chain, must use the input variable to the block
Definition: hexrays.hpp:3320
#define CHF_TERM
terminating chain; the variable does not survive across the block
Definition: hexrays.hpp:3321
#define CV_RESTART
restart enumeration at the top expr (apply_to_exprs)
Definition: hexrays.hpp:5799
#define CV_PRUNE
this bit is set by visit...() to prune the walk
Definition: hexrays.hpp:5796
#define CV_PARENTS
maintain parent information
Definition: hexrays.hpp:5797
#define CV_POST
call the leave...() functions
Definition: hexrays.hpp:5798
#define CV_INSNS
visit only statements, prune all expressions do not use before the final ctree maturity because expre...
Definition: hexrays.hpp:5800
#define CVAR_FLOAT
used in a fpu insn
Definition: hexrays.hpp:1180
#define CVAR_THISARG
'this' argument of c++ member functions
Definition: hexrays.hpp:1184
#define CVAR_REGNAME
has a register name (like _RAX): if lvar is used by an m_ext instruction
Definition: hexrays.hpp:1187
#define CVAR_BYREF
the address of the variable was taken
Definition: hexrays.hpp:1194
#define CVAR_NAME
has nice name?
Definition: hexrays.hpp:1171
#define CVAR_SHARED
variable is mapped to several chains
Definition: hexrays.hpp:1199
#define CVAR_INASM
variable is used in instructions translated into __asm {...}
Definition: hexrays.hpp:1195
#define CVAR_UTYPE
user-defined type
Definition: hexrays.hpp:1175
#define CVAR_UNUSED
user-defined __unused attribute meaningful only if: is_arg_var() && !mba->final_type
Definition: hexrays.hpp:1197
#define CVAR_MAPDST
other variables are mapped to this var
Definition: hexrays.hpp:1182
#define CVAR_USED
is used in the code?
Definition: hexrays.hpp:1169
#define CVAR_OVER
overlapping variable
Definition: hexrays.hpp:1179
#define CVAR_SPLIT
variable was created by an explicit request otherwise we could reuse an existing var
Definition: hexrays.hpp:1185
#define CVAR_FAKE
fake variable (return var or va_list)
Definition: hexrays.hpp:1178
#define CVAR_RESULT
function result variable
Definition: hexrays.hpp:1176
#define CVAR_ARG
function argument
Definition: hexrays.hpp:1177
#define CVAR_TYPE
the type is defined?
Definition: hexrays.hpp:1170
#define CVAR_AUTOMAP
variable was automatically mapped
Definition: hexrays.hpp:1193
#define CVAR_PARTIAL
variable type is partialy defined
Definition: hexrays.hpp:1183
#define CVAR_MREG
corresponding mregs were replaced?
Definition: hexrays.hpp:1172
#define CVAR_NOWD
width is unknown
Definition: hexrays.hpp:1173
#define CVAR_SPOILED
internal flag, do not use: spoiled var
Definition: hexrays.hpp:1181
#define CVAR_DUMMY
dummy argument (added to fill a hole in the argument list)
Definition: hexrays.hpp:1190
#define CVAR_NOTARG
variable cannot be an input argument
Definition: hexrays.hpp:1192
#define CVAR_NOPTR
variable cannot be a pointer (user choice)
Definition: hexrays.hpp:1189
#define CVAR_UNAME
user-defined name
Definition: hexrays.hpp:1174
#define DECOMP_VOID_MBA
return empty mba object (to be used with gen_microcode)
Definition: hexrays.hpp:7152
#define EXFL_CPADONE
pointer arithmetic correction done
Definition: hexrays.hpp:6153
#define EXFL_CSTR
string literal
Definition: hexrays.hpp:6157
#define EXFL_FPOP
floating point operation
Definition: hexrays.hpp:6155
#define EXFL_LVALUE
expression is lvalue even if it doesn't look like it
Definition: hexrays.hpp:6154
#define EXFL_UNDEF
expression uses undefined value
Definition: hexrays.hpp:6159
#define EXFL_VFTABLE
is ptr to vftable (used for cot_memptr, cot_memref)
Definition: hexrays.hpp:6161
#define EXFL_PARTIAL
type of the expression is considered partial
Definition: hexrays.hpp:6158
#define EXFL_JUMPOUT
jump out-of-function
Definition: hexrays.hpp:6160
#define LVINF_UNUSED
unused argument, corresponds to CVAR_UNUSED
Definition: hexrays.hpp:1446
#define LVINF_SPLIT
split allocation of a new variable.
Definition: hexrays.hpp:1441
#define LVINF_KEEP
preserve saved user settings regardless of vars for example, if a var loses all its user-defined attr...
Definition: hexrays.hpp:1435
#define LVINF_NOMAP
forbid automatic mapping of the variable
Definition: hexrays.hpp:1445
#define LVINF_NOPTR
variable type should not be a pointer
Definition: hexrays.hpp:1444
merror_t
Definition: hexrays.hpp:482
@ MERR_ONLY32
only 32-bit functions can be decompiled for the current database
Definition: hexrays.hpp:508
@ MERR_LICENSE
no license available
Definition: hexrays.hpp:507
@ MERR_CANCELED
decompilation has been cancelled
Definition: hexrays.hpp:502
@ MERR_UNKTYPE
undefined type s (currently unused error code)
Definition: hexrays.hpp:498
@ MERR_BADFRAME
function frame is wrong
Definition: hexrays.hpp:497
@ MERR_BUSY
already decompiling a function
Definition: hexrays.hpp:510
@ MERR_HUGESTACK
stack frame is too big
Definition: hexrays.hpp:493
@ MERR_BADBLK
bad block found
Definition: hexrays.hpp:488
@ MERR_BADIDB
inconsistent database information
Definition: hexrays.hpp:499
@ MERR_CLOUD
cloud: s
Definition: hexrays.hpp:518
@ MERR_EXCEPTION
exception analysis failed
Definition: hexrays.hpp:492
@ MERR_BLOCK
no error, switch to new block
Definition: hexrays.hpp:484
@ MERR_FUNCSIZE
too big function
Definition: hexrays.hpp:513
@ MERR_PARTINIT
partially initialized variable s
Definition: hexrays.hpp:505
@ MERR_BADRANGES
bad input ranges
Definition: hexrays.hpp:514
@ MERR_DSLOT
bad instruction in the delay slot
Definition: hexrays.hpp:516
@ MERR_OK
ok
Definition: hexrays.hpp:483
@ MERR_INSN
cannot convert to microcode
Definition: hexrays.hpp:486
@ MERR_COMPLEX
too complex function
Definition: hexrays.hpp:506
@ MERR_BADARCH
current architecture is not supported
Definition: hexrays.hpp:515
@ MERR_ONLY64
only 64-bit functions can be decompiled for the current database
Definition: hexrays.hpp:509
@ MERR_RECDEPTH
max recursion depth reached during lvar allocation
Definition: hexrays.hpp:503
@ MERR_FARPTR
far memory model is supported only for pc
Definition: hexrays.hpp:511
@ MERR_STOP
no error, stop the analysis
Definition: hexrays.hpp:517
@ MERR_BADCALL
could not determine call arguments
Definition: hexrays.hpp:496
@ MERR_SIZEOF
wrong basic type sizes in compiler settings
Definition: hexrays.hpp:500
@ MERR_EXTERN
special segments cannot be decompiled
Definition: hexrays.hpp:512
@ MERR_BITNESS
16-bit functions cannot be decompiled
Definition: hexrays.hpp:495
@ MERR_LOOP
internal code: redo last loop (never reported)
Definition: hexrays.hpp:520
@ MERR_REDO
redecompilation has been requested
Definition: hexrays.hpp:501
@ MERR_PROLOG
prolog analysis failed
Definition: hexrays.hpp:490
@ MERR_LVARS
local variable allocation failed
Definition: hexrays.hpp:494
@ MERR_INTERR
internal error
Definition: hexrays.hpp:485
@ MERR_OVERLAP
variables would overlap: s
Definition: hexrays.hpp:504
@ MERR_BADSP
positive sp value has been found
Definition: hexrays.hpp:489
@ MERR_SWITCH
wrong switch idiom
Definition: hexrays.hpp:491
@ MERR_MEM
not enough memory
Definition: hexrays.hpp:487
#define MLI_NAME
apply lvar name
Definition: hexrays.hpp:1595
#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:792
#define NF_NEGATE
The user asked to negate the constant.
Definition: hexrays.hpp:790
#define NF_NEGDONE
temporary internal bit: negation has been performed
Definition: hexrays.hpp:788
#define NF_BINVDONE
temporary internal bit: inverting bits is done
Definition: hexrays.hpp:789
#define NF_BITNOT
The user asked to invert bits of the constant.
Definition: hexrays.hpp:791
#define SHINS_VALNUM
display value numbers
Definition: hexrays.hpp:2414
#define SHINS_NUMADDR
display definition addresses for numbers
Definition: hexrays.hpp:2413
#define SHINS_SHORT
do not display use-def chains and other attrs
Definition: hexrays.hpp:2415
#define ULV_PRECISE_DEFEA
Use precise defea's for lvar locations.
Definition: hexrays.hpp:1504
#define VDUI_VISIBLE
is visible?
Definition: hexrays.hpp:7607
#define VDUI_VALID
is valid?
Definition: hexrays.hpp:7608
tinfo_t dummy_ptrtype(int ptrsize, bool isfp)
Generate a dummy pointer type.
Definition: hexrays.hpp:9946
bool get_type(uval_t id, tinfo_t *tif, type_source_t guess)
Get a global type.
Definition: hexrays.hpp:9976
bool get_member_type(const member_t *mptr, tinfo_t *type)
Get type of a structure field.
Definition: hexrays.hpp:9954
bool set_type(uval_t id, const tinfo_t &tif, type_source_t source, bool force=false)
Set a global type.
Definition: hexrays.hpp:9982
bool is_type_correct(const type_t *ptr)
Verify a type string.
Definition: hexrays.hpp:9892
int partial_type_num(const tinfo_t &type)
Calculate number of partial subtypes.
Definition: hexrays.hpp:9916
bool is_small_udt(const tinfo_t &tif)
Is a small structure or union?
Definition: hexrays.hpp:9898
THREAD_SAFE bool is_inplace_def(const tinfo_t &type)
Is struct/union/enum definition (not declaration)?
Definition: hexrays.hpp:959
type_source_t
Type source (where the type information comes from)
Definition: hexrays.hpp:1039
bool is_bool_type(const tinfo_t &type)
Is a boolean type?
Definition: hexrays.hpp:9910
bool is_nonbool_type(const tinfo_t &type)
Is definitely a non-boolean type?
Definition: hexrays.hpp:9904
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:9930
THREAD_SAFE bool is_ptr_or_array(type_t t)
Is a pointer or array type?
Definition: hexrays.hpp:947
tinfo_t create_typedef(const char *name)
Create a reference to a named type.
Definition: hexrays.hpp:9968
const char * dstr(const tinfo_t *tif)
Print the specified type info.
Definition: hexrays.hpp:9886
tinfo_t get_unk_type(int size)
Create a partial type info by width.
Definition: hexrays.hpp:9938
THREAD_SAFE bool is_paf(type_t t)
Is a pointer, array, or function type?
Definition: hexrays.hpp:953
tinfo_t make_pointer(const tinfo_t &type)
Create a pointer type.
Definition: hexrays.hpp:9960
tinfo_t get_float_type(int width)
Get a type of a floating point value with the specified width.
Definition: hexrays.hpp:9922
input_device_t
Type of the input device.
Definition: hexrays.hpp:7543
@ USE_MOUSE
Mouse.
Definition: hexrays.hpp:7545
@ USE_KEYBOARD
Keyboard.
Definition: hexrays.hpp:7544
bool is_break_consumer(ctype_t op)
Does a break statement influence the specified statement code?
Definition: hexrays.hpp:5709
operand_locator_t const & user_numforms_first(user_numforms_iterator_t p)
Get reference to the current map key.
Definition: hexrays.hpp:8624
void udcall_map_free(udcall_map_t *map)
Delete udcall_map_t instance.
Definition: hexrays.hpp:8929
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:12622
#define MBA_PASSREGS
has mcallinfo_t::pass_regs
Definition: hexrays.hpp:4486
#define MBA2_ARGIDX_OK
may verify input argument list?
Definition: hexrays.hpp:4523
cursor_item_type_t
Type of the cursor item.
Definition: hexrays.hpp:6656
@ VDI_FUNC
the function itself (the very first line with the function prototype)
Definition: hexrays.hpp:6660
@ VDI_TAIL
cursor is at (beyond) the line end (commentable line)
Definition: hexrays.hpp:6661
@ VDI_LVAR
declaration of local variable
Definition: hexrays.hpp:6659
@ VDI_NONE
undefined
Definition: hexrays.hpp:6657
@ VDI_EXPR
c-tree item
Definition: hexrays.hpp:6658
boundaries_iterator_t boundaries_end(const boundaries_t *map)
Get iterator pointing to the end of boundaries_t.
Definition: hexrays.hpp:9537
#define MBL_PROP
needs 'propagation' pass
Definition: hexrays.hpp:3824
user_cmts_iterator_t user_cmts_prev(user_cmts_iterator_t p)
Move to the previous element.
Definition: hexrays.hpp:9009
#define IPROP_OPTIONAL
optional instruction
Definition: hexrays.hpp:3481
size_t user_numforms_size(user_numforms_t *map)
Get size of user_numforms_t.
Definition: hexrays.hpp:8704
boundaries_iterator_t boundaries_find(const boundaries_t *map, const cinsn_t *&key)
Find the specified key in boundaries_t.
Definition: hexrays.hpp:9510
void user_cmts_clear(user_cmts_t *map)
Clear user_cmts_t.
Definition: hexrays.hpp:9024
const cmt_type_t CMT_FUNC
Function comment.
Definition: hexrays.hpp:7596
memreg_index_t
< memory region types
Definition: hexrays.hpp:4350
@ MMIDX_SHADOW
stack: shadow arguments
Definition: hexrays.hpp:4354
@ MMIDX_GLBLOW
global memory: low part
Definition: hexrays.hpp:4351
@ MMIDX_GLBHIGH
global memory: high part
Definition: hexrays.hpp:4356
@ MMIDX_ARGS
stack: regular stack arguments
Definition: hexrays.hpp:4355
@ MMIDX_RETADDR
stack: return address
Definition: hexrays.hpp:4353
@ MMIDX_LVARS
stack: local variables
Definition: hexrays.hpp:4352
bool is_unary(ctype_t op)
Is unary operator?
Definition: hexrays.hpp:5644
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:9083
const mopt_t mop_d
result of another instruction
Definition: hexrays.hpp:2259
const cmt_type_t CMT_BLOCK2
Posterior block comment.
Definition: hexrays.hpp:7594
#define MBA2_OVER_CHAINS
has overlapped chains?
Definition: hexrays.hpp:4519
const minsn_t * getb_reginsn(const minsn_t *ins)
Skip assertions backward.
Definition: hexrays.hpp:11053
void user_labels_clear(user_labels_t *map)
Clear user_labels_t.
Definition: hexrays.hpp:9351
bool arglocs_overlap(const vdloc_t &loc1, size_t w1, const vdloc_t &loc2, size_t w2)
Do two arglocs overlap?
Definition: hexrays.hpp:10012
enum hexrays_event_t ENUM_SIZE(int)
Decompiler events.
Definition: hexrays.hpp:7325
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:8992
#define IPROP_WAS_NORET
was noret icall
Definition: hexrays.hpp:3507
#define MBA_SHORT
use short display
Definition: hexrays.hpp:4505
void * hexdsp_t(int code,...)
Hex-Rays decompiler dispatcher.
Definition: hexrays.hpp:7318
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:9808
size_t user_unions_size(user_unions_t *map)
Get size of user_unions_t.
Definition: hexrays.hpp:9249
#define GCO_USE
is source operand?
Definition: hexrays.hpp:5497
#define MBL_INCONST
inconsistent lists: we are building them
Definition: hexrays.hpp:3827
bool is_relational(ctype_t op)
Is comparison operator?
Definition: hexrays.hpp:5646
bool init_hexrays_plugin(int flags=0)
Check that your plugin is compatible with hex-rays decompiler.
Definition: hexrays.hpp:8601
void lvar_mapping_clear(lvar_mapping_t *map)
Clear lvar_mapping_t.
Definition: hexrays.hpp:8806
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:10132
item_preciser_t
Comment item preciser.
Definition: hexrays.hpp:5961
@ ITP_ASM
__asm-line
Definition: hexrays.hpp:5969
@ ITP_CASE
bit for switch cases
Definition: hexrays.hpp:5980
@ ITP_BLOCK2
closing block comment.
Definition: hexrays.hpp:5979
@ ITP_SEMI
semicolon
Definition: hexrays.hpp:5972
@ ITP_CURLY2
}
Definition: hexrays.hpp:5974
@ ITP_SIGN
if this bit is set too, then we have a negative case value
Definition: hexrays.hpp:5981
@ ITP_EMPTY
nothing
Definition: hexrays.hpp:5963
@ ITP_COLON
: (label)
Definition: hexrays.hpp:5976
@ ITP_ELSE
else-line
Definition: hexrays.hpp:5970
@ ITP_DO
do-line
Definition: hexrays.hpp:5971
@ ITP_CURLY1
{
Definition: hexrays.hpp:5973
@ ITP_ARG1
, (64 entries are reserved for 64 call arguments)
Definition: hexrays.hpp:5964
@ ITP_BRACE2
)
Definition: hexrays.hpp:5975
@ ITP_BLOCK1
opening block comment.
Definition: hexrays.hpp:5977
user_unions_iterator_t user_unions_prev(user_unions_iterator_t p)
Move to the previous element.
Definition: hexrays.hpp:9227
int mreg_t
Micro register.
Definition: hexrays.hpp:261
#define ANCHOR_ITP
item type preciser
Definition: hexrays.hpp:6643
#define hexapi
Public functions are marked with this keyword.
Definition: hexrays.hpp:235
bool is_bitop(ctype_t op)
Is bit related operator?
Definition: hexrays.hpp:5685
user_unions_iterator_t user_unions_next(user_unions_iterator_t p)
Move to the next element.
Definition: hexrays.hpp:9219
#define IPROP_SPLIT4
into 4 bytes
Definition: hexrays.hpp:3499
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:8638
void user_cmts_free(user_cmts_t *map)
Delete user_cmts_t instance.
Definition: hexrays.hpp:9038
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:8865
const mopt_t mop_l
local variable
Definition: hexrays.hpp:2264
#define IPROP_PERSIST
persistent insn; they are not destroyed
Definition: hexrays.hpp:3482
user_iflags_iterator_t user_iflags_next(user_iflags_iterator_t p)
Move to the next element.
Definition: hexrays.hpp:9110
void user_iflags_clear(user_iflags_t *map)
Clear user_iflags_t.
Definition: hexrays.hpp:9133
bool has_cached_cfunc(ea_t ea)
Do we have a cached decompilation result for 'ea'?
Definition: hexrays.hpp:12343
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:8883
cexpr_t * lnot(cexpr_t *e)
Logically negate the specified expression.
Definition: hexrays.hpp:12005
#define ANCHOR_CITEM
c-tree item
Definition: hexrays.hpp:6641
bool mark_cfunc_dirty(ea_t ea, bool close_views=false)
Flush the cached decompilation results.
Definition: hexrays.hpp:12331
eamap_iterator_t eamap_prev(eamap_iterator_t p)
Move to the previous element.
Definition: hexrays.hpp:9445
const cmt_type_t CMT_TAIL
Indented comment.
Definition: hexrays.hpp:7592
boundaries_iterator_t boundaries_begin(const boundaries_t *map)
Get iterator pointing to the beginning of boundaries_t.
Definition: hexrays.hpp:9528
bool is_additive(ctype_t op)
Is additive operator?
Definition: hexrays.hpp:5667
vdui_t * open_pseudocode(ea_t ea, int flags)
Open pseudocode window.
Definition: hexrays.hpp:11523
intvec_t & user_unions_second(user_unions_iterator_t p)
Get reference to the current map value.
Definition: hexrays.hpp:9176
int get_mreg_name(qstring *out, mreg_t reg, int width, void *ud=nullptr)
Get the microregister name.
Definition: hexrays.hpp:10471
rangeset_t & boundaries_second(boundaries_iterator_t p)
Get reference to the current map value.
Definition: hexrays.hpp:9503
#define MBA_THUNK
thunk function
Definition: hexrays.hpp:4487
cmt_retrieval_type_t
Comment retrieval type.
Definition: hexrays.hpp:6009
@ RETRIEVE_ALWAYS
Retrieve comment even if it has been used.
Definition: hexrays.hpp:6011
@ RETRIEVE_ONCE
Retrieve comment if it has not been used yet.
Definition: hexrays.hpp:6010
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:10102
size_t user_cmts_size(user_cmts_t *map)
Get size of user_cmts_t.
Definition: hexrays.hpp:9031
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:8656
void print_vdloc(qstring *vout, const vdloc_t &loc, int nbytes)
Print vdloc.
Definition: hexrays.hpp:10006
void user_cmts_erase(user_cmts_t *map, user_cmts_iterator_t p)
Erase current element from user_cmts_t.
Definition: hexrays.hpp:9017
eamap_iterator_t eamap_find(const eamap_t *map, const ea_t &key)
Find the specified key in eamap_t.
Definition: hexrays.hpp:9401
bool op_uses_z(ctype_t op)
Does operator use the 'z' field of cexpr_t?
Definition: hexrays.hpp:5640
qvector< citem_t * > ctree_items_t
Vector of parents.
Definition: hexrays.hpp:5781
void clear_cached_cfuncs()
Flush all cached decompilation results.
Definition: hexrays.hpp:12337
ea_t const & user_unions_first(user_unions_iterator_t p)
Get reference to the current map key.
Definition: hexrays.hpp:9169
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:8774
lvar_locator_t & lvar_mapping_second(lvar_mapping_iterator_t p)
Get reference to the current map value.
Definition: hexrays.hpp:8740
size_t udcall_map_size(udcall_map_t *map)
Get size of udcall_map_t.
Definition: hexrays.hpp:8922
void save_user_iflags(ea_t func_ea, const user_iflags_t *iflags)
Save user defined citem iflags into the database.
Definition: hexrays.hpp:12071
bool accepts_small_udts(ctype_t op)
Is the operator allowed on small structure or union?
Definition: hexrays.hpp:5726
const minsn_t * getf_reginsn(const minsn_t *ins)
Skip assertions forward.
Definition: hexrays.hpp:11047
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:8874
#define MBA2_LVARS_RENAMED
accept empty names now?
Definition: hexrays.hpp:4518
const cmt_type_t CMT_LVAR
Local variable comment.
Definition: hexrays.hpp:7595
user_numforms_iterator_t user_numforms_prev(user_numforms_iterator_t p)
Move to the previous element.
Definition: hexrays.hpp:8682
#define MBA_CMNSTK
stkvars+stkargs should be considered as one area
Definition: hexrays.hpp:4488
bool change_hexrays_config(const char *directive)
Parse DIRECTIVE and update the current configuration variables.
Definition: hexrays.hpp:11505
#define IPROP_WILDMATCH
match multiple insns
Definition: hexrays.hpp:3483
void block_chains_free(block_chains_t *set)
Delete block_chains_t instance.
Definition: hexrays.hpp:9685
cfuncptr_t decompile_snippet(const rangevec_t &ranges, hexrays_failure_t *hf=nullptr, int decomp_flags=0)
Decompile a snippet.
Definition: hexrays.hpp:7199
#define OPROP_IMPDONE
imported operand (a pointer) has been dereferenced
Definition: hexrays.hpp:2449
eamap_iterator_t eamap_next(eamap_iterator_t p)
Move to the next element.
Definition: hexrays.hpp:9437
#define GCO_REG
is register? otherwise a stack variable
Definition: hexrays.hpp:5496
udcall_map_iterator_t udcall_map_next(udcall_map_iterator_t p)
Move to the next element.
Definition: hexrays.hpp:8892
bool is_commutative(ctype_t op)
Is commutative operator?
Definition: hexrays.hpp:5654
udcall_map_iterator_t udcall_map_prev(udcall_map_iterator_t p)
Move to the previous element.
Definition: hexrays.hpp:8900
void user_numforms_erase(user_numforms_t *map, user_numforms_iterator_t p)
Erase current element from user_numforms_t.
Definition: hexrays.hpp:8690
const mlist_t & get_temp_regs()
Get list of temporary registers.
Definition: hexrays.hpp:10447
void save_user_cmts(ea_t func_ea, const user_cmts_t *user_cmts)
Save user defined comments into the database.
Definition: hexrays.hpp:12059
std::map< lvar_locator_t, lvar_locator_t > lvar_mapping_t
Local variable mapping (is used to merge variables)
Definition: hexrays.hpp:1485
user_numforms_iterator_t user_numforms_next(user_numforms_iterator_t p)
Move to the next element.
Definition: hexrays.hpp:8674
eamap_iterator_t eamap_begin(const eamap_t *map)
Get iterator pointing to the beginning of eamap_t.
Definition: hexrays.hpp:9419
ea_t get_merror_desc(qstring *out, merror_t code, mba_t *mba)
Get textual description of an error code.
Definition: hexrays.hpp:9800
const mopt_t mop_b
micro basic block (mblock_t)
Definition: hexrays.hpp:2262
block_chains_iterator_t block_chains_next(block_chains_iterator_t p)
Move to the next element.
Definition: hexrays.hpp:9648
const mopt_t mop_S
local stack variable (they exist until MMAT_LVARS)
Definition: hexrays.hpp:2260
int32 & user_iflags_second(user_iflags_iterator_t p)
Get reference to the current map value.
Definition: hexrays.hpp:9067
user_unions_t * user_unions_new()
Create a new user_unions_t instance.
Definition: hexrays.hpp:9263
size_t boundaries_size(boundaries_t *map)
Get size of boundaries_t.
Definition: hexrays.hpp:9576
void eamap_erase(eamap_t *map, eamap_iterator_t p)
Erase current element from eamap_t.
Definition: hexrays.hpp:9453
const mopt_t mop_sc
scattered
Definition: hexrays.hpp:2270
#define IPROP_CLNPOP
the purpose of the instruction is to clean stack (e.g.
Definition: hexrays.hpp:3486
#define FD_DEF
look for definition
Definition: hexrays.hpp:4163
const int NOSIZE
wrong or unexisting operand size
Definition: hexrays.hpp:2272
bool get_current_operand(gco_info_t *out)
Get the instruction operand under the cursor.
Definition: hexrays.hpp:11567
size_t eamap_size(eamap_t *map)
Get size of eamap_t.
Definition: hexrays.hpp:9467
void block_chains_clear(block_chains_t *set)
Clear block_chains_t.
Definition: hexrays.hpp:9671
chain_t & block_chains_get(block_chains_iterator_t p)
Get reference to the current set value.
Definition: hexrays.hpp:9605
#define MBA_CALLS
callinfo has been built
Definition: hexrays.hpp:4494
bool op_uses_y(ctype_t op)
Does operator use the 'y' field of cexpr_t?
Definition: hexrays.hpp:5638
allow_unused_labels_t
Unused label disposition.
Definition: hexrays.hpp:6750
@ ALLOW_UNUSED_LABELS
Unused labels are permitted.
Definition: hexrays.hpp:6752
@ FORBID_UNUSED_LABELS
Unused labels cause interr.
Definition: hexrays.hpp:6751
#define MBA_ASRPROP
assertion have been propagated
Definition: hexrays.hpp:4495
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:9310
int const & user_labels_first(user_labels_iterator_t p)
Get reference to the current map key.
Definition: hexrays.hpp:9278
#define MBA_ASRTOK
assertions have been generated
Definition: hexrays.hpp:4493
#define ANCHOR_BLKCMT
block comment (for ctree items)
Definition: hexrays.hpp:6644
cexpr_t * dereference(cexpr_t *e, int ptrsize, bool is_flt=false)
Dereference a pointer.
Definition: hexrays.hpp:12041
#define IPROP_SPLIT1
into 1 byte
Definition: hexrays.hpp:3497
const mopt_t mop_z
none
Definition: hexrays.hpp:2255
boundaries_iterator_t boundaries_prev(boundaries_iterator_t p)
Move to the previous element.
Definition: hexrays.hpp:9554
#define ANCHOR_LVAR
declaration of local variable
Definition: hexrays.hpp:6642
lvar_mapping_iterator_t lvar_mapping_prev(lvar_mapping_iterator_t p)
Move to the previous element.
Definition: hexrays.hpp:8791
const mopt_t mop_fn
floating point constant
Definition: hexrays.hpp:2268
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:9292
bool is_lvalue(ctype_t op)
Is Lvalue operator?
Definition: hexrays.hpp:5715
#define MBA_WINGR32
use wingraph32
Definition: hexrays.hpp:4510
#define MBA_SAVRST
save-restore analysis has been performed
Definition: hexrays.hpp:4496
bool parse_user_call(udcall_t *udc, const char *decl, bool silent)
Convert function type declaration into internal structure.
Definition: hexrays.hpp:10126
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:9814
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:9301
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:9210
cinsn_t *const & boundaries_first(boundaries_iterator_t p)
Get reference to the current map key.
Definition: hexrays.hpp:9496
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:8983
const cmt_type_t CMT_NONE
No comment is possible.
Definition: hexrays.hpp:7591
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:12029
#define MBA_RETREF
return type has been refined
Definition: hexrays.hpp:4497
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:9612
#define IPROP_FARCALL
call of a far function using push cs/call sequence
Definition: hexrays.hpp:3489
#define MBA2_HAS_OUTLINES
calls to outlined code have been inlined
Definition: hexrays.hpp:4531
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:8974
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:8647
#define OPROP_FLOAT
possibly floating value
Definition: hexrays.hpp:2451
qstack< history_item_t > history_t
Navigation history.
Definition: hexrays.hpp:7586
void user_iflags_erase(user_iflags_t *map, user_iflags_iterator_t p)
Erase current element from user_iflags_t.
Definition: hexrays.hpp:9126
#define MBA_LVARS1
lvar real allocation has been performed
Definition: hexrays.hpp:4500
const mopt_t mop_r
register (they exist until MMAT_LVARS)
Definition: hexrays.hpp:2256
cinsnptrvec_t & eamap_second(eamap_iterator_t p)
Get reference to the current map value.
Definition: hexrays.hpp:9394
void boundaries_free(boundaries_t *map)
Delete boundaries_t instance.
Definition: hexrays.hpp:9583
eamap_iterator_t eamap_end(const eamap_t *map)
Get iterator pointing to the end of eamap_t.
Definition: hexrays.hpp:9428
void udcall_map_clear(udcall_map_t *map)
Clear udcall_map_t.
Definition: hexrays.hpp:8915
#define CFS_LOCKED
cfunc is temporarily locked
Definition: hexrays.hpp:6970
user_cmts_iterator_t user_cmts_next(user_cmts_iterator_t p)
Move to the next element.
Definition: hexrays.hpp:9001
bool modify_user_lvars(ea_t entry_ea, user_lvar_modifier_t &mlv)
Modify saved local variable settings.
Definition: hexrays.hpp:10096
ea_t const & eamap_first(eamap_iterator_t p)
Get reference to the current map key.
Definition: hexrays.hpp:9387
const mopt_t mop_a
mop_addr_t: address of operand (mop_l, mop_v, mop_S, mop_r)
Definition: hexrays.hpp:2265
const cmt_type_t CMT_BLOCK1
Anterioir block comment.
Definition: hexrays.hpp:7593
const mopt_t mop_str
immediate string constant (user representation)
Definition: hexrays.hpp:2258
bool is_prepost(ctype_t op)
Is pre/post increment/decrement operator?
Definition: hexrays.hpp:5652
uint8 mopt_t
Instruction operand types.
Definition: hexrays.hpp:2253
void eamap_clear(eamap_t *map)
Clear eamap_t.
Definition: hexrays.hpp:9460
gctype_t
Kind of use-def and def-use chains.
Definition: hexrays.hpp:5052
@ GC_DIRTY_ALL
bitmask to represent all chains
Definition: hexrays.hpp:5057
@ GC_ASR
all the above and assertions
Definition: hexrays.hpp:5054
@ GC_END
number of chain types
Definition: hexrays.hpp:5056
@ GC_REGS_AND_STKVARS
registers and stkvars (restricted memory only)
Definition: hexrays.hpp:5053
@ GC_XDSU
only registers calculated with FULL_XDSU
Definition: hexrays.hpp:5055
user_iflags_t * restore_user_iflags(ea_t func_ea)
Restore user defined citem iflags from the database.
Definition: hexrays.hpp:12107
ctree_maturity_t
Ctree maturity level.
Definition: hexrays.hpp:5935
@ CMAT_CPA
corrected pointer arithmetic
Definition: hexrays.hpp:5941
@ CMAT_FINAL
ready-to-use
Definition: hexrays.hpp:5944
@ CMAT_CASTED
added necessary casts
Definition: hexrays.hpp:5943
@ CMAT_BUILT
just generated
Definition: hexrays.hpp:5937
@ CMAT_NICE
nicefied expressions
Definition: hexrays.hpp:5939
@ CMAT_TRANS2
applied second wave of transformations
Definition: hexrays.hpp:5940
@ CMAT_TRANS3
applied third wave of transformations
Definition: hexrays.hpp:5942
@ CMAT_TRANS1
applied first wave of transformations
Definition: hexrays.hpp:5938
@ CMAT_ZERO
does not exist
Definition: hexrays.hpp:5936
bool is_loop(ctype_t op)
Is loop statement code?
Definition: hexrays.hpp:5702
#define OPTI_COMBINSNS
may combine insns (only for optimize_insn)
Definition: hexrays.hpp:3614
type_sign_t get_op_signness(ctype_t op)
Get operator sign. Meaningful for sign-dependent operators, like cot_sdiv.
Definition: hexrays.hpp:11591
user_unions_t * restore_user_unions(ea_t func_ea)
Restore user defined union field selections from the database.
Definition: hexrays.hpp:12113
qvector< block_chains_t > block_chains_vec_t
Graph chains.
Definition: hexrays.hpp:3428
#define MBA_NICE
apply transformations to c code
Definition: hexrays.hpp:4508
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:9621
#define IPROP_INV_JX
inverted conditional jump
Definition: hexrays.hpp:3506
cfuncptr_t create_cfunc(mba_t *mba)
Create a new cfunc_t object.
Definition: hexrays.hpp:12325
#define OPROP_CCFLAGS
mop_n: a pc-relative value mop_a: an address obtained from a relocation else: value of a condition co...
Definition: hexrays.hpp:2452
#define IPROP_SPLIT
the instruction has been split:
Definition: hexrays.hpp:3496
ctype_t negated_relation(ctype_t op)
Negate a comparison operator. For example, cot_sge becomes cot_slt.
Definition: hexrays.hpp:11579
#define IPROP_UNMERGED
'goto' instruction was transformed info 'call'
Definition: hexrays.hpp:3516
#define MBA_LVARS0
lvar pre-allocation has been performed
Definition: hexrays.hpp:4499
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:8665
int mreg2reg(mreg_t reg, int width)
Map a microregister to a processor register.
Definition: hexrays.hpp:10465
const mopt_t mop_p
operand pair
Definition: hexrays.hpp:2269
size_t user_iflags_size(user_iflags_t *map)
Get size of user_iflags_t.
Definition: hexrays.hpp:9140
mreg_t reg2mreg(int reg)
Map a processor register to a microregister.
Definition: hexrays.hpp:10459
#define MBA_PATTERN
microcode pattern, callinfo is present
Definition: hexrays.hpp:4482
#define MBA_LOADED
loaded gdl, no instructions (debugging)
Definition: hexrays.hpp:4483
ctype_t swapped_relation(ctype_t op)
Swap a comparison operator. For example, cot_sge becomes cot_sle.
Definition: hexrays.hpp:11585
int cmt_type_t
Comment types.
Definition: hexrays.hpp:7589
use_curly_t
Should curly braces be printed?
Definition: hexrays.hpp:6388
@ USE_CURLY_BRACES
print curly braces without any checks
Definition: hexrays.hpp:6391
@ CALC_CURLY_BRACES
print curly braces if necessary
Definition: hexrays.hpp:6389
@ NO_CURLY_BRACES
don't print curly braces
Definition: hexrays.hpp:6390
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:8856
void user_numforms_clear(user_numforms_t *map)
Clear user_numforms_t.
Definition: hexrays.hpp:8697
ctype_t
Ctree item code.
Definition: hexrays.hpp:5536
@ cot_asgxor
x ^= y
Definition: hexrays.hpp:5541
@ cot_call
x(...)
Definition: hexrays.hpp:5594
@ cot_ule
x <= y unsigned
Definition: hexrays.hpp:5564
@ cot_asgsdiv
x /= y signed
Definition: hexrays.hpp:5549
@ cit_break
break-statement
Definition: hexrays.hpp:5616
@ cot_cast
(type)x
Definition: hexrays.hpp:5585
@ cot_sgt
x > y signed or fpu (see EXFL_FPOP)
Definition: hexrays.hpp:5565
@ cot_sdiv
x / y signed
Definition: hexrays.hpp:5575
@ cit_do
do-statement
Definition: hexrays.hpp:5614
@ cot_insn
instruction in expression, internal representation only
Definition: hexrays.hpp:5603
@ cot_lor
x || y
Definition: hexrays.hpp:5554
@ cot_tern
x ? y : z
Definition: hexrays.hpp:5553
@ cot_asgbor
x |= y
Definition: hexrays.hpp:5540
@ cit_block
block-statement: { ... }
Definition: hexrays.hpp:5609
@ cit_continue
continue-statement
Definition: hexrays.hpp:5617
@ cot_lnot
!x
Definition: hexrays.hpp:5586
@ cot_asgshl
x <<= y
Definition: hexrays.hpp:5548
@ cot_ptr
*x, access size in 'ptrsize'
Definition: hexrays.hpp:5588
@ cot_preinc
++x
Definition: hexrays.hpp:5592
@ cot_shl
x << y
Definition: hexrays.hpp:5571
@ cot_obj
obj_ea
Definition: hexrays.hpp:5601
@ cot_neg
-x
Definition: hexrays.hpp:5584
@ cot_xor
x ^ y
Definition: hexrays.hpp:5557
@ cot_add
x + y
Definition: hexrays.hpp:5572
@ cot_sshr
x >> y signed
Definition: hexrays.hpp:5569
@ cot_asg
x = y
Definition: hexrays.hpp:5539
@ cot_type
arbitrary type
Definition: hexrays.hpp:5606
@ cot_sub
x - y
Definition: hexrays.hpp:5573
@ cot_slt
x < y signed or fpu (see EXFL_FPOP)
Definition: hexrays.hpp:5567
@ cot_mul
x * y
Definition: hexrays.hpp:5574
@ cot_udiv
x / y unsigned
Definition: hexrays.hpp:5576
@ cot_asgsshr
x >>= y signed
Definition: hexrays.hpp:5546
@ cot_eq
x == y int or fpu (see EXFL_FPOP)
Definition: hexrays.hpp:5559
@ cit_return
return-statement
Definition: hexrays.hpp:5618
@ cot_asgadd
x += y
Definition: hexrays.hpp:5543
@ cot_ref
&x
Definition: hexrays.hpp:5589
@ cot_ne
x != y int or fpu (see EXFL_FPOP)
Definition: hexrays.hpp:5560
@ cit_empty
instruction types start here
Definition: hexrays.hpp:5608
@ cit_asm
asm-statement
Definition: hexrays.hpp:5620
@ cot_predec
–x
Definition: hexrays.hpp:5593
@ cot_asgmul
x *= y
Definition: hexrays.hpp:5545
@ cot_helper
arbitrary name
Definition: hexrays.hpp:5605
@ cot_fneg
-x fp
Definition: hexrays.hpp:5583
@ cot_ult
x < y unsigned
Definition: hexrays.hpp:5568
@ cot_uge
x >= y unsigned
Definition: hexrays.hpp:5562
@ cot_fadd
x + y fp
Definition: hexrays.hpp:5579
@ cot_asgushr
x >>= y unsigned
Definition: hexrays.hpp:5547
@ cot_fnum
fpc
Definition: hexrays.hpp:5599
@ cot_postdec
x–
Definition: hexrays.hpp:5591
@ cot_memref
x.m
Definition: hexrays.hpp:5596
@ cot_postinc
x++
Definition: hexrays.hpp:5590
@ cot_sizeof
sizeof(x)
Definition: hexrays.hpp:5604
@ cot_sle
x <= y signed or fpu (see EXFL_FPOP)
Definition: hexrays.hpp:5563
@ cot_ushr
x >> y unsigned
Definition: hexrays.hpp:5570
@ cot_fdiv
x / y fp
Definition: hexrays.hpp:5582
@ cit_while
while-statement
Definition: hexrays.hpp:5613
@ cot_fsub
x - y fp
Definition: hexrays.hpp:5580
@ cot_str
string constant (user representation)
Definition: hexrays.hpp:5600
@ cot_var
v
Definition: hexrays.hpp:5602
@ cot_sge
x >= y signed or fpu (see EXFL_FPOP)
Definition: hexrays.hpp:5561
@ cit_goto
goto-statement
Definition: hexrays.hpp:5619
@ cit_switch
switch-statement
Definition: hexrays.hpp:5615
@ cot_asgband
x &= y
Definition: hexrays.hpp:5542
@ cot_asgsmod
x %= y signed
Definition: hexrays.hpp:5551
@ cot_num
n
Definition: hexrays.hpp:5598
@ cot_band
x & y
Definition: hexrays.hpp:5558
@ cot_bnot
~x
Definition: hexrays.hpp:5587
@ cot_comma
x, y
Definition: hexrays.hpp:5538
@ cot_asgsub
x -= y
Definition: hexrays.hpp:5544
@ cit_if
if-statement
Definition: hexrays.hpp:5611
@ cot_smod
x % y signed
Definition: hexrays.hpp:5577
@ cot_bor
x | y
Definition: hexrays.hpp:5556
@ cot_umod
x % y unsigned
Definition: hexrays.hpp:5578
@ cot_memptr
x->m, access size in 'ptrsize'
Definition: hexrays.hpp:5597
@ cot_asgumod
x %= y unsigned
Definition: hexrays.hpp:5552
@ cot_ugt
x > y unsigned
Definition: hexrays.hpp:5566
@ cot_asgudiv
x /= y unsigned
Definition: hexrays.hpp:5550
@ cot_idx
x[y]
Definition: hexrays.hpp:5595
@ cot_fmul
x * y fp
Definition: hexrays.hpp:5581
@ cit_expr
expression-statement: expr;
Definition: hexrays.hpp:5610
@ cot_land
x && y
Definition: hexrays.hpp:5555
@ cit_for
for-statement
Definition: hexrays.hpp:5612
lvar_mapping_iterator_t lvar_mapping_next(lvar_mapping_iterator_t p)
Move to the next element.
Definition: hexrays.hpp:8783
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:10084
cfuncptr_t decompile(const mba_ranges_t &mbr, hexrays_failure_t *hf=nullptr, int decomp_flags=0)
Decompile a snippet or a function.
Definition: hexrays.hpp:12313
funcrole_t
Function roles.
Definition: hexrays.hpp:3053
@ ROLE_3WAYCMP1
3-way compare helper, returns 0/1/2
Definition: hexrays.hpp:3087
@ ROLE_VA_COPY
va_copy() function
Definition: hexrays.hpp:3078
@ ROLE_UNK
unknown function role
Definition: hexrays.hpp:3054
@ ROLE_VA_ARG
va_arg() macro
Definition: hexrays.hpp:3077
@ ROLE_BITTEST
[lock] bt
Definition: hexrays.hpp:3073
@ ROLE_BUG
BUG() helper macro: never returns, causes exception.
Definition: hexrays.hpp:3064
@ ROLE_SSE_CMP4
e.g. _mm_cmpgt_ss
Definition: hexrays.hpp:3093
@ ROLE_EMPTY
empty, does not do anything (maybe spoils regs)
Definition: hexrays.hpp:3055
@ ROLE_MEMSET64
memset64(void *dst, uint64 value, size_t count);
Definition: hexrays.hpp:3058
@ ROLE_ALLOCA
alloca() function
Definition: hexrays.hpp:3065
@ ROLE_WMEMCPY
wchar_t *wmemcpy(wchar_t *dst, const wchar_t *src, size_t n)
Definition: hexrays.hpp:3088
@ ROLE_FASTFAIL
__fastfail()
Definition: hexrays.hpp:3069
@ ROLE_SATURATED_MUL
saturated_mul
Definition: hexrays.hpp:3072
@ ROLE_BITTESTANDSET
[lock] bts
Definition: hexrays.hpp:3074
@ ROLE_WCSCPY
wchar_t *wcscpy(wchar_t *dst, const wchar_t *src);
Definition: hexrays.hpp:3090
@ ROLE_SSE_CMP8
e.g. _mm_cmpgt_sd
Definition: hexrays.hpp:3094
@ ROLE_STRCAT
strcat(char *dst, const char *src);
Definition: hexrays.hpp:3062
@ ROLE_TAIL
char *tail(const char *str);
Definition: hexrays.hpp:3063
@ ROLE_CFSUB3
carry flag after subtract with carry
Definition: hexrays.hpp:3083
@ ROLE_READFLAGS
__readeflags, __readcallersflags
Definition: hexrays.hpp:3070
@ ROLE_MEMCPY
memcpy(void *dst, const void *src, size_t count);
Definition: hexrays.hpp:3059
@ ROLE_OFSUB3
overflow flag after subtract with carry
Definition: hexrays.hpp:3084
@ ROLE_PRESENT
present() function (used in patterns)
Definition: hexrays.hpp:3067
@ ROLE_BITTESTANDCOMPLEMENT
[lock] btc
Definition: hexrays.hpp:3076
@ ROLE_ABS
integer absolute value
Definition: hexrays.hpp:3085
@ ROLE_VA_START
va_start() function
Definition: hexrays.hpp:3079
@ ROLE_STRLEN
strlen(const char *src);
Definition: hexrays.hpp:3061
@ ROLE_STRCPY
strcpy(char *dst, const char *src);
Definition: hexrays.hpp:3060
@ ROLE_WCSLEN
size_t wcslen(const wchar_t *s)
Definition: hexrays.hpp:3091
@ ROLE_ROR
rotate right
Definition: hexrays.hpp:3082
@ ROLE_MEMSET
memset(void *dst, uchar value, size_t count);
Definition: hexrays.hpp:3056
@ ROLE_IS_MUL_OK
is_mul_ok
Definition: hexrays.hpp:3071
@ ROLE_VA_END
va_end() function
Definition: hexrays.hpp:3080
@ ROLE_WMEMSET
wchar_t *wmemset(wchar_t *dst, wchar_t wc, size_t n)
Definition: hexrays.hpp:3089
@ ROLE_CONTAINING_RECORD
CONTAINING_RECORD() macro.
Definition: hexrays.hpp:3068
@ ROLE_BITTESTANDRESET
[lock] btr
Definition: hexrays.hpp:3075
@ ROLE_MEMSET32
memset32(void *dst, uint32 value, size_t count);
Definition: hexrays.hpp:3057
@ ROLE_BSWAP
bswap() function (any size)
Definition: hexrays.hpp:3066
@ ROLE_ROL
rotate left
Definition: hexrays.hpp:3081
@ ROLE_WCSCAT
wchar_t *wcscat(wchar_t *dst, const wchar_t *src)
Definition: hexrays.hpp:3092
@ ROLE_3WAYCMP0
3-way compare helper, returns -1/0/1
Definition: hexrays.hpp:3086
bool remove_optblock_handler(optblock_t *opt)
Remove a block level custom optimizer.
Definition: hexrays.hpp:10496
#define MBA_GLBOPT
microcode has been optimized globally
Definition: hexrays.hpp:4498
bool checkout_hexrays_license(bool silent)
Check out a floating decompiler license.
Definition: hexrays.hpp:11517
#define MBA2_IS_DTR
is destructor?
Definition: hexrays.hpp:4522
void save_user_labels(ea_t func_ea, const user_labels_t *user_labels)
Save user defined labels into the database.
Definition: hexrays.hpp:12047
user_labels_t * user_labels_new()
Create a new user_labels_t instance.
Definition: hexrays.hpp:9372
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:9319
#define MBA_REFINE
may refine return value size
Definition: hexrays.hpp:4509
bool close_pseudocode(TWidget *f)
Close pseudocode window.
Definition: hexrays.hpp:11529
void close_hexrays_waitbox()
Close the waitbox displayed by the decompiler.
Definition: hexrays.hpp:12307
bool install_hexrays_callback(hexrays_cb_t *callback, void *ud)
Install handler for decompiler events.
Definition: hexrays.hpp:12363
user_iflags_t * user_iflags_new()
Create a new user_iflags_t instance.
Definition: hexrays.hpp:9154
#define MBA2_CODE16_BIT
the code16 bit removed
Definition: hexrays.hpp:4529
void boundaries_clear(boundaries_t *map)
Clear boundaries_t.
Definition: hexrays.hpp:9569
#define IPROP_COMBINED
insn has been modified because of a partial reference
Definition: hexrays.hpp:3501
const mopt_t mop_n
immediate number constant
Definition: hexrays.hpp:2257
#define MBA_INSGDL
display instruction in graphs
Definition: hexrays.hpp:4507
user_numforms_t * user_numforms_new()
Create a new user_numforms_t instance.
Definition: hexrays.hpp:8718
mba_t * create_empty_mba(const mba_ranges_t &mbr, hexrays_failure_t *hf=nullptr)
Create an empty microcode object.
Definition: hexrays.hpp:7225
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:9183
hexcall_t
API call numbers.
Definition: hexrays.hpp:7982
#define MBA2_STACK_RETVAL
the return value is on the stack
Definition: hexrays.hpp:4530
boundaries_t * boundaries_new()
Create a new boundaries_t instance.
Definition: hexrays.hpp:9590
#define MBA_CHVARS
can verify chain varnums
Definition: hexrays.hpp:4502
side_effect_t
How to handle side effect of change_size() Sometimes we need to create a temporary operand and change...
Definition: hexrays.hpp:2425
@ ONLY_SIDEFF
only handle side effects
Definition: hexrays.hpp:2430
@ ANY_REGSIZE
any register size is permitted
Definition: hexrays.hpp:2431
@ NO_SIDEFF
change operand size but ignore side effects if you decide to keep the changed operand,...
Definition: hexrays.hpp:2426
@ ANY_FPSIZE
any size of floating operand is permitted
Definition: hexrays.hpp:2432
@ WITH_SIDEFF
change operand size and handle side effects
Definition: hexrays.hpp:2429
int remove_hexrays_callback(hexrays_cb_t *callback, void *ud)
Uninstall handler for decompiler events.
Definition: hexrays.hpp:12369
bool is_assignment(ctype_t op)
Is assignment operator?
Definition: hexrays.hpp:5648
void save_user_numforms(ea_t func_ea, const user_numforms_t *numforms)
Save user defined number formats into the database.
Definition: hexrays.hpp:12065
void user_numforms_free(user_numforms_t *map)
Delete user_numforms_t instance.
Definition: hexrays.hpp:8711
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:9201
#define IPROP_MBARRIER
this instruction acts as a memory barrier (instructions accessing memory may not be reordered past it...
Definition: hexrays.hpp:3514
void install_optblock_handler(optblock_t *opt)
Install a block level custom optimizer.
Definition: hexrays.hpp:10490
cexpr_t * make_ref(cexpr_t *e)
Create a reference.
Definition: hexrays.hpp:12035
#define MBA2_PROP_COMPLEX
allow propagation of more complex variable definitions
Definition: hexrays.hpp:4533
boundaries_iterator_t boundaries_next(boundaries_iterator_t p)
Move to the next element.
Definition: hexrays.hpp:9546
void user_unions_erase(user_unions_t *map, user_unions_iterator_t p)
Erase current element from user_unions_t.
Definition: hexrays.hpp:9235
number_format_t & user_numforms_second(user_numforms_iterator_t p)
Get reference to the current map value.
Definition: hexrays.hpp:8631
mba_t * gen_microcode(const mba_ranges_t &mbr, hexrays_failure_t *hf=nullptr, 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:12319
void user_unions_free(user_unions_t *map)
Delete user_unions_t instance.
Definition: hexrays.hpp:9256
bool is_logical(ctype_t op)
Is logical operator?
Definition: hexrays.hpp:5694
bool install_microcode_filter(microcode_filter_t *filter, bool install=true)
register/unregister non-standard microcode generator
Definition: hexrays.hpp:10138
lvar_locator_t const & lvar_mapping_first(lvar_mapping_iterator_t p)
Get reference to the current map key.
Definition: hexrays.hpp:8733
citem_cmt_t & user_cmts_second(user_cmts_iterator_t p)
Get reference to the current map value.
Definition: hexrays.hpp:8958
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:9074
#define MBA_COLGDL
display graph after each reduction
Definition: hexrays.hpp:4506
#define IPROP_TAILCALL
tail call
Definition: hexrays.hpp:3490
const mopt_t mop_f
list of arguments
Definition: hexrays.hpp:2263
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:9410
cfuncptr_t decompile_func(func_t *pfn, hexrays_failure_t *hf=nullptr, int decomp_flags=0)
Decompile a function.
Definition: hexrays.hpp:7182
void lvar_mapping_free(lvar_mapping_t *map)
Delete lvar_mapping_t instance.
Definition: hexrays.hpp:8820
#define MBA_NUMADDR
display definition addresses for numbers
Definition: hexrays.hpp:4511
size_t block_chains_size(block_chains_t *set)
Get size of block_chains_t.
Definition: hexrays.hpp:9678
#define MBL_LIST
use/def lists are ready (not dirty)
Definition: hexrays.hpp:3826
#define OPTI_MINSTKREF
may update minstkref
Definition: hexrays.hpp:3613
ea_t const & udcall_map_first(udcall_map_iterator_t p)
Get reference to the current map key.
Definition: hexrays.hpp:8842
void user_labels_free(user_labels_t *map)
Delete user_labels_t instance.
Definition: hexrays.hpp:9365
size_t lvar_mapping_size(lvar_mapping_t *map)
Get size of lvar_mapping_t.
Definition: hexrays.hpp:8813
#define MBA_DELPAIRS
pairs have been deleted once
Definition: hexrays.hpp:4501
#define MBA2_IS_CTR
is constructor?
Definition: hexrays.hpp:4521
void install_optinsn_handler(optinsn_t *opt)
Install an instruction level custom optimizer.
Definition: hexrays.hpp:10477
void user_iflags_free(user_iflags_t *map)
Delete user_iflags_t instance.
Definition: hexrays.hpp:9147
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:4527
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:9092
void user_labels_erase(user_labels_t *map, user_labels_iterator_t p)
Erase current element from user_labels_t.
Definition: hexrays.hpp:9344
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:8747
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:8765
user_numforms_t * restore_user_numforms(ea_t func_ea)
Restore user defined number formats from the database.
Definition: hexrays.hpp:12101
eamap_t * eamap_new()
Create a new eamap_t instance.
Definition: hexrays.hpp:9481
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:9639
#define IPROP_DONT_COMB
may not combine this instruction with others
Definition: hexrays.hpp:3513
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:8756
#define OPROP_UDEFVAL
uses undefined value
Definition: hexrays.hpp:2455
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:12077
#define IPROP_SPLIT2
into 2 bytes
Definition: hexrays.hpp:3498
bool op_uses_x(ctype_t op)
Does operator use the 'x' field of cexpr_t?
Definition: hexrays.hpp:5636
citem_locator_t const & user_iflags_first(user_iflags_iterator_t p)
Get reference to the current map key.
Definition: hexrays.hpp:9060
#define IPROP_SPLIT8
into 8 bytes
Definition: hexrays.hpp:3500
#define MBL_DMT64
needs "demote 64bits"
Definition: hexrays.hpp:3822
#define FD_USE
look for use
Definition: hexrays.hpp:4162
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:9192
bool locate_lvar(lvar_locator_t *out, ea_t func_ea, const char *varname)
Find a variable by name.
Definition: hexrays.hpp:10108
user_cmts_t * user_cmts_new()
Create a new user_cmts_t instance.
Definition: hexrays.hpp:9045
qvector< cinsn_t * > cinsnptrvec_t
Vector of pointers to statements.
Definition: hexrays.hpp:6467
#define MBA2_VALRNG_DONE
calculated valranges?
Definition: hexrays.hpp:4520
const mopt_t mop_c
mcases
Definition: hexrays.hpp:2267
udcall_t & udcall_map_second(udcall_map_iterator_t p)
Get reference to the current map value.
Definition: hexrays.hpp:8849
block_chains_t * block_chains_new()
Create a new block_chains_t instance.
Definition: hexrays.hpp:9692
void term_hexrays_plugin()
Stop working with hex-rays decompiler.
Definition: hexrays.hpp:8609
mblock_type_t
Basic block types.
Definition: hexrays.hpp:3785
@ BLT_NONE
unknown block type
Definition: hexrays.hpp:3786
@ BLT_XTRN
external block (out of function address)
Definition: hexrays.hpp:3792
@ BLT_STOP
stops execution regularly (must be the last block)
Definition: hexrays.hpp:3787
@ BLT_2WAY
passes execution to two blocks (conditional jump)
Definition: hexrays.hpp:3790
@ BLT_0WAY
does not have successors (tail is a noret function)
Definition: hexrays.hpp:3788
@ BLT_1WAY
passes execution to one block (regular or goto block)
Definition: hexrays.hpp:3789
@ BLT_NWAY
passes execution to many blocks (switch idiom)
Definition: hexrays.hpp:3791
ctype_t asgop_revert(ctype_t cop)
Convert assignment operator into plain operator.
Definition: hexrays.hpp:11603
size_t user_labels_size(user_labels_t *map)
Get size of user_labels_t.
Definition: hexrays.hpp:9358
#define IPROP_FPINSN
floating point insn
Definition: hexrays.hpp:3488
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:9630
bool decompile_many(const char *outfile, const eavec_t *funcaddrs, int flags)
Batch decompilation.
Definition: hexrays.hpp:11541
#define IPROP_EXTSTX
this is m_ext propagated into m_stx
Definition: hexrays.hpp:3502
void boundaries_erase(boundaries_t *map, boundaries_iterator_t p)
Erase current element from boundaries_t.
Definition: hexrays.hpp:9562
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:9519
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:8965
#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:3508
#define IPROP_IGNLOWSRC
low part of the instruction source operand has been created artificially (this bit is used only for '...
Definition: hexrays.hpp:3503
vdui_t * get_widget_vdui(TWidget *f)
Get the vdui_t instance associated to the TWidget.
Definition: hexrays.hpp:11535
const mopt_t mop_v
global variable
Definition: hexrays.hpp:2261
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:9101
#define MBA2_LVARNAMES_OK
may verify lvar_names?
Definition: hexrays.hpp:4517
user_labels_iterator_t user_labels_prev(user_labels_iterator_t p)
Move to the previous element.
Definition: hexrays.hpp:9336
user_iflags_iterator_t user_iflags_prev(user_iflags_iterator_t p)
Move to the previous element.
Definition: hexrays.hpp:9118
bool is_multiplicative(ctype_t op)
Is multiplicative operator?
Definition: hexrays.hpp:5675
#define MBA_PRCDEFS
use precise defeas for chain-allocated lvars
Definition: hexrays.hpp:4480
void udcall_map_erase(udcall_map_t *map, udcall_map_iterator_t p)
Erase current element from udcall_map_t.
Definition: hexrays.hpp:8908
cinsn_t * new_block()
Create a new block-statement.
Definition: hexrays.hpp:12011
mba_maturity_t
Microcode maturity levels.
Definition: hexrays.hpp:4335
@ MMAT_LOCOPT
local optimization of each basic block is complete.
Definition: hexrays.hpp:4339
@ MMAT_LVARS
allocated local variables
Definition: hexrays.hpp:4345
@ MMAT_CALLS
detected call arguments. see also hxe_calls_done
Definition: hexrays.hpp:4341
@ MMAT_GLBOPT1
performed the first pass of global optimization
Definition: hexrays.hpp:4342
@ MMAT_PREOPTIMIZED
preoptimized pass is complete
Definition: hexrays.hpp:4338
@ MMAT_ZERO
microcode does not exist
Definition: hexrays.hpp:4336
@ MMAT_GLBOPT3
completed all global optimization. microcode is fixed now.
Definition: hexrays.hpp:4344
@ MMAT_GLBOPT2
most global optimization passes are done
Definition: hexrays.hpp:4343
@ MMAT_GENERATED
generated microcode
Definition: hexrays.hpp:4337
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:10090
ctype_t asgop(ctype_t cop)
Convert plain operator into assignment operator. For example, cot_add returns cot_asgadd.
Definition: hexrays.hpp:11597
bool restore_user_defined_calls(udcall_map_t *udcalls, ea_t func_ea)
Restore user defined function calls from the database.
Definition: hexrays.hpp:10114
bool remove_optinsn_handler(optinsn_t *opt)
Remove an instruction level custom optimizer.
Definition: hexrays.hpp:10483
void eamap_free(eamap_t *map)
Delete eamap_t instance.
Definition: hexrays.hpp:9474
warnid_t
Warning ids.
Definition: hexrays.hpp:4248
@ WARN_OPT_VALRNG2
52 mask 0xX is shortened because s <= 0xX"
Definition: hexrays.hpp:4302
@ WARN_GUESSED_TYPE
9 using guessed type s;
Definition: hexrays.hpp:4258
@ WARN_BAD_STROFF
33 user specified stroff has not been processed: s
Definition: hexrays.hpp:4282
@ WARN_OPT_USELESS_JCND
54 simplified comparisons for 's': s became s
Definition: hexrays.hpp:4305
@ WARN_FIXED_MACRO
29 fixed broken macro-insn
Definition: hexrays.hpp:4278
@ WARN_ODD_INPUT_REG
15 odd input register s
Definition: hexrays.hpp:4264
@ WARN_ILL_FUNCTYPE
2 invalid function type 's' has been ignored
Definition: hexrays.hpp:4251
@ WARN_ILL_PURGED
1 odd caller purged bytes d, correcting
Definition: hexrays.hpp:4250
@ WARN_UNINITED_REG
28 reference to an uninitialized register has been removed: s
Definition: hexrays.hpp:4277
@ WARN_ODD_ADDR_USE
16 odd use of a variable address
Definition: hexrays.hpp:4265
@ WARN_CBUILD_LOOPS
13 too many cbuild loops
Definition: hexrays.hpp:4262
@ WARN_BAD_VARSIZE
34 inconsistent variable size for 's'
Definition: hexrays.hpp:4283
@ WARN_VARARG_MANY
5 too many varargs, some ignored
Definition: hexrays.hpp:4254
@ WARN_MAX
may be used in notes as a placeholder when the warning id is not available
Definition: hexrays.hpp:4306
@ WARN_UNBALANCED_STACK
51 unbalanced stack, ignored a potential tail call
Definition: hexrays.hpp:4300
@ WARN_FRAG_LVAR
26 fragmented variable at s may be wrong
Definition: hexrays.hpp:4275
@ WARN_BAD_PURGED
12 inconsistent function type and number of purged bytes
Definition: hexrays.hpp:4261
@ WARN_UNSUPP_REG
35 unsupported processor register 's'
Definition: hexrays.hpp:4284
@ WARN_VARARG_REGS
0 cannot handle register arguments in vararg function, discarded them
Definition: hexrays.hpp:4249
@ WARN_MISSED_SWITCH
39 wrong markup of switch jump, skipped it
Definition: hexrays.hpp:4288
@ WARN_UNDEF_LVAR
42 variable 's' is possibly undefined
Definition: hexrays.hpp:4291
@ WARN_RET_LOCREF
47 returning address of temporary local variable 's'
Definition: hexrays.hpp:4296
@ WARN_BAD_RETVAR
25 wrong return variable
Definition: hexrays.hpp:4274
@ WARN_CR_NOFIELD
31 CONTAINING_RECORD: no field 's' in struct 's' at d
Definition: hexrays.hpp:4280
@ WARN_BAD_CALL_SP
38 bad sp value at call
Definition: hexrays.hpp:4287
@ WARN_WRITE_CONST
24 write access to const memory at a has been detected
Definition: hexrays.hpp:4273
@ WARN_WIDEN_CHAINS
11 failed to widen chains
Definition: hexrays.hpp:4260
@ WARN_ILL_FPU_STACK
18 inconsistent fpu stack
Definition: hexrays.hpp:4267
@ WARN_SELFREF_PROP
19 self-referencing variable has been detected
Definition: hexrays.hpp:4268
@ WARN_WRONG_VA_OFF
30 wrong offset of va_list variable
Definition: hexrays.hpp:4279
@ WARN_BAD_STKPNT
41 wrong sp change point
Definition: hexrays.hpp:4290
@ WARN_OPT_VALRNG
46 conditional instruction was optimized away because s
Definition: hexrays.hpp:4295
@ WARN_BAD_SHADOW
45 ignored the value written to the shadow area of the succeeding call
Definition: hexrays.hpp:4294
@ WARN_NO_SAVE_REST
14 could not find valid save-restore pair for s
Definition: hexrays.hpp:4263
@ WARN_BAD_INSN
49 bad instruction
Definition: hexrays.hpp:4298
@ WARN_ILL_ELLIPSIS
8 erroneously detected ellipsis type has been ignored
Definition: hexrays.hpp:4257
@ WARN_EXP_LINVAR
10 failed to expand a linear variable
Definition: hexrays.hpp:4259
@ WARN_VARARG_NOSTK
4 call vararg without local stack
Definition: hexrays.hpp:4253
@ WARN_MUST_RET_FP
17 function return type is incorrect (must be floating point)
Definition: hexrays.hpp:4266
@ WARN_JUMPOUT
43 control flows out of bounds
Definition: hexrays.hpp:4292
@ WARN_BAD_FIELD_TYPE
23 incorrect structure member type for s::s, ignored
Definition: hexrays.hpp:4272
@ WARN_WOULD_OVERLAP
20 variables would overlap: s
Definition: hexrays.hpp:4269
@ WARN_VARARG_TCAL
3 cannot handle tail call to vararg
Definition: hexrays.hpp:4252
@ WARN_ODD_ABI
50 encountered odd instruction for the current ABI
Definition: hexrays.hpp:4299
@ WARN_HUGE_STKOFF
27 exceedingly huge offset into the stack frame
Definition: hexrays.hpp:4276
@ WARN_ADDR_OUTARGS
6 cannot handle address arithmetics in outgoing argument area of stack frame – unused
Definition: hexrays.hpp:4255
@ WARN_MAX_ARGS
22 too many input arguments, some ignored
Definition: hexrays.hpp:4271
@ WARN_ARRAY_INARG
21 array has been used for an input argument
Definition: hexrays.hpp:4270
@ WARN_UNALIGNED_ARG
36 unaligned function argument 's'
Definition: hexrays.hpp:4285
@ WARN_CR_BADOFF
32 CONTAINING_RECORD: too small offset d for struct 's'
Definition: hexrays.hpp:4281
@ WARN_BAD_SP
40 positive sp value a has been found
Definition: hexrays.hpp:4289
@ WARN_OPT_VALRNG3
53 masking with 0XX was optimized away because s <= 0xX
Definition: hexrays.hpp:4304
@ WARN_BAD_VALRNG
44 values range analysis failed
Definition: hexrays.hpp:4293
@ WARN_DEP_UNK_CALLS
7 found interdependent unknown calls
Definition: hexrays.hpp:4256
@ WARN_BAD_STD_TYPE
37 corrupted or unexisting local type 's'
Definition: hexrays.hpp:4286
@ WARN_BAD_MAPDST
48 too short map destination 's' for variable 's'
Definition: hexrays.hpp:4297
treeloc_t const & user_cmts_first(user_cmts_iterator_t p)
Get reference to the current map key.
Definition: hexrays.hpp:8951
void block_chains_erase(block_chains_t *set, block_chains_iterator_t p)
Erase current element from block_chains_t.
Definition: hexrays.hpp:9664
#define IPROP_ASSERT
assertion: usually mov #val, op.
Definition: hexrays.hpp:3491
user_labels_t * restore_user_labels(ea_t func_ea)
Restore user defined labels from the database.
Definition: hexrays.hpp:12083
block_chains_iterator_t block_chains_prev(block_chains_iterator_t p)
Move to the previous element.
Definition: hexrays.hpp:9656
user_cmts_t * restore_user_cmts(ea_t func_ea)
Restore user defined comments from the database.
Definition: hexrays.hpp:12095
const cmt_type_t CMT_ALL
All comments.
Definition: hexrays.hpp:7597
#define MBA_VALNUM
display value numbers
Definition: hexrays.hpp:4512
void user_unions_clear(user_unions_t *map)
Clear user_unions_t.
Definition: hexrays.hpp:9242
#define MBA_RETFP
function returns floating point value
Definition: hexrays.hpp:4484
const mopt_t mop_h
helper function
Definition: hexrays.hpp:2266
void lvar_mapping_erase(lvar_mapping_t *map, lvar_mapping_iterator_t p)
Erase current element from lvar_mapping_t.
Definition: hexrays.hpp:8799
#define OPROP_LOWADDR
a low address offset
Definition: hexrays.hpp:2456
const char * get_hexrays_version()
Get decompiler version.
Definition: hexrays.hpp:11511
bool is_binary(ctype_t op)
Is binary operator?
Definition: hexrays.hpp:5642
#define GCO_DEF
is destination operand?
Definition: hexrays.hpp:5498
#define OPROP_UDT
a struct or union
Definition: hexrays.hpp:2450
ivlset_tpl< ivl_t, uval_t > uval_ivl_ivlset_t
Set of address intervals.
Definition: hexrays.hpp:1965
lvar_mapping_t * lvar_mapping_new()
Create a new lvar_mapping_t instance.
Definition: hexrays.hpp:8827
bool is_kreg(mreg_t r)
Is a kernel register? Kernel registers are temporary registers that can be used freely.
Definition: hexrays.hpp:10453
udcall_map_t * udcall_map_new()
Create a new udcall_map_t instance.
Definition: hexrays.hpp:8936
void send_database(const hexrays_failure_t &err, bool silent)
Send the database to Hex-Rays.
Definition: hexrays.hpp:11555
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:10120
ssize_t hexrays_cb_t(void *ud, hexrays_event_t event, va_list va)
Handler of decompiler events.
Definition: hexrays.hpp:7517
#define IPROP_DONT_PROP
may not propagate
Definition: hexrays.hpp:3512
user_labels_iterator_t user_labels_next(user_labels_iterator_t p)
Move to the next element.
Definition: hexrays.hpp:9328
qstring & user_labels_second(user_labels_iterator_t p)
Get reference to the current map value.
Definition: hexrays.hpp:9285
Function argument.
Definition: hexrays.hpp:6577
tinfo_t formal_type
formal parameter type (if known)
Definition: hexrays.hpp:6579
Function argument list.
Definition: hexrays.hpp:6594
tinfo_t functype
function object type
Definition: hexrays.hpp:6595
asm statement
Definition: hexrays.hpp:6457
Compound statement (curly braces)
Definition: hexrays.hpp:6571
Switch case. Usually cinsn_t is a block.
Definition: hexrays.hpp:6609
uint64vec_t values
List of case values.
Definition: hexrays.hpp:6610
Vector of switch cases.
Definition: hexrays.hpp:6621
Do-loop.
Definition: hexrays.hpp:6436
Statement with an expression.
Definition: hexrays.hpp:6380
cexpr_t expr
Expression of the statement.
Definition: hexrays.hpp:6381
Ctree item: expression.
Definition: hexrays.hpp:6113
type_sign_t get_type_sign() const
Get expression sign.
Definition: hexrays.hpp:6263
bit_bound_t get_high_nbit_bound() const
Get max number of bits that can really be used by the expression.
Definition: hexrays.hpp:11755
int ptrsize
memory access size (used for cot_ptr, cot_memptr)
Definition: hexrays.hpp:6140
bool contains_comma(int times=1) const
Does the expression contain a comma operator?
Definition: hexrays.hpp:6243
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:11707
bool is_type_unsigned() const
Is expression unsigned?
Definition: hexrays.hpp:6265
void cleanup()
Cleanup the expression.
Definition: hexrays.hpp:11713
bool is_nice_cond() const
Is nice condition?.
Definition: hexrays.hpp:6255
bool is_aliasable() const
Check if the expression if aliasable.
bool is_call_arg_of(const citem_t *parent) const
Is call argument?
Definition: hexrays.hpp:6261
fnumber_t * fpc
used for cot_fnum
Definition: hexrays.hpp:6117
carglist_t * a
argument list (used for cot_call)
Definition: hexrays.hpp:6133
bool requires_lvalue(const cexpr_t *child) const
Check if the expression requires an lvalue.
Definition: hexrays.hpp:11769
uint64 numval() const
Get numeric value of the expression.
Definition: hexrays.hpp:6289
bool is_zero_const() const
Check if the expression is a zero.
Definition: hexrays.hpp:6315
void print1(qstring *vout, const cfunc_t *func) const
Print expression into one line.
Definition: hexrays.hpp:11725
bool like_boolean() const
Does the expression look like a boolean expression? In other words, its possible values are only 0 an...
cexpr_t * get_ptr_or_array()
Find pointer or array child.
Definition: hexrays.hpp:6335
const cexpr_t * find_op(ctype_t _op) const
Find the child with the specified operator.
Definition: hexrays.hpp:6344
bool is_type_signed() const
Is expression signed?
Definition: hexrays.hpp:6267
char * string
utf8 string constant, user representation (used for cot_str)
Definition: hexrays.hpp:6146
bool is_negative_const() const
Check if the expression is a negative number.
Definition: hexrays.hpp:6300
bool is_nice_expr() const
Is nice expression? Nice expressions do not contain comma operators, embedded statements,...
Definition: hexrays.hpp:6252
const cexpr_t * find_num_op() const
Find the operand with a numeric value.
Definition: hexrays.hpp:6358
cinsn_t * insn
an embedded statement, they are prohibited at the final maturity stage (CMAT_FINAL)
Definition: hexrays.hpp:6143
bool is_non_negative_const() const
Check if the expression is a non-negative number.
Definition: hexrays.hpp:6305
bool is_const_value(uint64 _v) const
Check if the expression is a number with the specified value.
Definition: hexrays.hpp:6295
void calc_type(bool recursive)
Calculate the type of the expression.
Definition: hexrays.hpp:11731
cnumber_t * n
used for cot_num
Definition: hexrays.hpp:6116
bool equal_effect(const cexpr_t &r) const
Compare two expressions.
Definition: hexrays.hpp:11737
ea_t obj_ea
used for cot_obj
Definition: hexrays.hpp:6123
cexpr_t * y
the second operand of the expression
Definition: hexrays.hpp:6132
bool is_call_object_of(const citem_t *parent) const
Is call object?
Definition: hexrays.hpp:6258
const cexpr_t * theother(const cexpr_t *what) const
Get the other operand.
Definition: hexrays.hpp:6366
bool contains_insn_or_label() const
Does the expression contain an embedded statement operator or a label?
Definition: hexrays.hpp:6247
bool is_child_of(const citem_t *parent) const
Verify if the specified item is our parent.
Definition: hexrays.hpp:11743
bool contains_insn(int times=1) const
Does the expression contain an embedded statement operator?
Definition: hexrays.hpp:6245
char * helper
helper name (used for cot_helper)
Definition: hexrays.hpp:6145
var_ref_t v
used for cot_var
Definition: hexrays.hpp:6122
bool has_side_effects() const
Check if the expression has side effects.
Definition: hexrays.hpp:11775
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:11719
cexpr_t * z
the third operand of the expression
Definition: hexrays.hpp:6139
int get_low_nbit_bound() const
Get min number of bits that are certainly required to represent the expression.
Definition: hexrays.hpp:11763
bool contains_operator(ctype_t needed_op, int times=1) const
Check if the expression contains the specified operator.
Definition: hexrays.hpp:11749
bool cpadone() const
Pointer arithmetic correction done for this expression?
Definition: hexrays.hpp:6165
const cexpr_t * find_ptr_or_array(bool remove_eqsize_casts) const
Find the pointer operand.
bool is_non_zero_const() const
Check if the expression is a non-zero number.
Definition: hexrays.hpp:6310
uint32 m
member offset (used for cot_memptr, cot_memref) for unions, the member number
Definition: hexrays.hpp:6134
cexpr_t * x
the first operand of the expression
Definition: hexrays.hpp:6129
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:6249
tinfo_t type
expression type. must be carefully maintained
Definition: hexrays.hpp:6148
bool get_1num_op(cexpr_t **o1, cexpr_t **o2)
Get pointers to operands.
Definition: hexrays.hpp:7279
int refwidth
how many bytes are accessed? (-1: none)
Definition: hexrays.hpp:6125
bool get_const_value(uint64 *out) const
Get expression value.
Definition: hexrays.hpp:6321
bool maybe_ptr() const
May the expression be a pointer?
Definition: hexrays.hpp:11781
For-loop.
Definition: hexrays.hpp:6422
cexpr_t init
Initialization expression.
Definition: hexrays.hpp:6423
cexpr_t step
Step expression.
Definition: hexrays.hpp:6424
Class to traverse the whole function.
Definition: hexrays.hpp:5915
cfunc_t * func
Pointer to current function.
Definition: hexrays.hpp:5916
bool calc_rvalue_type(tinfo_t *target, const cexpr_t *e)
Calculate rvalue type.
Definition: hexrays.hpp:11659
Decompiled function. Decompilation result is kept here.
Definition: hexrays.hpp:6947
void set_user_union_selection(ea_t ea, const intvec_t &path)
Set a union field selection.
Definition: hexrays.hpp:12217
user_cmts_t * user_cmts
user-defined comments.
Definition: hexrays.hpp:6956
user_unions_t * user_unions
user-defined union field selections.
Definition: hexrays.hpp:6959
void build_c_tree()
Generate the function body.
Definition: hexrays.hpp:12119
const char * get_user_cmt(const treeloc_t &loc, cmt_retrieval_type_t rt) const
Retrieve a user defined comment.
Definition: hexrays.hpp:12175
void remove_unused_labels()
Remove unused labels.
Definition: hexrays.hpp:12169
strvec_t sv
decompilation output: function text. use get_pseudocode
Definition: hexrays.hpp:6973
sval_t get_stkoff_delta()
Get stack offset delta.
Definition: hexrays.hpp:12155
void print_func(vc_printer_t &vp) const
Print function text.
Definition: hexrays.hpp:12137
const strvec_t & get_pseudocode()
Get pointer to decompilation output: the pseudocode.
Definition: hexrays.hpp:12277
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:12253
user_iflags_t * user_iflags
user-defined item flags ctree item iflags bits
Definition: hexrays.hpp:6958
void set_user_iflags(const citem_locator_t &loc, int32 iflags)
Set citem iflags.
Definition: hexrays.hpp:12193
int hdrlines
number of lines in the declaration area
Definition: hexrays.hpp:6974
boundaries_t & get_boundaries()
Get pointer to map of instruction boundaries.
Definition: hexrays.hpp:12271
hexwarns_t & get_warnings()
Get information about decompilation warnings.
Definition: hexrays.hpp:12259
lvars_t * get_lvars()
Get vector of local variables.
Definition: hexrays.hpp:12149
bool has_orphan_cmts() const
Check if there are orphan comments.
Definition: hexrays.hpp:12199
void print_dcl(qstring *vout) const
Print function prototype.
Definition: hexrays.hpp:12131
eamap_t * eamap
ea->insn map. use get_eamap
Definition: hexrays.hpp:6971
user_numforms_t * numforms
user-defined number formats.
Definition: hexrays.hpp:6957
ctree_maturity_t maturity
maturity level
Definition: hexrays.hpp:6952
void save_user_labels() const
Save user-defined labels into the database.
Definition: hexrays.hpp:12223
void save_user_unions() const
Save user-defined union field selections into the database.
Definition: hexrays.hpp:12247
intvec_t & argidx
list of arguments (indexes into vars)
Definition: hexrays.hpp:6951
boundaries_t * boundaries
map of instruction boundaries. use get_boundaries
Definition: hexrays.hpp:6972
int statebits
current cfunc_t state.
Definition: hexrays.hpp:6965
citem_t * find_label(int label)
Find the label.
Definition: hexrays.hpp:12163
user_labels_t * user_labels
user-defined labels.
Definition: hexrays.hpp:6955
int refcnt
reference count to this object. use cfuncptr_t
Definition: hexrays.hpp:6964
bool get_user_union_selection(ea_t ea, intvec_t *path)
Retrieve a user defined union field selection.
Definition: hexrays.hpp:12211
void save_user_iflags() const
Save user-defined iflags into the database.
Definition: hexrays.hpp:12241
void refresh_func_ctext()
Refresh ctext after a ctree modification.
Definition: hexrays.hpp:12283
ctree_items_t treeitems
vector of ctree items
Definition: hexrays.hpp:6975
int del_orphan_cmts()
Delete all orphan comments.
Definition: hexrays.hpp:12205
void save_user_cmts() const
Save user-defined comments into the database.
Definition: hexrays.hpp:12229
mba_t * mba
underlying microcode
Definition: hexrays.hpp:6949
void set_user_cmt(const treeloc_t &loc, const char *cmt)
Set a user defined comment.
Definition: hexrays.hpp:12181
ea_t entry_ea
function entry address
Definition: hexrays.hpp:6948
cinsn_t body
function body, must be a block
Definition: hexrays.hpp:6950
eamap_t & get_eamap()
Get pointer to ea->insn map.
Definition: hexrays.hpp:12265
void verify(allow_unused_labels_t aul, bool even_without_debugger) const
Verify the ctree.
Definition: hexrays.hpp:12125
bool get_func_type(tinfo_t *type) const
Get the function type.
Definition: hexrays.hpp:12143
void save_user_numforms() const
Save user-defined number formats into the database.
Definition: hexrays.hpp:12235
int32 get_user_iflags(const citem_locator_t &loc) const
Retrieve citem iflags.
Definition: hexrays.hpp:12187
Goto statement.
Definition: hexrays.hpp:6448
int label_num
Target label number.
Definition: hexrays.hpp:6449
Chain visitor class.
Definition: hexrays.hpp:3420
If statement.
Definition: hexrays.hpp:6396
Ctree item: statement.
Definition: hexrays.hpp:6472
cdo_t * cdo
details of do-statement
Definition: hexrays.hpp:6480
bool contains_free_continue() const
Check if the statement has free continue statements.
Definition: hexrays.hpp:6561
bool is_ordinary_flow() const
Check if the statement passes execution to the next statement.
Definition: hexrays.hpp:11895
void zero()
Overwrite with zeroes without cleaning memory or deleting children.
Definition: hexrays.hpp:6506
cgoto_t * cgoto
details of goto-statement
Definition: hexrays.hpp:6483
cif_t * cif
details of if-statement
Definition: hexrays.hpp:6477
cexpr_t * cexpr
details of expression-statement
Definition: hexrays.hpp:6476
void print1(qstring *vout, const cfunc_t *func) const
Print the statement into one line.
Definition: hexrays.hpp:11889
cif_t & create_if(cexpr_t *cnd)
Create a new if-statement.
Definition: hexrays.hpp:11877
cfor_t * cfor
details of for-statement
Definition: hexrays.hpp:6478
cswitch_t * cswitch
details of switch-statement
Definition: hexrays.hpp:6481
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:11883
bool collect_free_continues(cinsnptrvec_t *continues)
Collect free continue statements.
Definition: hexrays.hpp:11913
void replace_by(cinsn_t *r)
Replace the statement.
Definition: hexrays.hpp:11859
bool collect_free_breaks(cinsnptrvec_t *breaks)
Collect free break statements.
Definition: hexrays.hpp:11907
void cleanup()
Cleanup the statement.
Definition: hexrays.hpp:11865
bool contains_insn(ctype_t type, int times=1) const
Check if the statement contains a statement of the specified type.
Definition: hexrays.hpp:11901
bool contains_free_break() const
Check if the statement has free break statements.
Definition: hexrays.hpp:6559
cinsn_t & new_insn(ea_t insn_ea)
Create a new statement.
Definition: hexrays.hpp:11871
cwhile_t * cwhile
details of while-statement
Definition: hexrays.hpp:6479
creturn_t * creturn
details of return-statement
Definition: hexrays.hpp:6482
cblock_t * cblock
details of block-statement
Definition: hexrays.hpp:6475
casm_t * casm
details of asm-statement
Definition: hexrays.hpp:6484
Ctree item comment.
Definition: hexrays.hpp:6017
Generic ctree item locator.
Definition: hexrays.hpp:6029
ea_t ea
citem address
Definition: hexrays.hpp:6030
ctype_t op
citem operation
Definition: hexrays.hpp:6031
Basic ctree item.
Definition: hexrays.hpp:6069
bool contains_expr(const cexpr_t *e) const
Does the item contain an expression?
Definition: hexrays.hpp:11671
ctype_t op
item type
Definition: hexrays.hpp:6071
bool is_expr() const
Is an expression?
Definition: hexrays.hpp:6088
void print1(qstring *vout, const cfunc_t *func) const
Print item into one line.
Definition: hexrays.hpp:7268
bool contains_label() const
Does the item contain a label?
Definition: hexrays.hpp:11677
int label_num
label number.
Definition: hexrays.hpp:6072
void swap(citem_t &r)
Swap two citem_t.
Definition: hexrays.hpp:6081
const citem_t * find_parent_of(const citem_t *sitem) const
Find parent of the specified item.
Definition: hexrays.hpp:11683
ea_t ea
address that corresponds to the item. may be BADADDR
Definition: hexrays.hpp:6070
Base class for loop statements.
Definition: hexrays.hpp:6410
An immediate number.
Definition: hexrays.hpp:5739
uint64 value(const tinfo_t &type) const
Get value.
Definition: hexrays.hpp:11615
void print(qstring *vout, const tinfo_t &type, const citem_t *parent=nullptr, bool *nice_stroff=nullptr) const
Get text representation.
Definition: hexrays.hpp:11609
void assign(uint64 v, int nbytes, type_sign_t sign)
Assign new value.
Definition: hexrays.hpp:11623
uint64 _value
its value
Definition: hexrays.hpp:5740
number_format_t nf
how to represent it
Definition: hexrays.hpp:5741
Return statement.
Definition: hexrays.hpp:6442
Switch statement.
Definition: hexrays.hpp:6628
cnumber_t mvnf
Maximal switch value and number format.
Definition: hexrays.hpp:6629
ccases_t cases
Switch cases: values and instructions.
Definition: hexrays.hpp:6630
Cursor position in the output text (pseudocode).
Definition: hexrays.hpp:7552
bool in_ctree(int hdrlines) const
Is the cursor in the variable/type declaration area?
Definition: hexrays.hpp:7558
int lnnum
Line number.
Definition: hexrays.hpp:7553
int y
y coordinate of the cursor within the window
Definition: hexrays.hpp:7555
int x
x coordinate of the cursor within the window
Definition: hexrays.hpp:7554
DECLARE_COMPARISONS(ctext_position_t)
Comparison operators.
Definition: hexrays.hpp:7560
Invisible COLOR_ADDR tags in the output text are used to refer to ctree items and variables.
Definition: hexrays.hpp:6637
Cursor item.
Definition: hexrays.hpp:6667
int get_udm(udm_t *udm=nullptr, tinfo_t *parent=nullptr, uint64 *p_offset=nullptr) const
Get type of a structure field.
Definition: hexrays.hpp:11961
lvar_t * l
VDI_LVAR: Local variable.
Definition: hexrays.hpp:6674
int get_edm(tinfo_t *parent) const
Get type of an enum member.
Definition: hexrays.hpp:11967
ea_t get_ea() const
Get address of the current item.
Definition: hexrays.hpp:11979
cinsn_t * i
VDI_EXPR: Statement.
Definition: hexrays.hpp:6673
int get_label_num(int gln_flags) const
Get label number of the current item.
Definition: hexrays.hpp:11987
cfunc_t * f
VDI_FUNC: Function.
Definition: hexrays.hpp:6675
treeloc_t loc
VDI_TAIL: Line tail.
Definition: hexrays.hpp:6676
lvar_t * get_lvar() const
Get pointer to local variable.
Definition: hexrays.hpp:11973
cexpr_t * e
VDI_EXPR: Expression.
Definition: hexrays.hpp:6672
bool is_citem() const
Is the current item is a ctree item?
Definition: hexrays.hpp:6741
member_t * get_memptr(struc_t **p_sptr=nullptr) const
Get pointer to structure member.
Definition: hexrays.hpp:11955
A helper ctree traversal class that maintains parent information.
Definition: hexrays.hpp:5895
bool recalc_parent_types()
Recalculate type of parent nodes.
Definition: hexrays.hpp:11653
cblock_t * get_block()
Get pointer to the parent block of the currently visited item.
Definition: hexrays.hpp:7309
A generic helper class that is used for ctree traversal.
Definition: hexrays.hpp:5790
virtual int visit_expr(cexpr_t *)
Visit an expression.
Definition: hexrays.hpp:5872
virtual int leave_expr(cexpr_t *)
Visit an expression after having visited its children.
Definition: hexrays.hpp:5888
void set_restart()
Restart the travesal. Meaningful only in apply_to_exprs()
Definition: hexrays.hpp:5822
virtual int visit_insn(cinsn_t *)
Visit a statement.
Definition: hexrays.hpp:5864
void clr_prune()
Do not prune children. This is an internal function, no need to call it.
Definition: hexrays.hpp:5820
parents_t parents
Vector of parents of the current item.
Definition: hexrays.hpp:5826
ctree_visitor_t(int _flags)
Constructor.
Definition: hexrays.hpp:5831
bool maintain_parents() const
Should the parent information by maintained?
Definition: hexrays.hpp:5807
int apply_to(citem_t *item, citem_t *parent)
Traverse ctree.
Definition: hexrays.hpp:11641
cexpr_t * parent_expr()
Get parent of the current item as an expression.
Definition: hexrays.hpp:5851
bool is_postorder() const
Should the leave...() functions be called?
Definition: hexrays.hpp:5813
bool must_restart() const
Should the traversal restart?
Definition: hexrays.hpp:5811
void clr_restart()
Do not restart. This is an internal function, no need to call it.
Definition: hexrays.hpp:5824
bool only_insns() const
Should all expressions be automatically pruned?
Definition: hexrays.hpp:5815
cinsn_t * parent_insn()
Get parent of the current item as a statement.
Definition: hexrays.hpp:5853
void prune_now()
Prune children.
Definition: hexrays.hpp:5818
int cv_flags
Ctree visitor property bits
Definition: hexrays.hpp:5791
bool must_prune() const
Should the traversal skip the children of the current item?
Definition: hexrays.hpp:5809
virtual int leave_insn(cinsn_t *)
Visit a statement after having visited its children.
Definition: hexrays.hpp:5880
int apply_to_exprs(citem_t *item, citem_t *parent)
Traverse only expressions.
Definition: hexrays.hpp:11647
While-loop.
Definition: hexrays.hpp:6430
Helper class to convert binary data structures into text and put into a file.
Definition: hexrays.hpp:878
FILE * fp
Output file pointer.
Definition: hexrays.hpp:879
Floating point constant.
Definition: hexrays.hpp:2396
fpvalue_t fnum
Internal representation of the number.
Definition: hexrays.hpp:2397
int nbytes
Original size of the constant in bytes.
Definition: hexrays.hpp:2398
Result of get_current_operand()
Definition: hexrays.hpp:5486
int regnum
if register, the register id
Definition: hexrays.hpp:5491
vivl_t cvt_to_ivl() const
Convert operand info to VIVL.
Definition: hexrays.hpp:5513
qstring name
register or stkvar name
Definition: hexrays.hpp:5487
bool append_to_list(mlist_t *list, const mba_t *mba) const
Append operand info to LIST.
Definition: hexrays.hpp:11561
sval_t stkoff
if stkvar, stack offset
Definition: hexrays.hpp:5490
int size
operand size
Definition: hexrays.hpp:5493
Exception object: decompiler failure information.
Definition: hexrays.hpp:5442
qstring str
string information
Definition: hexrays.hpp:5445
merror_t code
Microcode error codes
Definition: hexrays.hpp:5443
ea_t errea
associated address
Definition: hexrays.hpp:5444
Warning instances.
Definition: hexrays.hpp:4312
ea_t ea
Address where the warning occurred.
Definition: hexrays.hpp:4313
qstring text
Fully formatted text of the warning.
Definition: hexrays.hpp:4315
warnid_t id
Warning id.
Definition: hexrays.hpp:4314
Navigation history item.
Definition: hexrays.hpp:7576
ea_t end
BADADDR-decompile function; otherwise end of the range.
Definition: hexrays.hpp:7578
ea_t ea
The entry address of the decompiled function.
Definition: hexrays.hpp:7577
Local variable locator.
Definition: hexrays.hpp:1121
bool is_reg2() const
Is variable located on two registers?
Definition: hexrays.hpp:1141
bool is_reg1() const
Is variable located on one register?
Definition: hexrays.hpp:1139
const scattered_aloc_t & get_scattered() const
Get information about scattered variable.
Definition: hexrays.hpp:1153
bool is_scattered() const
Is variable scattered?
Definition: hexrays.hpp:1147
sval_t get_stkoff() const
Get offset of the varialbe in the stack frame.
Definition: hexrays.hpp:1134
bool is_stk_var() const
Is variable located on the stack?
Definition: hexrays.hpp:1145
bool is_reg_var() const
Is variable located on register(s)?
Definition: hexrays.hpp:1143
mreg_t get_reg2() const
Get the number of the second register (works only for ALOC_REG2 lvars)
Definition: hexrays.hpp:1151
vdloc_t location
Variable location.
Definition: hexrays.hpp:1122
mreg_t get_reg1() const
Get the register number of the variable.
Definition: hexrays.hpp:1149
Reference to a local variable. Used by mop_l.
Definition: hexrays.hpp:2277
int idx
index into mba->vars
Definition: hexrays.hpp:2287
mba_t *const mba
Pointer to the parent mba_t object.
Definition: hexrays.hpp:2285
lvar_t & var() const
Retrieve the referenced variable.
Definition: hexrays.hpp:10509
sval_t off
offset from the beginning of the variable
Definition: hexrays.hpp:2286
Saved user settings for local variables: name, type, comment.
Definition: hexrays.hpp:1425
qstring cmt
Comment.
Definition: hexrays.hpp:1429
tinfo_t type
Type.
Definition: hexrays.hpp:1428
lvar_locator_t ll
Variable locator.
Definition: hexrays.hpp:1426
qstring name
Name.
Definition: hexrays.hpp:1427
All user-defined information about local variables.
Definition: hexrays.hpp:1489
int ulv_flags
Various flags. Possible values are from lvar_uservec_t property bits.
Definition: hexrays.hpp:1507
uval_t stkoff_delta
Delta to add to IDA stack offset to calculate Hex-Rays stack offsets.
Definition: hexrays.hpp:1499
lvar_mapping_t lmaps
Local variable mapping (used for merging variables)
Definition: hexrays.hpp:1495
lvar_saved_infos_t lvvec
User-specified names, types, comments for lvars.
Definition: hexrays.hpp:1492
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:1394
int find_stkvar(sval_t spoff, int width)
Find stack variable at the specified location.
Definition: hexrays.hpp:10066
lvar_t * find(const lvar_locator_t &ll)
Find variable at the specified location.
Definition: hexrays.hpp:10072
int find_lvar(const vdloc_t &location, int width, int defblk=-1) const
Find variable at the specified location.
Definition: hexrays.hpp:10078
int find_input_lvar(const vdloc_t &argloc, int _size)
Find input variable at the specified location.
Definition: hexrays.hpp:1399
Item iterator for mba_ranges_t.
Definition: hexrays.hpp:4395
Chunk iterator for mba_ranges_t.
Definition: hexrays.hpp:4443
Ranges to decompile. Either a function or an explicit vector of ranges.
Definition: hexrays.hpp:4362
rangevec_t ranges
snippet mode: ranges to decompile.
Definition: hexrays.hpp:4364
func_t * pfn
function to decompile. if not null, then function mode.
Definition: hexrays.hpp:4363
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:2207
An integer constant.
Definition: hexrays.hpp:2370
Micro operand visitor.
Definition: hexrays.hpp:2220
bool prune
Should skip sub-operands of the current operand? visit_mop() may set 'prune=true' for that.
Definition: hexrays.hpp:2228
Number representation.
Definition: hexrays.hpp:780
bool is_char() const
Is a character constant?
Definition: hexrays.hpp:818
qstring type_name
for stroffs: structure for offsetof() for enums: enum name
Definition: hexrays.hpp:798
number_format_t(int _opnum=0)
Contructor.
Definition: hexrays.hpp:802
char opnum
operand number: 0..UA_MAXOP
Definition: hexrays.hpp:782
bool is_stroff() const
Is a structure field offset?
Definition: hexrays.hpp:820
bool is_hex() const
Is a hexadecimal number?
Definition: hexrays.hpp:810
bool is_numop() const
Is a number?
Definition: hexrays.hpp:822
char props
properties: combination of NF_ bits (Number format property bits)
Definition: hexrays.hpp:783
bool is_oct() const
Is a octal number?
Definition: hexrays.hpp:814
flags_t flags32
low 32bit of flags (for compatibility)
Definition: hexrays.hpp:781
char org_nbytes
original number size in bytes
Definition: hexrays.hpp:797
uchar serial
for enums: constant serial number
Definition: hexrays.hpp:796
bool is_dec() const
Is a decimal number?
Definition: hexrays.hpp:812
flags64_t flags
ida flags, which describe number radix, enum, etc
Definition: hexrays.hpp:800
bool is_enum() const
Is a symbolic constant?
Definition: hexrays.hpp:816
bool is_fixed() const
Is number representation fixed? Fixed representation cannot be modified by the decompiler.
Definition: hexrays.hpp:808
int get_radix() const
Get number radix.
Definition: hexrays.hpp:805
bool needs_to_be_inverted() const
Does the number need to be negated or bitwise negated? Returns true if the user requested a negation ...
Definition: hexrays.hpp:825
The context info used by visitors.
Definition: hexrays.hpp:2189
Operand locator.
Definition: hexrays.hpp:764
ea_t ea
address of the original processor instruction
Definition: hexrays.hpp:769
int opnum
operand number in the instruction
Definition: hexrays.hpp:770
User defined callback to optimize microcode blocks.
Definition: hexrays.hpp:2140
virtual int func(mblock_t *blk)=0
Optimize a block.
User defined callback to optimize individual microcode instructions.
Definition: hexrays.hpp:2109
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:894
bool with_tags
Generate output with color tags.
Definition: hexrays.hpp:895
qstring & s
Reference to the output string.
Definition: hexrays.hpp:896
qstring_printer_t(const cfunc_t *f, qstring &_s, bool tags)
Constructor.
Definition: hexrays.hpp:898
Chunk iterator of arbitrary rangevec items.
Definition: hexrays.hpp:4433
Item iterator of arbitrary rangevec items.
Definition: hexrays.hpp:4384
Scattered operand info. Used for mop_sc.
Definition: hexrays.hpp:2336
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:2351
mba_t * mba
Pointer to the parent mba_t object.
Definition: hexrays.hpp:2342
qstring name
Usually scattered operands are created from a function prototype, which has the name information.
Definition: hexrays.hpp:2347
Scattered mop: visit each of the scattered locations as a separate mop.
Definition: hexrays.hpp:2235
Reference to a stack variable. Used for mop_S.
Definition: hexrays.hpp:2309
sval_t off
Offset to the stack variable from the bottom of the stack frame.
Definition: hexrays.hpp:2318
mba_t *const mba
Pointer to the parent mba_t object.
Definition: hexrays.hpp:2313
member_t * get_stkvar(uval_t *p_off=nullptr) const
Retrieve the referenced stack variable.
Definition: hexrays.hpp:10521
Ctree location. Used to denote comment locations.
Definition: hexrays.hpp:5987
User-defined function calls.
Definition: hexrays.hpp:1640
Callback to apply the selection.
Definition: hexrays.hpp:7944
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:7929
uval_t offset
operand offset, will be used when calculating the UDT path
Definition: hexrays.hpp:7931
qstring text
any text for the column "Operand" of widget
Definition: hexrays.hpp:7930
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:5772
int idx
index into lvars_t
Definition: hexrays.hpp:5774
mba_t * mba
pointer to the underlying micro array
Definition: hexrays.hpp:5773
Helper class to convert cfunc_t into text.
Definition: hexrays.hpp:866
const cfunc_t * func
cfunc_t to generate text for
Definition: hexrays.hpp:867
virtual bool oneliner() const newapi
Are we generating one-line text representation?
Definition: hexrays.hpp:873
vc_printer_t(const cfunc_t *f)
Constructor.
Definition: hexrays.hpp:870
Exception object: decompiler exception.
Definition: hexrays.hpp:5455
Exception object: decompiler internal error.
Definition: hexrays.hpp:5470
Base helper class to convert binary data structures into text.
Definition: hexrays.hpp:849
int hdrlines
number of header lines (prototype+typedef+lvars) valid at the end of print process
Definition: hexrays.hpp:851
Information about the pseudocode window.
Definition: hexrays.hpp:7602
bool visible() const
Is the pseudocode window visible? if not, it might be invisible or destroyed.
Definition: hexrays.hpp:7613
bool rename_label(int label)
Rename a label.
Definition: hexrays.hpp:12532
TWidget * ct
pseudocode view
Definition: hexrays.hpp:7627
bool set_strmem_type(struc_t *sptr, member_t *mptr)
Set structure field type.
Definition: hexrays.hpp:12496
merror_t last_code
result of the last user action. See Microcode error codes
Definition: hexrays.hpp:7632
bool collapse_lvars(bool hide)
Collapse/uncollapse local variable declarations.
Definition: hexrays.hpp:12610
bool set_lvar_cmt(lvar_t *v, const char *cmt)
Set local variable comment.
Definition: hexrays.hpp:12472
bool set_global_type(ea_t ea)
Set global item type.
Definition: hexrays.hpp:12520
bool refresh_cpos(input_device_t idv)
Refresh the current position.
Definition: hexrays.hpp:12418
bool set_lvar_type(lvar_t *v, const tinfo_t &type)
Set local variable type.
Definition: hexrays.hpp:12454
void refresh_ctext(bool activate=true)
Refresh pseudocode window.
Definition: hexrays.hpp:12388
ctree_item_t head
First ctree item on the current line (for block comments)
Definition: hexrays.hpp:7636
bool map_lvar(lvar_t *from, lvar_t *to)
Map a local variable to another.
Definition: hexrays.hpp:12490
bool invert_bits()
Bitwise negate a number.
Definition: hexrays.hpp:12598
bool rename_strmem(struc_t *sptr, member_t *mptr)
Rename structure field.
Definition: hexrays.hpp:12508
bool ui_map_lvar(lvar_t *v)
Map a local variable to another.
Definition: hexrays.hpp:12478
void refresh_view(bool redo_mba)
Refresh pseudocode window.
Definition: hexrays.hpp:12382
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:12460
int get_current_label()
Get current label.
Definition: hexrays.hpp:12406
bool valid() const
Does the pseudocode window contain valid code? It can become invalid if the function type gets change...
Definition: hexrays.hpp:7616
bool ui_set_lvar_type(lvar_t *v)
Set local variable type.
Definition: hexrays.hpp:12448
void clear()
Clear the pseudocode window.
Definition: hexrays.hpp:12412
bool ui_rename_lvar(lvar_t *v)
Rename local variable.
Definition: hexrays.hpp:12430
ctree_item_t item
Current ctree item.
Definition: hexrays.hpp:7637
ctext_position_t cpos
Current ctext position.
Definition: hexrays.hpp:7635
bool invert_sign()
Negate a number.
Definition: hexrays.hpp:12592
bool in_ctree() const
Is the current item a statement?
Definition: hexrays.hpp:7669
bool edit_cmt(const treeloc_t &loc)
Edit an indented comment.
Definition: hexrays.hpp:12556
int view_idx
pseudocode window index (0..)
Definition: hexrays.hpp:7626
bool set_num_radix(int base)
Change number base.
Definition: hexrays.hpp:12574
bool edit_func_cmt()
Edit a function comment.
Definition: hexrays.hpp:12562
void switch_to(cfuncptr_t f, bool activate)
Display the specified pseudocode.
Definition: hexrays.hpp:12394
bool del_orphan_cmts()
Delete all orphan comments.
Definition: hexrays.hpp:12568
bool collapse_item(bool hide)
Collapse/uncollapse item.
Definition: hexrays.hpp:12604
mba_t * mba
pointer to underlying microcode
Definition: hexrays.hpp:7630
bool jump_enter(input_device_t idv, int omflags)
Process the Enter key.
Definition: hexrays.hpp:12538
bool split_item(bool split)
Split/unsplit item.
Definition: hexrays.hpp:12616
cfuncptr_t cfunc
pointer to function object
Definition: hexrays.hpp:7631
bool set_udm_type(tinfo_t &udt_type, int udm_idx)
Set structure field type.
Definition: hexrays.hpp:12502
bool rename_global(ea_t ea)
Rename global item.
Definition: hexrays.hpp:12526
bool rename_lvar(lvar_t *v, const char *name, bool is_user_name)
Rename local variable.
Definition: hexrays.hpp:12436
int flags
Properties of pseudocode window
Definition: hexrays.hpp:7603
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:12550
bool get_current_item(input_device_t idv)
Get current item.
Definition: hexrays.hpp:12424
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:12442
bool ctree_to_disasm()
Jump to disassembly.
Definition: hexrays.hpp:12544
bool set_num_enum()
Convert number to symbolic constant.
Definition: hexrays.hpp:12580
bool ui_edit_lvar_cmt(lvar_t *v)
Set local variable comment.
Definition: hexrays.hpp:12466
bool rename_udm(tinfo_t &udt_type, int udm_idx)
Rename structure field.
Definition: hexrays.hpp:12514
ctree_item_t tail
Tail ctree item on the current line (for indented comments)
Definition: hexrays.hpp:7638
cnumber_t * get_number()
Get current number.
Definition: hexrays.hpp:12400
bool ui_unmap_lvar(lvar_t *v)
Unmap a local variable.
Definition: hexrays.hpp:12484
bool locked() const
Does the pseudocode window contain valid code? We lock windows before modifying them,...
Definition: hexrays.hpp:7621
bool set_num_stroff()
Convert number to structure field offset.
Definition: hexrays.hpp:12586
Value interval (register or stack range)
Definition: hexrays.hpp:3243
uval_t intersect(const vivl_t &r)
Intersect value intervals the same type.
Definition: hexrays.hpp:10829
bool overlap(const vivl_t &r) const
Do two value intervals overlap?
Definition: hexrays.hpp:3268
bool contains(const voff_t &voff2) const
Does our value interval contain the specified value offset?
Definition: hexrays.hpp:3281
int size
Interval size in bytes.
Definition: hexrays.hpp:3244
bool includes(const vivl_t &r) const
Does our value interval include another?
Definition: hexrays.hpp:3274
bool extend_to_cover(const vivl_t &r)
Extend a value interval using another value interval of the same type.
Definition: hexrays.hpp:10823
Value offset (microregister number or stack offset)
Definition: hexrays.hpp:3206
sval_t off
register number or stack offset
Definition: hexrays.hpp:3207
mopt_t type
mop_r - register, mop_S - stack, mop_z - undefined
Definition: hexrays.hpp:3208