libTriton version 1.0 build 1590
Loading...
Searching...
No Matches
astContext.cpp
Go to the documentation of this file.
1
2/*
3** Copyright (C) - Triton
4**
5** This program is under the terms of the Apache License 2.0.
6*/
7
8#include <list>
9#include <memory>
10#include <vector>
11
12#include <triton/ast.hpp>
13#include <triton/astContext.hpp>
14#include <triton/exceptions.hpp>
17
18
19
20namespace triton {
21 namespace ast {
22
24 : modes(modes) {
25 }
26
27
29 this->valueMapping.clear();
30 this->nodes.clear();
31 }
32
33
35 std::enable_shared_from_this<AstContext>::operator=(other);
36
37 this->astRepresentation = other.astRepresentation;
38 this->modes = other.modes;
39 this->nodes = other.nodes;
40 this->valueMapping = other.valueMapping;
41
42 return *this;
43 }
44
45
47 /*
48 * We keep references to nodes which belong to a depth in the AST which is
49 * a multiple of 10000. Thus, when the root node is destroyed, the stack recursivity
50 * stops when the depth level of 10000 is reached, because the nodes there still
51 * have a reference to them in the AST manager. The destruction will continue at the
52 * next allocation of nodes and so on. So, it means that ASTs are destroyed by steps
53 * of depth of 10000 which avoids the overflow while keeping a good scale.
54 *
55 * See: #753.
56 */
57 triton::uint32 lvl = node->getLevel();
58 if (lvl != 0 && (lvl % 10000) == 0) {
59 this->nodes.push_front(node);
60 }
61 return node;
62 }
63
64
66 this->nodes.erase(std::remove_if(this->nodes.begin(), this->nodes.end(),
67 [](const SharedAbstractNode& n) {
68 return (n.use_count() == 1 ? true : false);
69 }), this->nodes.end()
70 );
71 }
72
73
75 SharedAbstractNode node = std::make_shared<ArrayNode>(indexSize, this->shared_from_this());
76 if (node == nullptr)
77 throw triton::exceptions::Ast("AstContext::array(): Not enough memory.");
78 node->init();
79 return this->collect(node);
80 }
81
82
84 SharedAbstractNode node = std::make_shared<AssertNode>(expr);
85 if (node == nullptr)
86 throw triton::exceptions::Ast("AstContext::assert_(): Not enough memory.");
87 node->init();
88 return this->collect(node);
89 }
90
91
93 SharedAbstractNode node = std::make_shared<BswapNode>(expr);
94 if (node == nullptr)
95 throw triton::exceptions::Ast("AstContext::bswap(): Not enough memory.");
96 node->init();
97 return this->collect(node);
98 }
99
100
102 SharedAbstractNode node = std::make_shared<BvNode>(value, size, this->shared_from_this());
103 if (node == nullptr)
104 throw triton::exceptions::Ast("AstContext::bv(): Not enough memory.");
105 node->init();
106 return this->collect(node);
107 }
108
109
111 if (this->modes->isModeEnabled(triton::modes::AST_OPTIMIZATIONS)) {
112 /* Optimization: 0 + A = A */
113 if (!expr1->isSymbolized() && expr1->evaluate() == 0)
114 return expr2;
115
116 /* Optimization: A + 0 = A */
117 if (!expr2->isSymbolized() && expr2->evaluate() == 0)
118 return expr1;
119 }
120
121 SharedAbstractNode node = std::make_shared<BvaddNode>(expr1, expr2);
122 if (node == nullptr)
123 throw triton::exceptions::Ast("AstContext::bvadd(): Not enough memory.");
124 node->init();
125
126 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
127 if (node->isSymbolized() == false) {
128 return this->bv(node->evaluate(), node->getBitvectorSize());
129 }
130 }
131
132 return this->collect(node);
133 }
134
135
137 if (this->modes->isModeEnabled(triton::modes::AST_OPTIMIZATIONS)) {
138 /* Optimization: 0 & A = 0 */
139 if (!expr1->isSymbolized() && expr1->evaluate() == 0)
140 return this->bv(0, expr1->getBitvectorSize());
141
142 /* Optimization: A & 0 = 0 */
143 if (!expr2->isSymbolized() && expr2->evaluate() == 0)
144 return this->bv(0, expr1->getBitvectorSize());
145
146 /* Optimization: A & -1 = A */
147 if (!expr2->isSymbolized() && expr2->evaluate() == expr2->getBitvectorMask())
148 return expr1;
149
150 /* Optimization: -1 & A = A */
151 if (!expr1->isSymbolized() && expr1->evaluate() == expr1->getBitvectorMask())
152 return expr2;
153
154 /* Optimization: A & A = A */
155 if (!expr1->isSymbolized() && !expr2->isSymbolized() && expr1->equalTo(expr2))
156 return expr1;
157 }
158
159 SharedAbstractNode node = std::make_shared<BvandNode>(expr1, expr2);
160 if (node == nullptr)
161 throw triton::exceptions::Ast("AstContext::bvand(): Not enough memory.");
162 node->init();
163
164 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
165 if (node->isSymbolized() == false) {
166 return this->bv(node->evaluate(), node->getBitvectorSize());
167 }
168 }
169
170 return this->collect(node);
171 }
172
173
175 if (this->modes->isModeEnabled(triton::modes::AST_OPTIMIZATIONS)) {
176 /* Optimization: 0 >> A = 0 */
177 if (!expr1->isSymbolized() && expr1->evaluate() == 0)
178 return this->bv(0, expr1->getBitvectorSize());
179
180 /* Optimization: A >> 0 = A */
181 if (!expr2->isSymbolized() && expr2->evaluate() == 0)
182 return expr1;
183 }
184
185 SharedAbstractNode node = std::make_shared<BvashrNode>(expr1, expr2);
186 if (node == nullptr)
187 throw triton::exceptions::Ast("AstContext::bvashr(): Not enough memory.");
188 node->init();
189
190 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
191 if (node->isSymbolized() == false) {
192 return this->bv(node->evaluate(), node->getBitvectorSize());
193 }
194 }
195
196 return this->collect(node);
197 }
198
199
201 SharedAbstractNode node = std::make_shared<BvNode>(0, 1, this->shared_from_this());
202 if (node == nullptr)
203 throw triton::exceptions::Ast("AstContext::bvfalse(): Not enough memory.");
204 node->init();
205 return this->collect(node);
206 }
207
208
210 if (this->modes->isModeEnabled(triton::modes::AST_OPTIMIZATIONS)) {
211 /* Optimization: 0 >> A = 0 */
212 if (!expr1->isSymbolized() && expr1->evaluate() == 0)
213 return this->bv(0, expr1->getBitvectorSize());
214
215 /* Optimization: A >> 0 = A */
216 if (!expr2->isSymbolized() && expr2->evaluate() == 0)
217 return expr1;
218
219 /* Optimization: A >> B>=size(A) = 0 */
220 if (!expr2->isSymbolized() && expr2->evaluate() >= expr1->getBitvectorSize())
221 return this->bv(0, expr1->getBitvectorSize());
222 }
223
224 SharedAbstractNode node = std::make_shared<BvlshrNode>(expr1, expr2);
225 if (node == nullptr)
226 throw triton::exceptions::Ast("AstContext::bvlshr(): Not enough memory.");
227 node->init();
228
229 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
230 if (node->isSymbolized() == false) {
231 return this->bv(node->evaluate(), node->getBitvectorSize());
232 }
233 }
234
235 return this->collect(node);
236 }
237
238
240 if (this->modes->isModeEnabled(triton::modes::AST_OPTIMIZATIONS)) {
241 /* Optimization: 0 * A = 0 */
242 if (!expr1->isSymbolized() && expr1->evaluate() == 0)
243 return this->bv(0, expr1->getBitvectorSize());
244
245 /* Optimization: A * 0 = 0 */
246 if (!expr2->isSymbolized() && expr2->evaluate() == 0)
247 return this->bv(0, expr1->getBitvectorSize());
248
249 /* Optimization: 1 * A = A */
250 if (!expr1->isSymbolized() && expr1->evaluate() == 1)
251 return expr2;
252
253 /* Optimization: A * 1 = A */
254 if (!expr2->isSymbolized() && expr2->evaluate() == 1)
255 return expr1;
256 }
257
258 SharedAbstractNode node = std::make_shared<BvmulNode>(expr1, expr2);
259 if (node == nullptr)
260 throw triton::exceptions::Ast("AstContext::bvmul(): Not enough memory.");
261 node->init();
262
263 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
264 if (node->isSymbolized() == false) {
265 return this->bv(node->evaluate(), node->getBitvectorSize());
266 }
267 }
268
269 return this->collect(node);
270 }
271
272
274 SharedAbstractNode node = std::make_shared<BvnandNode>(expr1, expr2);
275 if (node == nullptr)
276 throw triton::exceptions::Ast("AstContext::bvnand(): Not enough memory.");
277 node->init();
278
279 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
280 if (node->isSymbolized() == false) {
281 return this->bv(node->evaluate(), node->getBitvectorSize());
282 }
283 }
284
285 return this->collect(node);
286 }
287
288
290 SharedAbstractNode node = std::make_shared<BvnegNode>(expr);
291 if (node == nullptr)
292 throw triton::exceptions::Ast("AstContext::bvneg(): Not enough memory.");
293 node->init();
294
295 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
296 if (node->isSymbolized() == false) {
297 return this->bv(node->evaluate(), node->getBitvectorSize());
298 }
299 }
300
301 return this->collect(node);
302 }
303
304
306 SharedAbstractNode node = std::make_shared<BvnorNode>(expr1, expr2);
307 if (node == nullptr)
308 throw triton::exceptions::Ast("AstContext::bvnor(): Not enough memory.");
309 node->init();
310
311 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
312 if (node->isSymbolized() == false) {
313 return this->bv(node->evaluate(), node->getBitvectorSize());
314 }
315 }
316
317 return this->collect(node);
318 }
319
320
322 SharedAbstractNode node = std::make_shared<BvnotNode>(expr);
323 if (node == nullptr)
324 throw triton::exceptions::Ast("AstContext::bvnot(): Not enough memory.");
325 node->init();
326
327 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
328 if (node->isSymbolized() == false) {
329 return this->bv(node->evaluate(), node->getBitvectorSize());
330 }
331 }
332
333 return this->collect(node);
334 }
335
336
338 if (this->modes->isModeEnabled(triton::modes::AST_OPTIMIZATIONS)) {
339 /* Optimization: 0 | A = A */
340 if (!expr1->isSymbolized() && expr1->evaluate() == 0)
341 return expr2;
342
343 /* Optimization: A | 0 = A */
344 if (!expr2->isSymbolized() && expr2->evaluate() == 0)
345 return expr1;
346
347 /* Optimization: -1 | A = -1 */
348 if (!expr1->isSymbolized() && expr1->evaluate() == expr1->getBitvectorMask())
349 return this->bv(expr1->getBitvectorMask(), expr1->getBitvectorSize());
350
351 /* Optimization: A | -1 = -1 */
352 if (!expr2->isSymbolized() && expr2->evaluate() == expr2->getBitvectorMask())
353 return this->bv(expr2->getBitvectorMask(), expr2->getBitvectorSize());
354
355 /* Optimization: A | A = A */
356 if (expr1->equalTo(expr2))
357 return expr1;
358 }
359
360 SharedAbstractNode node = std::make_shared<BvorNode>(expr1, expr2);
361 if (node == nullptr)
362 throw triton::exceptions::Ast("AstContext::bvor(): Not enough memory.");
363 node->init();
364
365 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
366 if (node->isSymbolized() == false) {
367 return this->bv(node->evaluate(), node->getBitvectorSize());
368 }
369 }
370
371 return this->collect(node);
372 }
373
374
376 SharedAbstractNode node = std::make_shared<BvrolNode>(expr, rot);
377 if (node == nullptr)
378 throw triton::exceptions::Ast("AstContext::bvrol(): Not enough memory.");
379 node->init();
380
381 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
382 if (node->isSymbolized() == false) {
383 return this->bv(node->evaluate(), node->getBitvectorSize());
384 }
385 }
386
387 return this->collect(node);
388 }
389
390
392 /*
393 * If the mode SYMBOLIZE_INDEX_ROTATION we apply a AST transformation
394 * in order to make index rotation symbolic. Note that this mode increases the
395 * complexity of solving.
396 *
397 * bvrol(expr, rot) = ((expr << (rot % size)) | (expr >> (size - (rot % size))))
398 **/
399 if (this->modes->isModeEnabled(triton::modes::SYMBOLIZE_INDEX_ROTATION)) {
400 auto size = expr->getBitvectorSize();
401 auto bvsize = this->bv(size, size);
402 const auto& node = this->bvor(
403 this->bvshl(expr, this->bvsmod(rot, bvsize)),
404 this->bvlshr(expr, this->bvsub(bvsize, this->bvsmod(rot, bvsize)))
405 );
406 return node;
407 }
408
409 /* Otherwise, we concretize the index rotation */
410 SharedAbstractNode node = std::make_shared<BvrolNode>(expr, this->integer(rot->evaluate()));
411 if (node == nullptr)
412 throw triton::exceptions::Ast("AstContext::bvrol(): Not enough memory.");
413 node->init();
414
415 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
416 if (node->isSymbolized() == false) {
417 return this->bv(node->evaluate(), node->getBitvectorSize());
418 }
419 }
420
421 return this->collect(node);
422 }
423
424
426 SharedAbstractNode node = std::make_shared<BvrorNode>(expr, rot);
427 if (node == nullptr)
428 throw triton::exceptions::Ast("AstContext::bvror(): Not enough memory.");
429 node->init();
430
431 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
432 if (node->isSymbolized() == false) {
433 return this->bv(node->evaluate(), node->getBitvectorSize());
434 }
435 }
436
437 return this->collect(node);
438 }
439
440
442 /*
443 * If the mode SYMBOLIZE_INDEX_ROTATION we apply a AST transformation
444 * in order to make index rotation symbolic. Note that this mode increases the
445 * complexity of solving.
446 *
447 * bvror(expr, rot) = ((expr >> (rot % size)) | (expr << (size - (rot % size))))
448 **/
449 if (this->modes->isModeEnabled(triton::modes::SYMBOLIZE_INDEX_ROTATION)) {
450 auto size = expr->getBitvectorSize();
451 auto bvsize = this->bv(size, size);
452 const auto& node = this->bvor(
453 this->bvlshr(expr, this->bvsmod(rot, bvsize)),
454 this->bvshl(expr, this->bvsub(bvsize, this->bvsmod(rot, bvsize)))
455 );
456 return node;
457 }
458
459 /* Otherwise, we concretize the index rotation */
460 SharedAbstractNode node = std::make_shared<BvrorNode>(expr, this->integer(rot->evaluate()));
461 if (node == nullptr)
462 throw triton::exceptions::Ast("AstContext::bvror(): Not enough memory.");
463 node->init();
464
465 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
466 if (node->isSymbolized() == false) {
467 return this->bv(node->evaluate(), node->getBitvectorSize());
468 }
469 }
470
471 return this->collect(node);
472 }
473
474
476 if (this->modes->isModeEnabled(triton::modes::AST_OPTIMIZATIONS)) {
477 /* Optimization: A / 1 = A */
478 if (!expr2->isSymbolized() && expr2->evaluate() == 1)
479 return expr1;
480 }
481
482 SharedAbstractNode node = std::make_shared<BvsdivNode>(expr1, expr2);
483 if (node == nullptr)
484 throw triton::exceptions::Ast("AstContext::bvsdiv(): Not enough memory.");
485 node->init();
486
487 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
488 if (node->isSymbolized() == false) {
489 return this->bv(node->evaluate(), node->getBitvectorSize());
490 }
491 }
492
493 return this->collect(node);
494 }
495
496
498 SharedAbstractNode node = std::make_shared<BvsgeNode>(expr1, expr2);
499 if (node == nullptr)
500 throw triton::exceptions::Ast("AstContext::bvsge(): Not enough memory.");
501 node->init();
502 return this->collect(node);
503 }
504
505
507 SharedAbstractNode node = std::make_shared<BvsgtNode>(expr1, expr2);
508 if (node == nullptr)
509 throw triton::exceptions::Ast("AstContext::bvsgt(): Not enough memory.");
510 node->init();
511 return this->collect(node);
512 }
513
514
516 if (this->modes->isModeEnabled(triton::modes::AST_OPTIMIZATIONS)) {
517 /* Optimization: 0 << A = 0 */
518 if (!expr1->isSymbolized() && expr1->evaluate() == 0)
519 return this->bv(0, expr1->getBitvectorSize());
520
521 /* Optimization: A << 0 = A */
522 if (!expr2->isSymbolized() && expr2->evaluate() == 0)
523 return expr1;
524
525 /* Optimization: A << B>=size(A) = 0 */
526 if (!expr2->isSymbolized() && expr2->evaluate() >= expr1->getBitvectorSize())
527 return this->bv(0, expr1->getBitvectorSize());
528 }
529
530 SharedAbstractNode node = std::make_shared<BvshlNode>(expr1, expr2);
531 if (node == nullptr)
532 throw triton::exceptions::Ast("AstContext::bvshl(): Not enough memory.");
533 node->init();
534
535 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
536 if (node->isSymbolized() == false) {
537 return this->bv(node->evaluate(), node->getBitvectorSize());
538 }
539 }
540
541 return this->collect(node);
542 }
543
544
546 SharedAbstractNode node = std::make_shared<BvsleNode>(expr1, expr2);
547 if (node == nullptr)
548 throw triton::exceptions::Ast("AstContext::bvsle(): Not enough memory.");
549 node->init();
550 return this->collect(node);
551 }
552
553
555 SharedAbstractNode node = std::make_shared<BvsltNode>(expr1, expr2);
556 if (node == nullptr)
557 throw triton::exceptions::Ast("AstContext::bvslt(): Not enough memory.");
558 node->init();
559 return this->collect(node);
560 }
561
562
564 SharedAbstractNode node = std::make_shared<BvsmodNode>(expr1, expr2);
565 if (node == nullptr)
566 throw triton::exceptions::Ast("AstContext::bvsmod(): Not enough memory.");
567 node->init();
568
569 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
570 if (node->isSymbolized() == false) {
571 return this->bv(node->evaluate(), node->getBitvectorSize());
572 }
573 }
574
575 return this->collect(node);
576 }
577
578
580 SharedAbstractNode node = std::make_shared<BvsremNode>(expr1, expr2);
581 if (node == nullptr)
582 throw triton::exceptions::Ast("AstContext::bvsrem(): Not enough memory.");
583 node->init();
584
585 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
586 if (node->isSymbolized() == false) {
587 return this->bv(node->evaluate(), node->getBitvectorSize());
588 }
589 }
590
591 return this->collect(node);
592 }
593
594
596 if (this->modes->isModeEnabled(triton::modes::AST_OPTIMIZATIONS)) {
597 /* Optimization: A - 0 = A */
598 if (!expr2->isSymbolized() && expr2->evaluate() == 0)
599 return expr1;
600
601 /* Optimization: 0 - A = -A */
602 if (!expr1->isSymbolized() && expr1->evaluate() == 0)
603 return this->bvneg(expr2);
604
605 /* Optimization: A - A = 0 */
606 if (expr1->equalTo(expr2))
607 return this->bv(0, expr1->getBitvectorSize());
608 }
609
610 SharedAbstractNode node = std::make_shared<BvsubNode>(expr1, expr2);
611 if (node == nullptr)
612 throw triton::exceptions::Ast("AstContext::bvsub(): Not enough memory.");
613 node->init();
614
615 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
616 if (node->isSymbolized() == false) {
617 return this->bv(node->evaluate(), node->getBitvectorSize());
618 }
619 }
620
621 return this->collect(node);
622 }
623
624
626 SharedAbstractNode node = std::make_shared<BvNode>(1, 1, this->shared_from_this());
627 if (node == nullptr)
628 throw triton::exceptions::Ast("AstContext::bvtrue(): Not enough memory.");
629 node->init();
630 return this->collect(node);
631 }
632
633
635 if (this->modes->isModeEnabled(triton::modes::AST_OPTIMIZATIONS)) {
636 /* Optimization: A / 1 = A */
637 if (!expr2->isSymbolized() && expr2->evaluate() == 1)
638 return expr1;
639 }
640
641 SharedAbstractNode node = std::make_shared<BvudivNode>(expr1, expr2);
642 if (node == nullptr)
643 throw triton::exceptions::Ast("AstContext::bvudiv(): Not enough memory.");
644 node->init();
645
646 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
647 if (node->isSymbolized() == false) {
648 return this->bv(node->evaluate(), node->getBitvectorSize());
649 }
650 }
651
652 return this->collect(node);
653 }
654
655
657 SharedAbstractNode node = std::make_shared<BvugeNode>(expr1, expr2);
658 if (node == nullptr)
659 throw triton::exceptions::Ast("AstContext::bvuge(): Not enough memory.");
660 node->init();
661 return this->collect(node);
662 }
663
664
666 SharedAbstractNode node = std::make_shared<BvugtNode>(expr1, expr2);
667 if (node == nullptr)
668 throw triton::exceptions::Ast("AstContext::bvugt(): Not enough memory.");
669 node->init();
670 return this->collect(node);
671 }
672
673
675 SharedAbstractNode node = std::make_shared<BvuleNode>(expr1, expr2);
676 if (node == nullptr)
677 throw triton::exceptions::Ast("AstContext::bvule(): Not enough memory.");
678 node->init();
679 return this->collect(node);
680 }
681
682
684 SharedAbstractNode node = std::make_shared<BvultNode>(expr1, expr2);
685 if (node == nullptr)
686 throw triton::exceptions::Ast("AstContext::bvult(): Not enough memory.");
687 node->init();
688 return this->collect(node);
689 }
690
691
693 SharedAbstractNode node = std::make_shared<BvuremNode>(expr1, expr2);
694 if (node == nullptr)
695 throw triton::exceptions::Ast("AstContext::bvurem(): Not enough memory.");
696 node->init();
697
698 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
699 if (node->isSymbolized() == false) {
700 return this->bv(node->evaluate(), node->getBitvectorSize());
701 }
702 }
703
704 return this->collect(node);
705 }
706
707
709 SharedAbstractNode node = std::make_shared<BvxnorNode>(expr1, expr2);
710 if (node == nullptr)
711 throw triton::exceptions::Ast("AstContext::bvxnor(): Not enough memory.");
712 node->init();
713
714 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
715 if (node->isSymbolized() == false) {
716 return this->bv(node->evaluate(), node->getBitvectorSize());
717 }
718 }
719
720 return this->collect(node);
721 }
722
723
725 if (this->modes->isModeEnabled(triton::modes::AST_OPTIMIZATIONS)) {
726 /* Optimization: A ^ 0 = A */
727 if (!expr2->isSymbolized() && expr2->evaluate() == 0)
728 return expr1;
729
730 /* Optimization: 0 ^ A = A */
731 if (!expr1->isSymbolized() && expr1->evaluate() == 0)
732 return expr2;
733
734 /* Optimization: A ^ A = 0 */
735 if (expr1->equalTo(expr2))
736 return this->bv(0, expr1->getBitvectorSize());
737 }
738
739 SharedAbstractNode node = std::make_shared<BvxorNode>(expr1, expr2);
740 if (node == nullptr)
741 throw triton::exceptions::Ast("AstContext::bvxor(): Not enough memory.");
742 node->init();
743
744 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
745 if (node->isSymbolized() == false) {
746 return this->bv(node->evaluate(), node->getBitvectorSize());
747 }
748 }
749
750 return this->collect(node);
751 }
752
753
754 template TRITON_EXPORT SharedAbstractNode AstContext::compound(const std::vector<SharedAbstractNode>& exprs);
755 template TRITON_EXPORT SharedAbstractNode AstContext::compound(const std::list<SharedAbstractNode>& exprs);
756
757
759 SharedAbstractNode node = std::make_shared<ConcatNode>(expr1, expr2);
760 if (node == nullptr)
761 throw triton::exceptions::Ast("AstContext::concat(): Not enough memory.");
762 node->init();
763
764 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
765 if (node->isSymbolized() == false) {
766 return this->bv(node->evaluate(), node->getBitvectorSize());
767 }
768 }
769
770 if (this->modes->isModeEnabled(triton::modes::AST_OPTIMIZATIONS)) {
771 /* Optimization: concatenate extractions in one if possible */
772 SharedAbstractNode n = this->simplify_concat(std::vector<SharedAbstractNode>({expr1, expr2}));
773 if (n) {
774 return n;
775 }
776 }
777
778 return this->collect(node);
779 }
780
781
782 template TRITON_EXPORT SharedAbstractNode AstContext::concat(const std::vector<SharedAbstractNode>& exprs);
783 template TRITON_EXPORT SharedAbstractNode AstContext::concat(const std::list<SharedAbstractNode>& exprs);
784
785
787 SharedAbstractNode node = std::make_shared<DeclareNode>(var);
788 if (node == nullptr)
789 throw triton::exceptions::Ast("AstContext::declare(): Not enough memory.");
790 node->init();
791 return this->collect(node);
792 }
793
794
796 SharedAbstractNode node = std::make_shared<DistinctNode>(expr1, expr2);
797 if (node == nullptr)
798 throw triton::exceptions::Ast("AstContext::distinct(): Not enough memory.");
799 node->init();
800 return this->collect(node);
801 }
802
803
805 SharedAbstractNode node = std::make_shared<EqualNode>(expr1, expr2);
806 if (node == nullptr)
807 throw triton::exceptions::Ast("AstContext::equal(): Not enough memory.");
808 node->init();
809 return this->collect(node);
810 }
811
812
814 /* Optimization: If we extract the full size of expr, just return expr */
815 if (low == 0 && (high + 1) == expr->getBitvectorSize())
816 return expr;
817
818 if (this->modes->isModeEnabled(triton::modes::AST_OPTIMIZATIONS)) {
819 SharedAbstractNode n = this->simplify_extract(high, low, expr);
820 if (n) {
821 return n;
822 }
823 }
824
825 SharedAbstractNode node = std::make_shared<ExtractNode>(high, low, expr);
826 if (node == nullptr)
827 throw triton::exceptions::Ast("AstContext::extract(): Not enough memory.");
828 node->init();
829
830 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
831 if (node->isSymbolized() == false) {
832 return this->bv(node->evaluate(), node->getBitvectorSize());
833 }
834 }
835
836 return this->collect(node);
837 }
838
839
840 template TRITON_EXPORT SharedAbstractNode AstContext::forall(const std::vector<SharedAbstractNode>& exprs, const SharedAbstractNode& body);
841 template TRITON_EXPORT SharedAbstractNode AstContext::forall(const std::list<SharedAbstractNode>& exprs, const SharedAbstractNode& body);
842
843
845 SharedAbstractNode node = std::make_shared<IffNode>(expr1, expr2);
846 if (node == nullptr)
847 throw triton::exceptions::Ast("AstContext::iff(): Not enough memory.");
848 node->init();
849 return this->collect(node);
850 }
851
852
854 SharedAbstractNode node = std::make_shared<IntegerNode>(value, this->shared_from_this());
855 if (node == nullptr)
856 throw triton::exceptions::Ast("AstContext::integer(): Not enough memory.");
857 node->init();
858 return this->collect(node);
859 }
860
861
863 if (this->modes->isModeEnabled(triton::modes::AST_OPTIMIZATIONS) ||
864 this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
865 /* Optimization: False ? A : B => B, True ? A : B => A */
866 if (!ifExpr->isSymbolized()) {
867 return ifExpr->evaluate() ? thenExpr : elseExpr;
868 }
869 }
870
871 SharedAbstractNode node = std::make_shared<IteNode>(ifExpr, thenExpr, elseExpr);
872 if (node == nullptr)
873 throw triton::exceptions::Ast("AstContext::ite(): Not enough memory.");
874 node->init();
875
876 return this->collect(node);
877 }
878
879
881 SharedAbstractNode node = std::make_shared<LandNode>(expr1, expr2);
882 if (node == nullptr)
883 throw triton::exceptions::Ast("AstContext::land(): Not enough memory.");
884 node->init();
885 return this->collect(node);
886 }
887
888
889 template TRITON_EXPORT SharedAbstractNode AstContext::land(const std::vector<SharedAbstractNode>& exprs);
890 template TRITON_EXPORT SharedAbstractNode AstContext::land(const std::list<SharedAbstractNode>& exprs);
891
892
893 SharedAbstractNode AstContext::let(std::string alias, const SharedAbstractNode& expr2, const SharedAbstractNode& expr3) {
894 SharedAbstractNode node = std::make_shared<LetNode>(alias, expr2, expr3);
895 if (node == nullptr)
896 throw triton::exceptions::Ast("AstContext::let(): Not enough memory.");
897 node->init();
898 return this->collect(node);
899 }
900
901
903 SharedAbstractNode node = std::make_shared<LnotNode>(expr);
904 if (node == nullptr)
905 throw triton::exceptions::Ast("AstContext::lnot(): Not enough memory.");
906 node->init();
907 return this->collect(node);
908 }
909
910
912 SharedAbstractNode node = std::make_shared<LorNode>(expr1, expr2);
913 if (node == nullptr)
914 throw triton::exceptions::Ast("AstContext::lor(): Not enough memory.");
915 node->init();
916 return this->collect(node);
917 }
918
919
920 template TRITON_EXPORT SharedAbstractNode AstContext::lor(const std::vector<SharedAbstractNode>& exprs);
921 template TRITON_EXPORT SharedAbstractNode AstContext::lor(const std::list<SharedAbstractNode>& exprs);
922
923
925 SharedAbstractNode node = std::make_shared<LxorNode>(expr1, expr2);
926 if (node == nullptr)
927 throw triton::exceptions::Ast("AstContext::lxor(): Not enough memory");
928 node->init();
929 return this->collect(node);
930 }
931
932
933 template TRITON_EXPORT SharedAbstractNode AstContext::lxor(const std::vector<SharedAbstractNode>& exprs);
934 template TRITON_EXPORT SharedAbstractNode AstContext::lxor(const std::list<SharedAbstractNode>& exprs);
935
936
938 SharedAbstractNode node = std::make_shared<ReferenceNode>(expr);
939 if (node == nullptr)
940 throw triton::exceptions::Ast("AstContext::reference(): Not enough memory.");
941 node->init();
942 return this->collect(node);
943 }
944
945
947 SharedAbstractNode node = std::make_shared<SelectNode>(array, index);
948 if (node == nullptr)
949 throw triton::exceptions::Ast("AstContext::select(): Not enough memory.");
950 node->init();
951 return this->collect(node);
952 }
953
954
956 SharedAbstractNode node = std::make_shared<SelectNode>(array, index);
957 if (node == nullptr)
958 throw triton::exceptions::Ast("AstContext::select(): Not enough memory.");
959 node->init();
960 return this->collect(node);
961 }
962
963
965 SharedAbstractNode node = std::make_shared<StoreNode>(array, index, expr);
966 if (node == nullptr)
967 throw triton::exceptions::Ast("AstContext::store(): Not enough memory.");
968 node->init();
969 return this->collect(node);
970 }
971
972
974 SharedAbstractNode node = std::make_shared<StoreNode>(array, index, expr);
975 if (node == nullptr)
976 throw triton::exceptions::Ast("AstContext::store(): Not enough memory.");
977 node->init();
978 return this->collect(node);
979 }
980
981
983 SharedAbstractNode node = std::make_shared<StringNode>(value, this->shared_from_this());
984 if (node == nullptr)
985 throw triton::exceptions::Ast("AstContext::string(): Not enough memory.");
986 node->init();
987 return this->collect(node);
988 }
989
990
992 /* Optimization: Just return expr if the extend is zero */
993 if (sizeExt == 0)
994 return expr;
995
996 SharedAbstractNode node = std::make_shared<SxNode>(sizeExt, expr);
997 if (node == nullptr)
998 throw triton::exceptions::Ast("AstContext::sx(): Not enough memory.");
999 node->init();
1000
1001 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
1002 if (node->isSymbolized() == false) {
1003 return this->bv(node->evaluate(), node->getBitvectorSize());
1004 }
1005 }
1006
1007 return this->collect(node);
1008 }
1009
1010
1012 // try to get node from variable pool
1013 auto it = this->valueMapping.find(symVar->getName());
1014 if (it != this->valueMapping.end()) {
1015 if (auto node = it->second.first.lock()) {
1016 if (node->getBitvectorSize() != symVar->getSize()) {
1017 throw triton::exceptions::Ast("AstContext::variable(): Missmatching variable size.");
1018 }
1019 // This node already exist, just return it
1020 return node;
1021 }
1022 throw triton::exceptions::Ast("AstContext::variable(): This symbolic variable is dead.");
1023 }
1024 else {
1025 // if not found, create a new variable node
1026 SharedAbstractNode node = std::make_shared<VariableNode>(symVar, this->shared_from_this());
1027 this->initVariable(symVar->getName(), 0, node);
1028 if (node == nullptr) {
1029 throw triton::exceptions::Ast("AstContext::variable(): Not enough memory");
1030 }
1031 node->init();
1032 return this->collect(node);
1033 }
1034 }
1035
1036
1038 /* Optimization: Just return expr if the extend is zero */
1039 if (sizeExt == 0)
1040 return expr;
1041
1042 SharedAbstractNode node = std::make_shared<ZxNode>(sizeExt, expr);
1043 if (node == nullptr)
1044 throw triton::exceptions::Ast("AstContext::zx(): Not enough memory.");
1045 node->init();
1046
1047 if (this->modes->isModeEnabled(triton::modes::CONSTANT_FOLDING)) {
1048 if (node->isSymbolized() == false) {
1049 return this->bv(node->evaluate(), node->getBitvectorSize());
1050 }
1051 }
1052
1053 return this->collect(node);
1054 }
1055
1056
1057 void AstContext::initVariable(const std::string& name, const triton::uint512& value, const SharedAbstractNode& node) {
1058 auto it = this->valueMapping.find(name);
1059 if (it == this->valueMapping.end()) {
1060 this->valueMapping.insert(std::make_pair(name, std::make_pair(node, value)));
1061 }
1062 else {
1063 throw triton::exceptions::Ast("AstContext::initVariable(): Ast variable already initialized.");
1064 }
1065 }
1066
1067
1068 void AstContext::updateVariable(const std::string& name, const triton::uint512& value) {
1069 auto it = this->valueMapping.find(name);
1070 if (it != this->valueMapping.end()) {
1071 if (auto node = it->second.first.lock()) {
1072 it->second.second = value;
1073 node->initParents();
1074 }
1075 else {
1076 throw triton::exceptions::Ast("AstContext::updateVariable(): This symbolic variable is dead.");
1077 }
1078 }
1079 else {
1080 throw triton::exceptions::Ast("AstContext::updateVariable(): This symbolic variable is not assigned at any AbstractNode or does not exist.");
1081 }
1082 }
1083
1084
1086 auto it = this->valueMapping.find(name);
1087 if (it != this->valueMapping.end()) {
1088 if (auto node = it->second.first.lock())
1089 return node;
1090 else
1091 throw triton::exceptions::Ast("AstContext::getVariableNode(): This symbolic variable is dead.");
1092 }
1093
1094 return nullptr;
1095 }
1096
1097
1098 const triton::uint512& AstContext::getVariableValue(const std::string& name) const {
1099 auto it = this->valueMapping.find(name);
1100 if (it != this->valueMapping.end()) {
1101 if (auto node = it->second.first.lock())
1102 return it->second.second;
1103 else
1104 throw triton::exceptions::Ast("AstContext::getVariableValue(): This symbolic variable is dead.");
1105 }
1106
1107 throw triton::exceptions::Ast("AstContext::updateVariable(): Variable does not exist.");
1108 }
1109
1110
1112 this->astRepresentation.setMode(mode);
1113 }
1114
1115
1117 return this->astRepresentation.getMode();
1118 }
1119
1120
1121 std::ostream& AstContext::print(std::ostream& stream, AbstractNode* node) {
1122 return this->astRepresentation.print(stream, node);
1123 }
1124
1125
1126 SharedAbstractNode AstContext::simplify_concat(std::vector<SharedAbstractNode> exprs) {
1127 /*
1128 * Optimization: concatenate extractions in one if possible. We are
1129 * trying to find out whether this is a concatenation of sequential
1130 * extractions from the same AST. Thus, we can make only one extraction.
1131 *
1132 * (concat ((_ extract 31 24) a) ((_ extract 23 16) a)
1133 * ((_ extract 15 8) a) ((_ extract 7 0) a)) =>
1134 * ((_ extract 31 0) a)
1135 *
1136 * So, we are examining whether we can replace concatenation with one
1137 * extraction ((_ extract high low) ast_ref).
1138 **/
1139 uint32 high = 0; // target extraction upper bound
1140 uint32 low = 1; // target extraction lower bound
1141 SharedAbstractNode ast_ref = 0; // target AST to extract from
1142 SharedAbstractNode ast_node = 0; // ast_ref with unrolled references
1143
1144 /* Try to join all extractions into one from the right to the left */
1145 while (!exprs.empty()) {
1146 /* Get the right most node */
1147 SharedAbstractNode n = exprs.back();
1148 exprs.pop_back();
1149
1150 /* Returns the first non referene node encountered */
1152
1153 if (n->getType() == CONCAT_NODE) {
1154 /* Append concatenation children to the right */
1155 for (const SharedAbstractNode& part : n->getChildren()) {
1156 exprs.push_back(part);
1157 }
1158 continue;
1159 }
1160
1161 if (n->getType() != EXTRACT_NODE) {
1162 /* We cannot optimize if at least one node is not an extract */
1163 return 0;
1164 }
1165
1166 /* Get extraction arguments */
1167 const auto& childs = n->getChildren();
1168 triton::uint32 hi = triton::ast::getInteger<triton::uint32>(childs[0]);
1169 triton::uint32 lo = triton::ast::getInteger<triton::uint32>(childs[1]);
1170 if (hi < lo) {
1171 return 0;
1172 }
1173 n = childs[2];
1174
1175 /* Returns the first non referene node encountered */
1177
1178 if (!ast_ref) {
1179 /* First found extraction node */
1180 high = hi;
1181 low = lo;
1182 ast_ref = childs[2];
1183 ast_node = n;
1184 continue;
1185 }
1186
1187 /*
1188 * Check that unrolled target AST is equal to extraction node child.
1189 * Also, check that extraction lower bound connects with target
1190 * extraction upper bound.
1191 **/
1192 if (high + 1 != lo || !n->equalTo(ast_node)) {
1193 return 0;
1194 }
1195 high = hi;
1196 }
1197
1198 if (high < low) {
1199 return 0;
1200 }
1201
1202 /* Perform target extraction */
1203 return this->extract(high, low, ast_ref);
1204 }
1205
1206
1207 SharedAbstractNode AstContext::simplify_extract(triton::uint32 high, triton::uint32 low, const SharedAbstractNode& expr) {
1208 triton::uint32 size = expr->getBitvectorSize();
1209
1210 if (high <= low || high >= size) {
1211 return 0;
1212 }
1213
1214 SharedAbstractNode node = expr;
1215 while (true) {
1216 /* Returns the first non referene node encountered */
1218
1219 if (n->getType() == CONCAT_NODE) {
1220 /*
1221 * Optimization: If we extract the full part of concatenation, just
1222 * return the part. We are trying to find a part of concatenation
1223 * that we can extract from. Thus, we can extract from only one part
1224 * of concatenation.
1225 *
1226 * ((_ extract 11 9) (concat (_ bv1 8) (_ bv2 8) (_ bv3 8) (_ bv4 8))) =>
1227 * ((_ extract 3 1) (_ bv3 8))
1228 */
1229 triton::uint32 hi = n->getBitvectorSize() - 1;
1230 bool found = false;
1231 /* Search for part of concatenation we can extract from. Iterate
1232 * from the left to the right. */
1233 for (const SharedAbstractNode& part : n->getChildren()) {
1234 if (hi < high) {
1235 /* Did not find a part we can extract from */
1236 break;
1237 }
1238 triton::uint32 sz = part->getBitvectorSize();
1239 triton::uint32 lo = hi + 1 - sz;
1240 if (hi == high && lo == low) {
1241 /* We are extracting the full part, just return it */
1242 return part;
1243 }
1244 if (hi >= high && lo <= low) {
1245 /* Extract from part: ((_ extract high-lo low-lo) part) */
1246 node = part;
1247 high -= lo;
1248 low -= lo;
1249 found = true;
1250 break;
1251 }
1252 hi -= sz;
1253 }
1254 if (found) {
1255 /* Optimize ((_ extract high low) node) one more time */
1256 continue;
1257 }
1258 }
1259 else if (n->getType() == ZX_NODE || n->getType() == SX_NODE) {
1260 /*
1261 * Optimization: If we extract from the node being extended, just
1262 * return the node
1263 *
1264 * ((_ extract 31 0) ((_ zero_extend 32) (_ bv1 32))) => (_ bv1 32)
1265 *
1266 * ((_ extract 7 0) ((_ sign_extend 32) (_ bv1 32))) =>
1267 * ((_ extract 7 0) (_ bv1 32))
1268 **/
1269 n = n->getChildren()[1];
1270 triton::uint32 sz = n->getBitvectorSize();
1271 if (low == 0 && high + 1 == sz) {
1272 /* Just return the node being extended */
1273 return n;
1274 }
1275 if (high < sz) {
1276 /* Optimize ((_ extract high low) n) one more time */
1277 node = n;
1278 continue;
1279 }
1280 }
1281 break;
1282 }
1283
1284 /* Returns the first non referene node encountered */
1286
1287 /*
1288 * Optimization: extract from extract is one extract
1289 *
1290 * ((_ extract high low) ((_ extract hi lo) a)) =>
1291 * ((_ extract high+lo low+lo) a)
1292 **/
1293 if (n->getType() == EXTRACT_NODE) {
1294 const auto& childs = n->getChildren();
1295 triton::uint32 hi = triton::ast::getInteger<triton::uint32>(childs[0]);
1296 triton::uint32 lo = triton::ast::getInteger<triton::uint32>(childs[1]);
1297 if (lo + high <= hi) {
1298 node = childs[2];
1299 high += lo;
1300 low += lo;
1301 }
1302 }
1303
1304 return node == expr ? 0 : this->extract(high, low, node);
1305 }
1306
1307 }; /* ast namespace */
1308}; /* triton namespace */
Abstract node.
Definition ast.hpp:68
AST Context - Used as AST builder.
TRITON_EXPORT void setRepresentationMode(triton::ast::representations::mode_e mode)
Sets the representation mode for this astContext.
TRITON_EXPORT SharedAbstractNode bvsgt(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - bvsgt node builder.
TRITON_EXPORT SharedAbstractNode bvmul(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - bvmul node builder.
TRITON_EXPORT SharedAbstractNode bvnand(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - bvnand node builder.
TRITON_EXPORT SharedAbstractNode bvsub(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - bvsub node builder.
TRITON_EXPORT SharedAbstractNode distinct(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - distinct node builder.
TRITON_EXPORT SharedAbstractNode land(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - land node builder.
TRITON_EXPORT void garbage(void)
Garbage unused nodes.
TRITON_EXPORT SharedAbstractNode bvuge(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - bvuge node builder.
TRITON_EXPORT SharedAbstractNode bvshl(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - bvshl node builder.
SharedAbstractNode compound(const T &exprs)
AST C++ API - compound node builder.
TRITON_EXPORT SharedAbstractNode iff(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - iff node builder.
TRITON_EXPORT SharedAbstractNode bvfalse(void)
AST C++ API - bvfalse node builder.
TRITON_EXPORT SharedAbstractNode bvxnor(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - bvxnor node builder.
TRITON_EXPORT SharedAbstractNode bvor(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - bvor node builder.
TRITON_EXPORT SharedAbstractNode bvrol(const SharedAbstractNode &expr, triton::uint32 rot)
AST C++ API - bvrol node builder.
TRITON_EXPORT ~AstContext()
Destructor.
TRITON_EXPORT AstContext & operator=(const AstContext &other)
Operator.
TRITON_EXPORT AstContext(const triton::modes::SharedModes &modes)
Constructor.
TRITON_EXPORT SharedAbstractNode bvule(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - bvule node builder.
TRITON_EXPORT SharedAbstractNode store(const SharedAbstractNode &array, triton::usize index, const SharedAbstractNode &expr)
AST C++ API - store node builder.
TRITON_EXPORT SharedAbstractNode concat(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - concat node builder.
SharedAbstractNode forall(const T &vars, const SharedAbstractNode &body)
AST C++ API - forall node builder.
TRITON_EXPORT SharedAbstractNode bvand(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - bvand node builder.
TRITON_EXPORT SharedAbstractNode bvudiv(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - bvudiv node builder.
TRITON_EXPORT SharedAbstractNode string(std::string value)
AST C++ API - string node builder.
TRITON_EXPORT SharedAbstractNode bvxor(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - bvxor node builder.
TRITON_EXPORT SharedAbstractNode reference(const triton::engines::symbolic::SharedSymbolicExpression &expr)
AST C++ API - reference node builder.
TRITON_EXPORT SharedAbstractNode zx(triton::uint32 sizeExt, const SharedAbstractNode &expr)
AST C++ API - zx node builder.
TRITON_EXPORT SharedAbstractNode bswap(const SharedAbstractNode &expr)
AST C++ API - bswap node builder.
TRITON_EXPORT SharedAbstractNode sx(triton::uint32 sizeExt, const SharedAbstractNode &expr)
AST C++ API - sx node builder.
TRITON_EXPORT SharedAbstractNode bvsge(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - bvsge node builder.
TRITON_EXPORT SharedAbstractNode bvsrem(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - bvsrem node builder.
TRITON_EXPORT SharedAbstractNode bvtrue(void)
AST C++ API - bvtrue node builder.
TRITON_EXPORT SharedAbstractNode bv(const triton::uint512 &value, triton::uint32 size)
AST C++ API - bv node builder.
TRITON_EXPORT SharedAbstractNode bvult(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - bvult node builder.
TRITON_EXPORT SharedAbstractNode bvashr(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - bvashr node builder.
TRITON_EXPORT SharedAbstractNode bvsdiv(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - bvsdiv node builder.
TRITON_EXPORT triton::ast::representations::mode_e getRepresentationMode(void) const
Gets the representations mode of this astContext.
SharedAbstractNode getVariableNode(const std::string &name)
Gets a variable node from its name.
TRITON_EXPORT SharedAbstractNode lor(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - lor node builder.
TRITON_EXPORT SharedAbstractNode bvnor(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - bvnor node builder.
TRITON_EXPORT SharedAbstractNode bvsle(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - bvsle node builder.
TRITON_EXPORT SharedAbstractNode lxor(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - lxor node builder.
TRITON_EXPORT SharedAbstractNode variable(const triton::engines::symbolic::SharedSymbolicVariable &symVar)
AST C++ API - variable node builder.
TRITON_EXPORT SharedAbstractNode bvlshr(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - bvlshr node builder.
TRITON_EXPORT std::ostream & print(std::ostream &stream, AbstractNode *node)
Prints the node according to the current representation mode.
TRITON_EXPORT void updateVariable(const std::string &name, const triton::uint512 &value)
Updates a variable value in this context.
TRITON_EXPORT SharedAbstractNode ite(const SharedAbstractNode &ifExpr, const SharedAbstractNode &thenExpr, const SharedAbstractNode &elseExpr)
AST C++ API - ite node builder.
TRITON_EXPORT SharedAbstractNode assert_(const SharedAbstractNode &expr)
AST C++ API - assert node builder.
TRITON_EXPORT SharedAbstractNode lnot(const SharedAbstractNode &expr)
AST C++ API - lnot node builder.
TRITON_EXPORT SharedAbstractNode select(const SharedAbstractNode &array, triton::usize index)
AST C++ API - select node builder.
TRITON_EXPORT SharedAbstractNode bvneg(const SharedAbstractNode &expr)
AST C++ API - bvneg node builder.
TRITON_EXPORT SharedAbstractNode collect(const SharedAbstractNode &node)
Collect new nodes.
TRITON_EXPORT const triton::uint512 & getVariableValue(const std::string &name) const
Gets a variable value from its name.
TRITON_EXPORT SharedAbstractNode bvugt(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - bvugt node builder.
TRITON_EXPORT SharedAbstractNode bvslt(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - bvslt node builder.
TRITON_EXPORT SharedAbstractNode equal(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - equal node builder.
TRITON_EXPORT SharedAbstractNode integer(const triton::uint512 &value)
AST C++ API - integer node builder.
TRITON_EXPORT SharedAbstractNode bvror(const SharedAbstractNode &expr, triton::uint32 rot)
AST C++ API - bvror node builder.
TRITON_EXPORT SharedAbstractNode array(triton::uint32 addrSize)
AST C++ API - array node builder.
TRITON_EXPORT SharedAbstractNode bvadd(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - bvadd node builder.
TRITON_EXPORT SharedAbstractNode let(std::string alias, const SharedAbstractNode &expr2, const SharedAbstractNode &expr3)
AST C++ API - let node builder.
TRITON_EXPORT void initVariable(const std::string &name, const triton::uint512 &value, const SharedAbstractNode &node)
Initializes a variable in the context.
TRITON_EXPORT SharedAbstractNode extract(triton::uint32 high, triton::uint32 low, const SharedAbstractNode &expr)
AST C++ API - extract node builder.
TRITON_EXPORT SharedAbstractNode bvsmod(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - bvsmod node builder.
TRITON_EXPORT SharedAbstractNode bvurem(const SharedAbstractNode &expr1, const SharedAbstractNode &expr2)
AST C++ API - bvurem node builder.
TRITON_EXPORT SharedAbstractNode bvnot(const SharedAbstractNode &expr)
AST C++ API - bvnot node builder.
TRITON_EXPORT SharedAbstractNode declare(const SharedAbstractNode &var)
AST C++ API - declare node builder.
TRITON_EXPORT std::ostream & print(std::ostream &stream, AbstractNode *node)
Prints the node according to the current representation mode.
TRITON_EXPORT void setMode(triton::ast::representations::mode_e mode)
Sets the representation mode.
TRITON_EXPORT triton::ast::representations::mode_e getMode(void) const
Returns the representation mode.
The exception class used by all AST nodes.
std::shared_ptr< triton::ast::AbstractNode > SharedAbstractNode
Shared Abstract Node.
Definition ast.hpp:59
SharedAbstractNode dereference(const SharedAbstractNode &node)
Returns the first non referene node encountered.
Definition ast.cpp:3743
std::shared_ptr< triton::modes::Modes > SharedModes
Shared Modes.
Definition modes.hpp:66
@ CONSTANT_FOLDING
[symbolic] Perform a constant folding optimization of sub ASTs which do not contain symbolic variable...
@ SYMBOLIZE_INDEX_ROTATION
[symbolic] Symbolize index rotation for bvrol and bvror (see #751). This mode increases the complexit...
@ AST_OPTIMIZATIONS
[AST] Classical arithmetic optimisations to reduce the depth of the trees.
mode_e
All types of representation mode.
Definition astEnums.hpp:98
std::shared_ptr< triton::engines::symbolic::SymbolicVariable > SharedSymbolicVariable
Shared Symbolic variable.
Definition ast.hpp:43
std::shared_ptr< triton::engines::symbolic::SymbolicExpression > SharedSymbolicExpression
Shared Symbolic Expression.
Definition ast.hpp:40
std::size_t usize
unsigned MAX_INT 32 or 64 bits according to the CPU.
math::wide_integer::uint512_t uint512
unsigned 512-bits
std::uint32_t uint32
unisgned 32-bits
The Triton namespace.