IDA C++ SDK 9.2
Loading...
Searching...
No Matches
gdl.hpp
Go to the documentation of this file.
1/*
2 * Interactive disassembler (IDA).
3 * Copyright (c) 1990-2025 Hex-Rays
4 * ALL RIGHTS RESERVED.
5 *
6 *
7 * Graph drawing support
8 *
9 */
10
11#ifndef __GDLDRAW_HPP
12#define __GDLDRAW_HPP
13
14#include <funcs.hpp>
15
21
22//-------------------------------------------------------------------------
23// forward declarations:
24class node_iterator;
25class qflow_chart_t;
26class gdl_graph_t;
27
40
41#ifndef SWIG
42#define DECLARE_HELPER(decl) \
43decl node_iterator *ida_export node_iterator_goup(node_iterator *); \
44decl void ida_export create_qflow_chart(qflow_chart_t &); \
45decl bool ida_export append_to_flowchart(qflow_chart_t &, ea_t, ea_t); \
46decl fc_block_type_t ida_export fc_calc_block_type(const qflow_chart_t &, size_t); \
47decl bool ida_export create_multirange_qflow_chart(qflow_chart_t &, const rangevec_t &);
48#else
49#define DECLARE_HELPER(decl)
50#endif // SWIG
51
52DECLARE_HELPER(idaman)
53
54//-------------------------------------------------------------------------
56class intset_t : public std::set<int>
57{
58public:
59 DEFINE_MEMORY_ALLOCATION_FUNCS()
60 size_t idaapi print(char *buf, size_t bufsize) const;
61 const char *idaapi dstr(void) const;
62 bool has(int value) const
63 {
64 const_iterator p = find(value);
65 const_iterator q = end();
66 return p != q;
67 }
68};
69
71
73class intmap_t : public std::map<int, int>
74{
75public:
77 size_t idaapi print(char *buf, size_t bufsize) const;
78 const char *idaapi dstr(void) const;
79};
80
82
83//-------------------------------------------------------------------------
85struct edge_t
86{
87 int src = 0;
88 int dst = 0;
89 edge_t(int x=0, int y=0) : src(x), dst(y) {}
90 bool operator < (const edge_t &y) const
91 { return src < y.src || (src == y.src && dst < y.dst); }
92 bool operator == (const edge_t &y) const
93 { return src == y.src && dst == y.dst; }
94 bool operator != (const edge_t &y) const
95 { return src != y.src || dst != y.dst; }
96};
98
99struct edgevec_t : public qvector<edge_t>
100{
101};
102
103struct edgeset_t;
104struct edge_segs_vec_t;
105struct edge_infos_t;
106struct destset_t;
107
109{
115 EDGE_SUBGRAPH = 5 // edge of a subgraph (used in collapse)
116};
117
118//-------------------------------------------------------------------------
120class node_set_t : public intset_t
121{
122public:
123 idaapi node_set_t(void) {}
124 idaapi node_set_t(int node) { insert(node); }
125 idaapi node_set_t(const gdl_graph_t *g);
126 bool idaapi add(int node) { return insert(node).second; }
127 void idaapi sub(int node) { erase(node); }
128 void idaapi sub(const node_set_t &r);
129 void idaapi add(const node_set_t &r);
130 void idaapi intersect(const node_set_t &r);
131 void idaapi extract(intvec_t &out) const;
132 int idaapi first(void) const { return empty() ? -1 : *begin(); }
133};
134
136
137//-------------------------------------------------------------------------
142{
143 intvec_t node_by_order;
144 intvec_t order_by_node;
145
146 void ensure_order_by_node()
147 {
148 if ( order_by_node.empty() )
149 {
150 size_t n = size();
151 order_by_node.resize(n, -1);
152 for ( size_t i = 0; i < n; i++ )
153 {
154 int idx = node_by_order[i];
155 if ( idx != -1 )
156 order_by_node[idx] = i;
157 }
158 }
159 }
160
161public:
163 void idaapi clear(void)
164 {
165 node_by_order.clear();
166 order_by_node.clear();
167 }
168
169 void idaapi resize(int n)
170 {
171 clear();
172 if ( n >= 0 )
173 node_by_order.resize(n, -1);
174 }
175
176 size_t idaapi size(void) const
177 {
178 return node_by_order.size();
179 }
180
181 void idaapi set(int _node, int num)
182 {
183 ensure_order_by_node();
184 if ( num >= 0 && num < node_by_order.size()
185 && _node >= 0 && _node < order_by_node.size() )
186 {
187 node_by_order[num] = _node;
188 order_by_node[_node] = num;
189 }
190 }
191
192 bool idaapi clr(int _node)
193 {
194 if ( _node < 0 )
195 return false;
196 ensure_order_by_node();
197 if ( _node >= order_by_node.size() )
198 return false;
199 int old = order_by_node[_node];
200 if ( old < 0 || old >= node_by_order.size() )
201 return false;
202 order_by_node[_node] = -1;
203 node_by_order[old] = -1;
204 // shift all order numbers higher than the deleted order number by one
205 size_t n = size();
206 for ( size_t i = 0; i < n; i++ )
207 if ( order_by_node[i] > old )
208 order_by_node[i]--;
209 int rest = n - old - 1;
210 if ( rest > 0 )
211 memmove(&node_by_order[old], &node_by_order[old+1], rest*sizeof(int));
212 return true;
213 }
214
215 int idaapi node(size_t _order) const
216 {
217 return _order < node_by_order.size() ? node_by_order[_order] : -1;
218 }
219
220 int idaapi order(int _node)
221 {
222 ensure_order_by_node();
223 return (_node >= 0 && _node < order_by_node.size()) ? order_by_node[_node] : -1;
224 }
225};
226
227//-------------------------------------------------------------------------
230{
231 DECLARE_HELPER(friend)
232 friend class gdl_graph_t;
233 const gdl_graph_t *g;
234 int i;
235 node_iterator &_goup(void);
236 node_iterator &goup(void) { return *node_iterator_goup(this); }
237public:
238 node_iterator(const gdl_graph_t *_g, int n) : g(_g), i(n) {}
239 node_iterator &operator++(void) { i++; return goup(); }
240 bool operator==(const node_iterator &n) const { return i == n.i && g == n.g; }
241 bool operator!=(const node_iterator &n) const { return !(*this == n); }
242 int operator*(void) const { return i; }
243};
244
245//-------------------------------------------------------------------------
248{
249 // does a path from 'm' to 'n' exist?
250 bool idaapi path(node_set_t &visited, int m, int n) const;
251public:
254 virtual char *idaapi get_node_label(char *iobuf, int iobufsize, int n) const { qnotused(iobufsize); qnotused(n); iobuf[0] = '\0'; return iobuf; }
255 virtual void idaapi print_graph_attributes(FILE *fp) const { qnotused(fp); }
256 virtual bool idaapi print_node(FILE *fp, int n) const { qnotused(fp); qnotused(n); return false; }
257 virtual bool idaapi print_edge(FILE *fp, int i, int j) const { qnotused(fp); qnotused(i); qnotused(j); return false; }
258 virtual void idaapi print_node_attributes(FILE *fp, int n) const { qnotused(fp); qnotused(n); }
259 virtual int idaapi size(void) const = 0; // number of the max node number
260 virtual int idaapi node_qty(void) const { return size(); } // number of alive nodes
261 virtual bool idaapi exists(int node) const { qnotused(node); return true; }
262 virtual int idaapi entry(void) const { return 0; }
263 virtual int idaapi exit(void) const { return size()-1; }
264 virtual int idaapi nsucc(int node) const = 0;
265 virtual int idaapi npred(int node) const = 0;
266 virtual int idaapi succ(int node, int i) const = 0;
267 virtual int idaapi pred(int node, int i) const = 0;
268 virtual bool idaapi empty(void) const { return node_qty() == 0; }
269 virtual bgcolor_t idaapi get_node_color(int n) const { qnotused(n); return DEFCOLOR; }
270 virtual bgcolor_t idaapi get_edge_color(int i, int j) const { qnotused(i); qnotused(j); return DEFCOLOR; }
271 void idaapi gen_gdl(FILE *fp) const;
272 void idaapi gen_gdl(const char *file) const;
273 size_t idaapi nedge(int node, bool ispred) const { return ispred ? npred(node) : nsucc(node); }
274 int idaapi edge(int node, int i, bool ispred) const { return ispred ? pred(node, i) : succ(node, i); }
275 int idaapi front(void) { return *begin(); }
276 node_iterator idaapi begin(void) const { return node_iterator(this, 0).goup(); }
277 node_iterator idaapi end(void) const { return node_iterator(this, size()); }
278 // does a path from 'm' to 'n' exist?
279 bool idaapi path_exists(int m, int n) const { node_set_t v; return path(v, m, n); }
280
281 void idaapi gen_dot(FILE *fp) const;
282 void idaapi gen_dot(const char *file) const;
283};
284
285
287
288idaman void ida_export gen_gdl(const gdl_graph_t *g, const char *fname);
289
290
297
298idaman int ida_export display_gdl(const char *fname);
299
300
301//-------------------------------------------------------------------------
302// Build and display program graphs
303
313
314idaman bool ida_export gen_flow_graph(
315 const char *filename,
316 const char *title,
317 func_t *pfn,
318 ea_t ea1,
319 ea_t ea2,
320 int gflags);
321
328#define CHART_PRINT_NAMES 0x1000
329#define CHART_GEN_DOT 0x2000
330#define CHART_GEN_GDL 0x4000
331#define CHART_WINGRAPH 0x8000
333
334
343
344idaman bool ida_export gen_simple_call_chart(
345 const char *filename,
346 const char *wait,
347 const char *title,
348 int gflags);
349
350
361
362idaman bool ida_export gen_complex_call_chart(
363 const char *filename,
364 const char *wait,
365 const char *title,
366 ea_t ea1,
367 ea_t ea2,
368 int flags,
369 int32 recursion_depth=-1);
370
374#define CHART_NOLIBFUNCS 0x0400
375#define CHART_REFERENCING 0x0001
376#define CHART_REFERENCED 0x0002
377#define CHART_RECURSIVE 0x0004
378#define CHART_FOLLOW_DIRECTION 0x0008
379#define CHART_IGNORE_XTRN 0x0010
380#define CHART_IGNORE_DATA_BSS 0x0020
381#define CHART_IGNORE_LIB_TO 0x0040
382#define CHART_IGNORE_LIB_FROM 0x0080
383#define CHART_PRINT_COMMENTS 0x0100
384#define CHART_PRINT_DOTS 0x0200
386
387
391
392idaman void ida_export setup_graph_subsystem(const char *_grapher, bgcolor_t (idaapi *get_graph_color)(int color));
393
394
396{
397public:
398 mutable bool cancelled = false;
399 char padding[3]; // make the class nicely aligned. otherwise we have
400 // problems with gcc in qflow_chart_t.
402 bool idaapi check_cancel(void) const;
403};
404
405//--------------------------------------------------------------------------
412
414inline THREAD_SAFE bool is_noret_block(fc_block_type_t btype)
415{
416 return btype == fcb_noret || btype == fcb_enoret;
417}
418
420inline THREAD_SAFE bool is_ret_block(fc_block_type_t btype)
421{
422 return btype == fcb_ret || btype == fcb_cndret;
423}
424
428#define FC_PRINT 0x0001
429#define FC_NOEXT 0x0002
433#define FC_RESERVED 0x0004
434#define FC_APPND 0x0008
435#define FC_CHKBREAK 0x0010
436#define FC_CALL_ENDS 0x0020
437#define FC_NOPREDS 0x0040
438#define FC_OUTLINES 0x0080
440
443{
444public:
447 qstring title;
449 func_t *pfn = nullptr;
450 int flags = 0;
452 int nproper = 0;
453
454 idaapi qflow_chart_t(void) {}
455 idaapi qflow_chart_t(const char *_title, func_t *_pfn, ea_t _ea1, ea_t _ea2, int _flags)
456 : title(_title), bounds(_ea1, _ea2), pfn(_pfn), flags(_flags)
457 {
458 refresh();
459 }
460 virtual ~qflow_chart_t() {}
461 void idaapi create(const char *_title, func_t *_pfn, ea_t _ea1, ea_t _ea2, int _flags)
462 {
463 title = _title;
464 pfn = _pfn;
465 bounds = range_t(_ea1, _ea2);
466 flags = _flags;
467 refresh();
468 }
469 void idaapi create(const char *_title, const rangevec_t &ranges, int _flags)
470 {
471 title = _title;
472 flags = _flags;
473 create_multirange_qflow_chart(*this, ranges);
474 }
475 void idaapi append_to_flowchart(ea_t ea1, ea_t ea2) { ::append_to_flowchart(*this, ea1, ea2); }
476 void idaapi refresh(void) { create_qflow_chart(*this); }
477 fc_block_type_t calc_block_type(size_t blknum) const
478 { return fc_calc_block_type(*this, blknum); }
479 bool is_ret_block(size_t blknum) const { return ::is_ret_block(calc_block_type(blknum)); }
480 bool is_noret_block(size_t blknum) const { return ::is_noret_block(calc_block_type(blknum)); }
481 virtual void idaapi print_node_attributes(FILE *fp, int n) const override { qnotused(fp); qnotused(n); }
482 virtual int idaapi nsucc(int node) const override { return int(blocks[node].succ.size()); }
483 virtual int idaapi npred(int node) const override { return int(blocks[node].pred.size()); }
484 virtual int idaapi succ(int node, int i) const override { return blocks[node].succ[i]; }
485 virtual int idaapi pred(int node, int i) const override { return blocks[node].pred[i]; }
486 virtual char *idaapi get_node_label(char *iobuf, int iobufsize, int n) const override { qnotused(iobuf); qnotused(iobufsize); qnotused(n); return nullptr; }
487 virtual int idaapi size(void) const override { return int(blocks.size()); }
488 bool idaapi print_names(void) const { return (flags & FC_PRINT) != 0; }
489};
490
491#endif // __GDLDRAW_HPP
Definition gdl.hpp:396
bool cancelled
Definition gdl.hpp:398
char padding[3]
Definition gdl.hpp:399
bool idaapi check_cancel(void) const
virtual ~cancellable_graph_t()
Definition gdl.hpp:401
A function is a set of continuous ranges of addresses with characteristics.
Definition funcs.hpp:85
gdl graph interface - includes only functions required to draw it
Definition gdl.hpp:248
virtual int idaapi npred(int node) const =0
void idaapi gen_gdl(const char *file) const
int idaapi edge(int node, int i, bool ispred) const
Definition gdl.hpp:274
size_t idaapi nedge(int node, bool ispred) const
Definition gdl.hpp:273
virtual bool idaapi exists(int node) const
Definition gdl.hpp:261
virtual void idaapi print_graph_attributes(FILE *fp) const
Definition gdl.hpp:255
virtual int idaapi pred(int node, int i) const =0
virtual char *idaapi get_node_label(char *iobuf, int iobufsize, int n) const
Definition gdl.hpp:254
virtual bool idaapi print_edge(FILE *fp, int i, int j) const
Definition gdl.hpp:257
virtual int idaapi exit(void) const
Definition gdl.hpp:263
node_iterator idaapi end(void) const
Definition gdl.hpp:277
virtual int idaapi node_qty(void) const
Definition gdl.hpp:260
void idaapi gen_dot(const char *file) const
virtual int idaapi nsucc(int node) const =0
virtual void idaapi print_node_attributes(FILE *fp, int n) const
Definition gdl.hpp:258
virtual bool idaapi print_node(FILE *fp, int n) const
Definition gdl.hpp:256
virtual int idaapi succ(int node, int i) const =0
DEFINE_MEMORY_ALLOCATION_FUNCS() virtual ~gdl_graph_t()
Definition gdl.hpp:252
void idaapi gen_dot(FILE *fp) const
virtual int idaapi size(void) const =0
virtual int idaapi entry(void) const
Definition gdl.hpp:262
virtual bgcolor_t idaapi get_edge_color(int i, int j) const
Definition gdl.hpp:270
bool idaapi path_exists(int m, int n) const
Definition gdl.hpp:279
virtual bgcolor_t idaapi get_node_color(int n) const
Definition gdl.hpp:269
node_iterator idaapi begin(void) const
Definition gdl.hpp:276
int idaapi front(void)
Definition gdl.hpp:275
virtual bool idaapi empty(void) const
Definition gdl.hpp:268
void idaapi gen_gdl(FILE *fp) const
Map of integer constants to integer constants.
Definition gdl.hpp:74
DEFINE_MEMORY_ALLOCATION_FUNCS() size_t idaapi print(char *buf
size_t bufsize const
Definition gdl.hpp:77
const char *idaapi dstr(void) const
Node iterator (used to draw graphs)
Definition gdl.hpp:230
node_iterator(const gdl_graph_t *_g, int n)
Definition gdl.hpp:238
bool operator==(const node_iterator &n) const
Definition gdl.hpp:240
node_iterator & operator++(void)
Definition gdl.hpp:239
int operator*(void) const
Definition gdl.hpp:242
bool operator!=(const node_iterator &n) const
Definition gdl.hpp:241
Node ordering in a graph.
Definition gdl.hpp:142
bool idaapi clr(int _node)
Definition gdl.hpp:192
size_t idaapi size(void) const
Definition gdl.hpp:176
void idaapi resize(int n)
Definition gdl.hpp:169
int idaapi order(int _node)
Definition gdl.hpp:220
void idaapi set(int _node, int num)
Definition gdl.hpp:181
int idaapi node(size_t _order) const
Definition gdl.hpp:215
DEFINE_MEMORY_ALLOCATION_FUNCS() void idaapi clear(void)
Definition gdl.hpp:162
Set of graph nodes.
Definition gdl.hpp:121
bool idaapi add(int node)
Definition gdl.hpp:126
void idaapi sub(int node)
Definition gdl.hpp:127
int idaapi first(void) const
Definition gdl.hpp:132
idaapi node_set_t(void)
Definition gdl.hpp:123
void idaapi extract(intvec_t &out) const
void idaapi sub(const node_set_t &r)
idaapi node_set_t(const gdl_graph_t *g)
idaapi node_set_t(int node)
Definition gdl.hpp:124
void idaapi intersect(const node_set_t &r)
void idaapi add(const node_set_t &r)
A flow chart for a function, or a set of address ranges.
Definition gdl.hpp:443
void idaapi create(const char *_title, const rangevec_t &ranges, int _flags)
Definition gdl.hpp:469
idaapi qflow_chart_t(const char *_title, func_t *_pfn, ea_t _ea1, ea_t _ea2, int _flags)
Definition gdl.hpp:455
virtual void idaapi print_node_attributes(FILE *fp, int n) const override
Definition gdl.hpp:481
bool is_ret_block(size_t blknum) const
Definition gdl.hpp:479
virtual char *idaapi get_node_label(char *iobuf, int iobufsize, int n) const override
Definition gdl.hpp:486
idaapi qflow_chart_t(void)
Definition gdl.hpp:454
range_t bounds
overall bounds of the qflow_chart_t instance
Definition gdl.hpp:448
virtual int idaapi nsucc(int node) const override
Definition gdl.hpp:482
virtual int idaapi pred(int node, int i) const override
Definition gdl.hpp:485
virtual int idaapi succ(int node, int i) const override
Definition gdl.hpp:484
blocks_t blocks
basic blocks
Definition gdl.hpp:451
void idaapi create(const char *_title, func_t *_pfn, ea_t _ea1, ea_t _ea2, int _flags)
Definition gdl.hpp:461
virtual ~qflow_chart_t()
Definition gdl.hpp:460
func_t * pfn
the function this instance was built upon
Definition gdl.hpp:449
fc_block_type_t calc_block_type(size_t blknum) const
Definition gdl.hpp:477
void idaapi refresh(void)
Definition gdl.hpp:476
bool idaapi print_names(void) const
Definition gdl.hpp:488
DECLARE_HELPER(friend) qstring title
int flags
flags. See Flow chart flags
Definition gdl.hpp:450
bool is_noret_block(size_t blknum) const
Definition gdl.hpp:480
qvector< qbasic_block_t > blocks_t
Definition gdl.hpp:445
virtual int idaapi npred(int node) const override
Definition gdl.hpp:483
void idaapi append_to_flowchart(ea_t ea1, ea_t ea2)
Definition gdl.hpp:475
virtual int idaapi size(void) const override
Definition gdl.hpp:487
int nproper
number of basic blocks belonging to the specified range
Definition gdl.hpp:452
Reimplementation of vector class from STL.
Definition pro.h:2250
qvector(void)
Definition pro.h:2328
Routines for working with functions within the disassembled program.
THREAD_SAFE bool is_noret_block(fc_block_type_t btype)
Does this block never return?
Definition gdl.hpp:414
idaman void ida_export gen_gdl(const gdl_graph_t *g, const char *fname)
Create GDL file for graph.
qvector< node_set_t > array_of_node_set_t
Definition gdl.hpp:135
idaman bool ida_export gen_simple_call_chart(const char *filename, const char *wait, const char *title, int gflags)
Build and display a simple function call graph.
DECLARE_TYPE_AS_MOVABLE(edge_t)
idaman bool ida_export gen_flow_graph(const char *filename, const char *title, func_t *pfn, ea_t ea1, ea_t ea2, int gflags)
Build and display a flow graph.
idaman int ida_export display_gdl(const char *fname)
Display GDL file by calling wingraph32.
idaman void ida_export setup_graph_subsystem(const char *_grapher, bgcolor_t(idaapi *get_graph_color)(int color))
Setup the user-defined graph colors and graph viewer program.
idaman bool ida_export gen_complex_call_chart(const char *filename, const char *wait, const char *title, ea_t ea1, ea_t ea2, int flags, int32 recursion_depth=-1)
Build and display a complex xref graph.
qvector< intmap_t > array_of_intmap_t
Definition gdl.hpp:81
edge_type_t
Definition gdl.hpp:109
@ EDGE_FORWARD
Definition gdl.hpp:112
@ EDGE_NONE
Definition gdl.hpp:110
@ EDGE_CROSS
Definition gdl.hpp:114
@ EDGE_SUBGRAPH
Definition gdl.hpp:115
@ EDGE_BACK
Definition gdl.hpp:113
@ EDGE_TREE
Definition gdl.hpp:111
DECLARE_HELPER(idaman) class intset_t typedef qvector< intvec_t > array_of_intvec_t
Set of integer constants.
Definition gdl.hpp:52
THREAD_SAFE bool is_ret_block(fc_block_type_t btype)
Does this block return?
Definition gdl.hpp:420
fc_block_type_t
Flow chart block types.
Definition gdl.hpp:30
@ fcb_normal
normal block
Definition gdl.hpp:31
@ fcb_ret
return block
Definition gdl.hpp:33
@ fcb_noret
noreturn block
Definition gdl.hpp:35
@ fcb_enoret
external noreturn block (does not belong to the function)
Definition gdl.hpp:36
@ fcb_cndret
conditional return block
Definition gdl.hpp:34
@ fcb_error
block passes execution past the function end
Definition gdl.hpp:38
@ fcb_indjump
block ends with indirect jump
Definition gdl.hpp:32
@ fcb_extern
external normal block
Definition gdl.hpp:37
idaman const char * end
Definition pro.h:1001
idaman size_t n
Definition pro.h:997
const char *hexapi dstr(const tinfo_t *tif)
Print the specified type info.
Definition hexrays.hpp:10432
asize_t size
Definition kernwin.hpp:6339
void(idaapi *range_marker)(ea_t ea
Pointer to range marker function (for idaviews and hexviews) This pointer is initialized by setup_ran...
qvector< int > intvec_t
vector of integers
Definition pro.h:2765
uint32 bgcolor_t
background color in RGB
Definition pro.h:5012
uint64 ea_t
Definition pro.h:421
int int32
signed 32 bit value
Definition pro.h:347
idaman size_t bufsize
Definition pro.h:600
_qstring< char > qstring
regular string
Definition pro.h:3694
Edge connecting two graph nodes.
Definition gdl.hpp:86
edge_t(int x=0, int y=0)
Definition gdl.hpp:89
int dst
destination node number
Definition gdl.hpp:88
int src
source node number
Definition gdl.hpp:87
Definition gdl.hpp:100
Information about a basic block of a qflow_chart_t.
Definition gdl.hpp:408
intvec_t pred
list of node predecessors
Definition gdl.hpp:410
intvec_t succ
list of node successors
Definition gdl.hpp:409
Base class for an range.
Definition range.hpp:35
range_t(ea_t ea1=0, ea_t ea2=0)
Definition range.hpp:39
Vector of range_t instances.
Definition range.hpp:93
THREAD_SAFE bool operator<(const bytevec_t &v1, const bytevec_t &v2)
Compare two bytevecs with '<'.
Definition typeinf.hpp:631