libTriton version 1.0 build 1588
Loading...
Searching...
No Matches
ast.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 <algorithm>
9#include <cmath>
10#include <list>
11#include <new>
12#include <stack>
13#include <unordered_map>
14#include <unordered_set>
15#include <utility>
16
17#include <triton/ast.hpp>
18#include <triton/astContext.hpp>
20#include <triton/exceptions.hpp>
23
24
25
26namespace triton {
27 namespace ast {
28
29 /* ====== Abstract node */
30
32 this->array = false;
33 this->ctxt = ctxt;
34 this->eval = 0;
35 this->hash = 0;
36 this->logical = false;
37 this->level = 1;
38 this->size = 0;
39 this->symbolized = false;
40 this->type = type;
41 }
42
43
45 /* See #828: Release ownership before calling container destructor */
46 this->children.clear();
47 }
48
49
51 return this->ctxt;
52 }
53
54
56 return this->type;
57 }
58
59
61 return this->size;
62 }
63
64
66 triton::uint512 mask = -1;
67 mask = mask >> (512 - this->size);
68 return mask;
69 }
70
71
72 bool AbstractNode::isSigned(void) const {
73 if ((this->eval >> (this->size-1)) & 1)
74 return true;
75 return false;
76 }
77
78
79 bool AbstractNode::isSymbolized(void) const {
80 return this->symbolized;
81 }
82
83
84 bool AbstractNode::isLogical(void) const {
85 switch (this->type) {
86 case BVSGE_NODE:
87 case BVSGT_NODE:
88 case BVSLE_NODE:
89 case BVSLT_NODE:
90 case BVUGE_NODE:
91 case BVUGT_NODE:
92 case BVULE_NODE:
93 case BVULT_NODE:
94 case DISTINCT_NODE:
95 case EQUAL_NODE:
96 case FORALL_NODE:
97 case IFF_NODE:
98 case LAND_NODE:
99 case LNOT_NODE:
100 case LOR_NODE:
101 case LXOR_NODE:
102 return true;
103
104 case ITE_NODE:
105 case REFERENCE_NODE:
106 return this->logical;
107
108 default:
109 break;
110 }
111
112 return false;
113 }
114
115
116 bool AbstractNode::isArray(void) const {
117 switch (this->type) {
118 case ARRAY_NODE:
119 case STORE_NODE:
120 return true;
121
122 /*
123 * Note that SELECT is not a node of type Array. SELECT returns
124 * a node of type (_ BitVec 8).
125 */
126
127 case REFERENCE_NODE:
128 return this->array;
129
130 default:
131 break;
132 }
133
134 return false;
135 }
136
137
139 return (this->evaluate() == other->evaluate()) &&
140 (this->getBitvectorSize() == other->getBitvectorSize()) &&
141 (this->isLogical() == other->isLogical());
142 }
143
144
146 return (this->hasSameConcreteValueAndTypeAs(other)) &&
147 (this->isSymbolized() == other->isSymbolized());
148 }
149
150
151 bool AbstractNode::equalTo(const SharedAbstractNode& other) const {
152 return (this->evaluate() == other->evaluate()) &&
153 (this->getBitvectorSize() == other->getBitvectorSize()) &&
154 (this->getHash() == other->getHash()) &&
155 (this->getLevel() == other->getLevel());
156 }
157
158
160 return this->eval;
161 }
162
163
165 return this->hash;
166 }
167
168
170 return this->level;
171 }
172
173
175 auto ancestors = parentsExtraction(this->shared_from_this(), false);
176 for (auto& sp : ancestors) {
177 sp->init();
178 }
179 }
180
181
182 std::vector<SharedAbstractNode>& AbstractNode::getChildren(void) {
183 return this->children;
184 }
185
186
187 std::vector<SharedAbstractNode> AbstractNode::getParents(void) {
188 std::vector<SharedAbstractNode> res;
189 std::vector<AbstractNode*> toRemove;
190
191 for (auto& kv: parents) {
192 if (auto sp = kv.second.second.lock())
193 res.push_back(sp);
194 else
195 toRemove.push_back(kv.first);
196 }
197
198 for(auto* an: toRemove)
199 parents.erase(an);
200
201 return res;
202 }
203
204
206 auto it = parents.find(p);
207
208 if (it == parents.end()) {
209 SharedAbstractNode A = p->shared_from_this();
210 this->parents.insert(std::make_pair(p, std::make_pair(1, WeakAbstractNode(A))));
211 }
212 else {
213 if (it->second.second.expired()) {
214 parents.erase(it);
215 SharedAbstractNode A = p->shared_from_this();
216 this->parents.insert(std::make_pair(p, std::make_pair(1, WeakAbstractNode(A))));
217 }
218 // Ptr already in, add it for the counter
219 else {
220 it->second.first += 1;
221 }
222 }
223 }
224
225
227 auto it = this->parents.find(p);
228
229 if (it == parents.end())
230 return;
231
232 it->second.first--;
233 if (it->second.first == 0)
234 this->parents.erase(it);
235 }
236
237
238 void AbstractNode::setParent(std::unordered_set<AbstractNode*>& p) {
239 for (AbstractNode* ptr : p) {
240 this->setParent(ptr);
241 }
242 }
243
244
246 this->children.push_back(child);
247 }
248
249
251 if (index >= this->children.size())
252 throw triton::exceptions::Ast("AbstractNode::setChild(): Invalid index.");
253
254 if (child == nullptr)
255 throw triton::exceptions::Ast("AbstractNode::setChild(): child cannot be null.");
256
257 if (this->children[index] != child) {
258 /* Remove the parent of the old child */
259 this->children[index]->removeParent(this);
260
261 /* Setup the parent of the child */
262 child->setParent(this);
263
264 /* Setup the child of the parent */
265 this->children[index] = child;
266
267 /* Init parents */
268 child->initParents();
269 }
270 }
271
272
274 this->size = size;
275 }
276
277
278 std::string AbstractNode::str(void) const {
279 std::stringstream s;
280 s << this;
281 if (!s.str().empty())
282 return s.str();
283 return nullptr;
284 }
285
286
287 /* ====== array */
288
289
290 ArrayNode::ArrayNode(triton::uint32 indexSize, const SharedAstContext& ctxt): AbstractNode(ARRAY_NODE, ctxt) {
291 this->indexSize = indexSize;
292 this->addChild(this->ctxt->integer(indexSize));
293 }
294
295
296 void ArrayNode::init(bool withParents) {
297 /* Init attributes. */
298 this->size = 0; // Array do not have size.
299 this->eval = 0; // Array cannot be evaluated.
300 this->level = 1;
301 this->symbolized = false;
302
303 /* Init children and spread information */
304 for (triton::uint32 index = 0; index < this->children.size(); index++) {
305 this->children[index]->setParent(this);
306 this->symbolized |= this->children[index]->isSymbolized();
307 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
308 }
309
310 /* Init parents if needed */
311 if (withParents) {
312 this->initParents();
313 }
314
315 this->initHash();
316 }
317
318
319 void ArrayNode::initHash(void) {
320 triton::uint512 s = this->children.size();
321
322 this->hash = static_cast<triton::uint64>(this->type);
323 if (s) this->hash = this->hash * s;
324 for (triton::uint32 index = 0; index < this->children.size(); index++) {
325 this->hash = this->hash * this->children[index]->getHash();
326 }
327
328 this->hash = triton::ast::rotl(this->hash, this->level);
329 }
330
331
333 this->memory[addr] = value;
334 }
335
336
338 if (this->memory.find(addr) != this->memory.end()) {
339 return this->memory.at(addr);
340 }
341 return 0;
342 }
343
344
346 return this->select(static_cast<triton::uint64>(addr));
347 }
348
349
351 return this->select(static_cast<triton::uint64>(node->evaluate()));
352 }
353
354
355 std::unordered_map<triton::uint64, triton::uint8>& ArrayNode::getMemory(void) {
356 return this->memory;
357 }
358
359
361 return this->indexSize;
362 }
363
364
365 /* ====== assert */
366
367
368 AssertNode::AssertNode(const SharedAbstractNode& expr): AbstractNode(ASSERT_NODE, expr->getContext()) {
369 this->addChild(expr);
370 }
371
372
373 void AssertNode::init(bool withParents) {
374 if (this->children.size() < 1)
375 throw triton::exceptions::Ast("AssertNode::init(): Must take at least one child.");
376
377 if (this->children[0]->isLogical() == false)
378 throw triton::exceptions::Ast("AssertNode::init(): Must take a logical node as argument.");
379
380 /* Init attributes */
381 this->size = this->children[0]->getBitvectorSize();
382 this->eval = ((this->children[0]->evaluate()) & this->getBitvectorMask());
383 this->level = 1;
384 this->symbolized = false;
385
386 /* Init children and spread information */
387 for (triton::uint32 index = 0; index < this->children.size(); index++) {
388 this->children[index]->setParent(this);
389 this->symbolized |= this->children[index]->isSymbolized();
390 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
391 }
392
393 /* Init parents if needed */
394 if (withParents) {
395 this->initParents();
396 }
397
398 this->initHash();
399 }
400
401
402 void AssertNode::initHash(void) {
403 triton::uint512 s = this->children.size();
404
405 this->hash = static_cast<triton::uint64>(this->type);
406 if (s) this->hash = this->hash * s;
407 for (triton::uint32 index = 0; index < this->children.size(); index++) {
408 this->hash = this->hash * this->children[index]->getHash();
409 }
410
411 this->hash = triton::ast::rotl(this->hash, this->level);
412 }
413
414
415 /* ====== bswap */
416
417
418 BswapNode::BswapNode(const SharedAbstractNode& expr): AbstractNode(BSWAP_NODE, expr->getContext()) {
419 this->addChild(expr);
420 }
421
422
423 void BswapNode::init(bool withParents) {
424 if (this->children.size() < 1)
425 throw triton::exceptions::Ast("BswapNode::init(): Must take at least one child.");
426
427 if (this->children[0]->getBitvectorSize() % 8 != 0)
428 throw triton::exceptions::Ast("BswapNode::init(): Invalid size, must be aligned on 8-bit.");
429
430 if (this->children[0]->isArray())
431 throw triton::exceptions::Ast("BswapNode::init(): Cannot take an array as argument.");
432
433 /* Init attributes */
434 this->size = this->children[0]->getBitvectorSize();
435 this->eval = this->children[0]->evaluate() & 0xff;
436 this->level = 1;
437 this->symbolized = false;
438
439 /* Init eval */
440 for (triton::uint32 index = 8 ; index != this->size ; index += triton::bitsize::byte) {
441 this->eval <<= triton::bitsize::byte;
442 this->eval |= ((this->children[0]->evaluate() >> index) & 0xff);
443 }
444
445 /* Init children and spread information */
446 for (triton::uint32 index = 0; index < this->children.size(); index++) {
447 this->children[index]->setParent(this);
448 this->symbolized |= this->children[index]->isSymbolized();
449 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
450 }
451
452 /* Init parents if needed */
453 if (withParents) {
454 this->initParents();
455 }
456
457 this->initHash();
458 }
459
460
461 void BswapNode::initHash(void) {
462 triton::uint512 s = this->children.size();
463
464 this->hash = static_cast<triton::uint64>(this->type);
465 if (s) this->hash = this->hash * s;
466 for (triton::uint32 index = 0; index < this->children.size(); index++) {
467 this->hash = this->hash * this->children[index]->getHash();
468 }
469
470 this->hash = triton::ast::rotl(this->hash, this->level);
471 }
472
473
474 /* ====== bvadd */
475
476
477 BvaddNode::BvaddNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(BVADD_NODE, expr1->getContext()) {
478 this->addChild(expr1);
479 this->addChild(expr2);
480 }
481
482
483 void BvaddNode::init(bool withParents) {
484 if (this->children.size() < 2)
485 throw triton::exceptions::Ast("BvaddNode::init(): Must take at least two children.");
486
487 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
488 throw triton::exceptions::Ast("BvaddNode::init(): Must take two nodes of same size.");
489
490 if (this->children[0]->isArray() || this->children[1]->isArray())
491 throw triton::exceptions::Ast("BvaddNode::init(): Cannot take an array as argument.");
492
493 /* Init attributes */
494 this->size = this->children[0]->getBitvectorSize();
495 this->eval = ((this->children[0]->evaluate() + this->children[1]->evaluate()) & this->getBitvectorMask());
496 this->level = 1;
497 this->symbolized = false;
498
499 /* Init children and spread information */
500 for (triton::uint32 index = 0; index < this->children.size(); index++) {
501 this->children[index]->setParent(this);
502 this->symbolized |= this->children[index]->isSymbolized();
503 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
504 }
505
506 /* Init parents if needed */
507 if (withParents) {
508 this->initParents();
509 }
510
511 this->initHash();
512 }
513
514
515 void BvaddNode::initHash(void) {
516 triton::uint512 s = this->children.size();
517
518 this->hash = static_cast<triton::uint64>(this->type);
519 if (s) this->hash = this->hash * s;
520 for (triton::uint32 index = 0; index < this->children.size(); index++) {
521 this->hash = this->hash * this->children[index]->getHash();
522 }
523
524 this->hash = triton::ast::rotl(this->hash, this->level);
525 }
526
527
528 /* ====== bvand */
529
530
531 BvandNode::BvandNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(BVAND_NODE, expr1->getContext()) {
532 this->addChild(expr1);
533 this->addChild(expr2);
534 }
535
536
537 void BvandNode::init(bool withParents) {
538 if (this->children.size() < 2)
539 throw triton::exceptions::Ast("BvandNode::init(): Must take at least two children.");
540
541 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
542 throw triton::exceptions::Ast("BvandNode::init(): Must take two nodes of same size.");
543
544 if (this->children[0]->isArray() || this->children[1]->isArray())
545 throw triton::exceptions::Ast("BvandNode::init(): Cannot take an array as argument.");
546
547 /* Init attributes */
548 this->size = this->children[0]->getBitvectorSize();
549 this->eval = (this->children[0]->evaluate() & this->children[1]->evaluate());
550 this->level = 1;
551 this->symbolized = false;
552
553 /* Init children and spread information */
554 for (triton::uint32 index = 0; index < this->children.size(); index++) {
555 this->children[index]->setParent(this);
556 this->symbolized |= this->children[index]->isSymbolized();
557 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
558 }
559
560 /* Init parents if needed */
561 if (withParents) {
562 this->initParents();
563 }
564
565 this->initHash();
566 }
567
568
569 void BvandNode::initHash(void) {
570 triton::uint512 s = this->children.size();
571
572 this->hash = static_cast<triton::uint64>(this->type);
573 if (s) this->hash = this->hash * s;
574 for (triton::uint32 index = 0; index < this->children.size(); index++) {
575 this->hash = this->hash * this->children[index]->getHash();
576 }
577
578 this->hash = triton::ast::rotl(this->hash, this->level);
579 }
580
581
582 /* ====== bvashr (shift with sign extension fill) */
583
584
585 BvashrNode::BvashrNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(BVASHR_NODE, expr1->getContext()) {
586 this->addChild(expr1);
587 this->addChild(expr2);
588 }
589
590
591 void BvashrNode::init(bool withParents) {
592 triton::uint32 shift = 0;
593 triton::uint512 mask = 0;
594 triton::uint512 value = 0;
595
596 if (this->children.size() < 2)
597 throw triton::exceptions::Ast("BvashrNode::init(): Must take at least two children.");
598
599 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
600 throw triton::exceptions::Ast("BvashrNode::init(): Must take two nodes of same size.");
601
602 if (this->children[0]->isArray() || this->children[1]->isArray())
603 throw triton::exceptions::Ast("BvashrNode::init(): Cannot take an array as argument.");
604
605 value = this->children[0]->evaluate();
606 shift = static_cast<triton::uint32>(this->children[1]->evaluate());
607
608 /* Init attributes */
609 this->size = this->children[0]->getBitvectorSize();
610 this->level = 1;
611 this->symbolized = false;
612
613 /* Mask based on the sign */
614 if (this->children[0]->isSigned()) {
615 mask = 1;
616 mask = ((mask << (this->size-1)) & this->getBitvectorMask());
617 }
618
619 if (shift >= this->size && this->children[0]->isSigned()) {
620 this->eval = -1;
621 this->eval &= this->getBitvectorMask();
622 }
623
624 else if (shift >= this->size && !this->children[0]->isSigned()) {
625 this->eval = 0;
626 }
627
628 else if (shift == 0) {
629 this->eval = value;
630 }
631
632 else {
633 this->eval = value & this->getBitvectorMask();
634 for (triton::uint32 index = 0; index < shift; index++) {
635 this->eval = (((this->eval >> 1) | mask) & this->getBitvectorMask());
636 }
637 }
638
639 /* Init children and spread information */
640 for (triton::uint32 index = 0; index < this->children.size(); index++) {
641 this->children[index]->setParent(this);
642 this->symbolized |= this->children[index]->isSymbolized();
643 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
644 }
645
646 /* Init parents if needed */
647 if (withParents) {
648 this->initParents();
649 }
650
651 this->initHash();
652 }
653
654
655 void BvashrNode::initHash(void) {
656 triton::uint512 s = this->children.size();
657
658 this->hash = static_cast<triton::uint64>(this->type);
659 if (s) this->hash = this->hash * s;
660 for (triton::uint32 index = 0; index < this->children.size(); index++) {
661 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
662 }
663
664 this->hash = triton::ast::rotl(this->hash, this->level);
665 }
666
667
668 /* ====== bvlshr (shift with zero filled) */
669
670
671 BvlshrNode::BvlshrNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(BVLSHR_NODE, expr1->getContext()) {
672 this->addChild(expr1);
673 this->addChild(expr2);
674 }
675
676
677 void BvlshrNode::init(bool withParents) {
678 if (this->children.size() < 2)
679 throw triton::exceptions::Ast("BvlshrNode::init(): Must take at least two children.");
680
681 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
682 throw triton::exceptions::Ast("BvlshrNode::init(): Must take two nodes of same size.");
683
684 if (this->children[0]->isArray() || this->children[1]->isArray())
685 throw triton::exceptions::Ast("BvlshrNode::init(): Cannot take an array as argument.");
686
687 /* Init attributes */
688 this->size = this->children[0]->getBitvectorSize();
689 this->eval = (this->children[0]->evaluate() >> static_cast<triton::uint32>(this->children[1]->evaluate()));
690 this->level = 1;
691 this->symbolized = false;
692
693 /* Init children and spread information */
694 for (triton::uint32 index = 0; index < this->children.size(); index++) {
695 this->children[index]->setParent(this);
696 this->symbolized |= this->children[index]->isSymbolized();
697 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
698 }
699
700 /* Init parents if needed */
701 if (withParents) {
702 this->initParents();
703 }
704
705 this->initHash();
706 }
707
708
709 void BvlshrNode::initHash(void) {
710 triton::uint512 s = this->children.size();
711
712 this->hash = static_cast<triton::uint64>(this->type);
713 if (s) this->hash = this->hash * s;
714 for (triton::uint32 index = 0; index < this->children.size(); index++) {
715 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
716 }
717
718 this->hash = triton::ast::rotl(this->hash, this->level);
719 }
720
721
722 /* ====== bvmul */
723
724
725 BvmulNode::BvmulNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(BVMUL_NODE, expr1->getContext()) {
726 this->addChild(expr1);
727 this->addChild(expr2);
728 }
729
730
731 void BvmulNode::init(bool withParents) {
732 if (this->children.size() < 2)
733 throw triton::exceptions::Ast("BvmulNode::init(): Must take at least two children.");
734
735 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
736 throw triton::exceptions::Ast("BvmulNode::init(): Must take two nodes of same size.");
737
738 if (this->children[0]->isArray() || this->children[1]->isArray())
739 throw triton::exceptions::Ast("BvmulNode::init(): Cannot take an array as argument.");
740
741 /* Init attributes */
742 this->size = this->children[0]->getBitvectorSize();
743 this->eval = ((this->children[0]->evaluate() * this->children[1]->evaluate()) & this->getBitvectorMask());
744 this->level = 1;
745 this->symbolized = false;
746
747 /* Init children and spread information */
748 for (triton::uint32 index = 0; index < this->children.size(); index++) {
749 this->children[index]->setParent(this);
750 this->symbolized |= this->children[index]->isSymbolized();
751 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
752 }
753
754 /* Init parents if needed */
755 if (withParents) {
756 this->initParents();
757 }
758
759 this->initHash();
760 }
761
762
763 void BvmulNode::initHash(void) {
764 triton::uint512 s = this->children.size();
765
766 this->hash = static_cast<triton::uint64>(this->type);
767 if (s) this->hash = this->hash * s;
768 for (triton::uint32 index = 0; index < this->children.size(); index++) {
769 this->hash = this->hash * this->children[index]->getHash();
770 }
771
772 this->hash = triton::ast::rotl(this->hash, this->level);
773 }
774
775
776 /* ====== bvnand */
777
778
779 BvnandNode::BvnandNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(BVNAND_NODE, expr1->getContext()) {
780 this->addChild(expr1);
781 this->addChild(expr2);
782 }
783
784
785 void BvnandNode::init(bool withParents) {
786 if (this->children.size() < 2)
787 throw triton::exceptions::Ast("BvnandNode::init(): Must take at least two children.");
788
789 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
790 throw triton::exceptions::Ast("BvnandNode::init(): Must take two nodes of same size.");
791
792 if (this->children[0]->isArray() || this->children[1]->isArray())
793 throw triton::exceptions::Ast("BvnandNode::init(): Cannot take an array as argument.");
794
795 /* Init attributes */
796 this->size = this->children[0]->getBitvectorSize();
797 this->eval = (~(this->children[0]->evaluate() & this->children[1]->evaluate()) & this->getBitvectorMask());
798 this->level = 1;
799 this->symbolized = false;
800
801 /* Init children and spread information */
802 for (triton::uint32 index = 0; index < this->children.size(); index++) {
803 this->children[index]->setParent(this);
804 this->symbolized |= this->children[index]->isSymbolized();
805 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
806 }
807
808 /* Init parents if needed */
809 if (withParents) {
810 this->initParents();
811 }
812
813 this->initHash();
814 }
815
816
817 void BvnandNode::initHash(void) {
818 triton::uint512 s = this->children.size();
819
820 this->hash = static_cast<triton::uint64>(this->type);
821 if (s) this->hash = this->hash * s;
822 for (triton::uint32 index = 0; index < this->children.size(); index++) {
823 this->hash = this->hash * this->children[index]->getHash();
824 }
825
826 this->hash = triton::ast::rotl(this->hash, this->level);
827 }
828
829
830 /* ====== bvneg */
831
832
833 BvnegNode::BvnegNode(const SharedAbstractNode& expr): AbstractNode(BVNEG_NODE, expr->getContext()) {
834 this->addChild(expr);
835 }
836
837
838 void BvnegNode::init(bool withParents) {
839 if (this->children.size() < 1)
840 throw triton::exceptions::Ast("BvnegNode::init(): Must take at least one child.");
841
842 if (this->children[0]->isArray())
843 throw triton::exceptions::Ast("BvnegNode::init(): Cannot take an array as argument.");
844
845 /* Init attributes */
846 this->size = this->children[0]->getBitvectorSize();
847 this->eval = (static_cast<triton::uint512>((-(static_cast<triton::sint512>(this->children[0]->evaluate())))) & this->getBitvectorMask());
848 this->level = 1;
849 this->symbolized = false;
850
851 /* Init children and spread information */
852 for (triton::uint32 index = 0; index < this->children.size(); index++) {
853 this->children[index]->setParent(this);
854 this->symbolized |= this->children[index]->isSymbolized();
855 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
856 }
857
858 /* Init parents if needed */
859 if (withParents) {
860 this->initParents();
861 }
862
863 this->initHash();
864 }
865
866
867 void BvnegNode::initHash(void) {
868 triton::uint512 s = this->children.size();
869
870 this->hash = static_cast<triton::uint64>(this->type);
871 if (s) this->hash = this->hash * s;
872 for (triton::uint32 index = 0; index < this->children.size(); index++) {
873 this->hash = this->hash * this->children[index]->getHash();
874 }
875
876 this->hash = triton::ast::rotl(this->hash, this->level);
877 }
878
879
880 /* ====== bvnor */
881
882
883 BvnorNode::BvnorNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(BVNOR_NODE, expr1->getContext()) {
884 this->addChild(expr1);
885 this->addChild(expr2);
886 }
887
888
889 void BvnorNode::init(bool withParents) {
890 if (this->children.size() < 2)
891 throw triton::exceptions::Ast("BvnorNode::init(): Must take at least two children.");
892
893 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
894 throw triton::exceptions::Ast("BvnorNode::init(): Must take two nodes of same size.");
895
896 if (this->children[0]->isArray() || this->children[1]->isArray())
897 throw triton::exceptions::Ast("BvnorNode::init(): Cannot take an array as argument.");
898
899 /* Init attributes */
900 this->size = this->children[0]->getBitvectorSize();
901 this->eval = (~(this->children[0]->evaluate() | this->children[1]->evaluate()) & this->getBitvectorMask());
902 this->level = 1;
903 this->symbolized = false;
904
905 /* Init children and spread information */
906 for (triton::uint32 index = 0; index < this->children.size(); index++) {
907 this->children[index]->setParent(this);
908 this->symbolized |= this->children[index]->isSymbolized();
909 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
910 }
911
912 /* Init parents if needed */
913 if (withParents) {
914 this->initParents();
915 }
916
917 this->initHash();
918 }
919
920
921 void BvnorNode::initHash(void) {
922 triton::uint512 s = this->children.size();
923
924 this->hash = static_cast<triton::uint64>(this->type);
925 if (s) this->hash = this->hash * s;
926 for (triton::uint32 index = 0; index < this->children.size(); index++) {
927 this->hash = this->hash * this->children[index]->getHash();
928 }
929
930 this->hash = triton::ast::rotl(this->hash, this->level);
931 }
932
933
934 /* ====== bvnot */
935
936
937 BvnotNode::BvnotNode(const SharedAbstractNode& expr): AbstractNode(BVNOT_NODE, expr->getContext()) {
938 this->addChild(expr);
939 }
940
941
942 void BvnotNode::init(bool withParents) {
943 if (this->children.size() < 1)
944 throw triton::exceptions::Ast("BvnotNode::init(): Must take at least one child.");
945
946 if (this->children[0]->isArray())
947 throw triton::exceptions::Ast("BvnotNode::init(): Cannot take an array as argument.");
948
949 /* Init attributes */
950 this->size = this->children[0]->getBitvectorSize();
951 this->eval = (~this->children[0]->evaluate() & this->getBitvectorMask());
952 this->level = 1;
953 this->symbolized = false;
954
955 /* Init children and spread information */
956 for (triton::uint32 index = 0; index < this->children.size(); index++) {
957 this->children[index]->setParent(this);
958 this->symbolized |= this->children[index]->isSymbolized();
959 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
960 }
961
962 /* Init parents if needed */
963 if (withParents) {
964 this->initParents();
965 }
966
967 this->initHash();
968 }
969
970
971 void BvnotNode::initHash(void) {
972 triton::uint512 s = this->children.size();
973
974 this->hash = static_cast<triton::uint64>(this->type);
975 if (s) this->hash = this->hash * s;
976 for (triton::uint32 index = 0; index < this->children.size(); index++) {
977 this->hash = this->hash * this->children[index]->getHash();
978 }
979
980 this->hash = triton::ast::rotl(this->hash, this->level);
981 }
982
983
984 /* ====== bvor */
985
986
987 BvorNode::BvorNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(BVOR_NODE, expr1->getContext()) {
988 this->addChild(expr1);
989 this->addChild(expr2);
990 }
991
992
993 void BvorNode::init(bool withParents) {
994 if (this->children.size() < 2)
995 throw triton::exceptions::Ast("BvorNode::init(): Must take at least two children.");
996
997 if (this->children[0]->getBitvectorSize() != this->children[0]->getBitvectorSize())
998 throw triton::exceptions::Ast("BvorNode::init(): Must take two nodes of same size.");
999
1000 if (this->children[0]->isArray() || this->children[1]->isArray())
1001 throw triton::exceptions::Ast("BvorNode::init(): Cannot take an array as argument.");
1002
1003 /* Init attributes */
1004 this->size = this->children[0]->getBitvectorSize();
1005 this->eval = (this->children[0]->evaluate() | this->children[1]->evaluate());
1006 this->level = 1;
1007 this->symbolized = false;
1008
1009 /* Init children and spread information */
1010 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1011 this->children[index]->setParent(this);
1012 this->symbolized |= this->children[index]->isSymbolized();
1013 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
1014 }
1015
1016 /* Init parents if needed */
1017 if (withParents) {
1018 this->initParents();
1019 }
1020
1021 this->initHash();
1022 }
1023
1024
1025 void BvorNode::initHash(void) {
1026 triton::uint512 s = this->children.size();
1027
1028 this->hash = static_cast<triton::uint64>(this->type);
1029 if (s) this->hash = this->hash * s;
1030 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1031 this->hash = this->hash * this->children[index]->getHash();
1032 }
1033
1034 this->hash = triton::ast::rotl(this->hash, this->level);
1035 }
1036
1037
1038 /* ====== bvrol */
1039
1040
1041 BvrolNode::BvrolNode(const SharedAbstractNode& expr, triton::uint32 rot): BvrolNode(expr, expr->getContext()->integer(rot)) {
1042 }
1043
1044
1045 BvrolNode::BvrolNode(const SharedAbstractNode& expr, const SharedAbstractNode& rot): AbstractNode(BVROL_NODE, expr->getContext()) {
1046 this->addChild(expr);
1047 this->addChild(rot);
1048 }
1049
1050
1051 void BvrolNode::init(bool withParents) {
1052 triton::uint32 rot = 0;
1053 triton::uint512 value = 0;
1054
1055 if (this->children.size() < 2)
1056 throw triton::exceptions::Ast("BvrolNode::init(): Must take at least two children.");
1057
1058 if (this->children[0]->isArray())
1059 throw triton::exceptions::Ast("BvrolNode::init(): Cannot take an array as argument.");
1060
1061 rot = triton::ast::getInteger<triton::uint32>(this->children[1]);
1062 value = this->children[0]->evaluate();
1063
1064 /* Init attributes */
1065 this->size = this->children[0]->getBitvectorSize();
1066 rot %= this->size;
1067 this->eval = (((value << rot) | (value >> (this->size - rot))) & this->getBitvectorMask());
1068 this->level = 1;
1069 this->symbolized = false;
1070
1071 /* Init children and spread information */
1072 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1073 this->children[index]->setParent(this);
1074 this->symbolized |= this->children[index]->isSymbolized();
1075 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
1076 }
1077
1078 /* Init parents if needed */
1079 if (withParents) {
1080 this->initParents();
1081 }
1082
1083 this->initHash();
1084 }
1085
1086
1087 void BvrolNode::initHash(void) {
1088 triton::uint512 s = this->children.size();
1089
1090 this->hash = static_cast<triton::uint64>(this->type);
1091 if (s) this->hash = this->hash * s;
1092 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1093 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
1094 }
1095
1096 this->hash = triton::ast::rotl(this->hash, this->level);
1097 }
1098
1099
1100 /* ====== bvror */
1101
1102
1103 BvrorNode::BvrorNode(const SharedAbstractNode& expr, triton::uint32 rot): BvrorNode(expr, expr->getContext()->integer(rot)) {
1104 }
1105
1106
1107 BvrorNode::BvrorNode(const SharedAbstractNode& expr, const SharedAbstractNode& rot): AbstractNode(BVROR_NODE, expr->getContext()) {
1108 this->addChild(expr);
1109 this->addChild(rot);
1110 }
1111
1112
1113 void BvrorNode::init(bool withParents) {
1114 triton::uint32 rot = 0;
1115 triton::uint512 value = 0;
1116
1117 if (this->children.size() < 2)
1118 throw triton::exceptions::Ast("BvrorNode::init(): Must take at least two children.");
1119
1120 if (this->children[0]->isArray())
1121 throw triton::exceptions::Ast("BvrorNode::init(): Cannot take an array as argument.");
1122
1123 rot = triton::ast::getInteger<triton::uint32>(this->children[1]);
1124 value = this->children[0]->evaluate();
1125
1126 /* Init attributes */
1127 this->size = this->children[0]->getBitvectorSize();
1128 rot %= this->size;
1129 this->eval = (((value >> rot) | (value << (this->size - rot))) & this->getBitvectorMask());
1130 this->level = 1;
1131 this->symbolized = false;
1132
1133 /* Init children and spread information */
1134 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1135 this->children[index]->setParent(this);
1136 this->symbolized |= this->children[index]->isSymbolized();
1137 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
1138 }
1139
1140 /* Init parents if needed */
1141 if (withParents) {
1142 this->initParents();
1143 }
1144
1145 this->initHash();
1146 }
1147
1148
1149 void BvrorNode::initHash(void) {
1150 triton::uint512 s = this->children.size();
1151
1152 this->hash = static_cast<triton::uint64>(this->type);
1153 if (s) this->hash = this->hash * s;
1154 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1155 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
1156 }
1157
1158 this->hash = triton::ast::rotl(this->hash, this->level);
1159 }
1160
1161
1162 /* ====== bvsdiv */
1163
1164
1165 BvsdivNode::BvsdivNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(BVSDIV_NODE, expr1->getContext()) {
1166 this->addChild(expr1);
1167 this->addChild(expr2);
1168 }
1169
1170
1171 void BvsdivNode::init(bool withParents) {
1172 triton::sint512 op1Signed = 0;
1173 triton::sint512 op2Signed = 0;
1174
1175 if (this->children.size() < 2)
1176 throw triton::exceptions::Ast("BvsdivNode::init(): Must take at least two children.");
1177
1178 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
1179 throw triton::exceptions::Ast("BvsdivNode::init(): Must take two nodes of same size.");
1180
1181 if (this->children[0]->isArray() || this->children[1]->isArray())
1182 throw triton::exceptions::Ast("BvsdivNode::init(): Cannot take an array as argument.");
1183
1184 /* Sign extend */
1185 op1Signed = triton::ast::modularSignExtend(this->children[0].get());
1186 op2Signed = triton::ast::modularSignExtend(this->children[1].get());
1187
1188 /* Init attributes */
1189 this->size = this->children[0]->getBitvectorSize();
1190 this->level = 1;
1191 this->symbolized = false;
1192
1193 if (op2Signed == 0) {
1194 this->eval = (op1Signed < 0 ? 1 : -1);
1195 this->eval &= this->getBitvectorMask();
1196 }
1197 else
1198 this->eval = (static_cast<triton::uint512>((op1Signed / op2Signed)) & this->getBitvectorMask());
1199
1200 /* Init children and spread information */
1201 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1202 this->children[index]->setParent(this);
1203 this->symbolized |= this->children[index]->isSymbolized();
1204 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
1205 }
1206
1207 /* Init parents if needed */
1208 if (withParents) {
1209 this->initParents();
1210 }
1211
1212 this->initHash();
1213 }
1214
1215
1216 void BvsdivNode::initHash(void) {
1217 triton::uint512 s = this->children.size();
1218
1219 this->hash = static_cast<triton::uint64>(this->type);
1220 if (s) this->hash = this->hash * s;
1221 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1222 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
1223 }
1224
1225 this->hash = triton::ast::rotl(this->hash, this->level);
1226 }
1227
1228
1229 /* ====== bvsge */
1230
1231
1232 BvsgeNode::BvsgeNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(BVSGE_NODE, expr1->getContext()) {
1233 this->addChild(expr1);
1234 this->addChild(expr2);
1235 }
1236
1237
1238 void BvsgeNode::init(bool withParents) {
1239 triton::sint512 op1Signed = 0;
1240 triton::sint512 op2Signed = 0;
1241
1242 if (this->children.size() < 2)
1243 throw triton::exceptions::Ast("BvsgeNode::init(): Must take at least two children.");
1244
1245 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
1246 throw triton::exceptions::Ast("BvsgeNode::init(): Must take two nodes of same size.");
1247
1248 if (this->children[0]->isArray() || this->children[1]->isArray())
1249 throw triton::exceptions::Ast("BvsgeNode::init(): Cannot take an array as argument.");
1250
1251 /* Sign extend */
1252 op1Signed = triton::ast::modularSignExtend(this->children[0].get());
1253 op2Signed = triton::ast::modularSignExtend(this->children[1].get());
1254
1255 /* Init attributes */
1256 this->size = 1;
1257 this->eval = (op1Signed >= op2Signed);
1258 this->level = 1;
1259 this->symbolized = false;
1260
1261 /* Init children and spread information */
1262 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1263 this->children[index]->setParent(this);
1264 this->symbolized |= this->children[index]->isSymbolized();
1265 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
1266 }
1267
1268 /* Init parents if needed */
1269 if (withParents) {
1270 this->initParents();
1271 }
1272
1273 this->initHash();
1274 }
1275
1276
1277 void BvsgeNode::initHash(void) {
1278 triton::uint512 s = this->children.size();
1279
1280 this->hash = static_cast<triton::uint64>(this->type);
1281 if (s) this->hash = this->hash * s;
1282 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1283 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
1284 }
1285
1286 this->hash = triton::ast::rotl(this->hash, this->level);
1287 }
1288
1289
1290 /* ====== bvsgt */
1291
1292
1293 BvsgtNode::BvsgtNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(BVSGT_NODE, expr1->getContext()) {
1294 this->addChild(expr1);
1295 this->addChild(expr2);
1296 }
1297
1298
1299 void BvsgtNode::init(bool withParents) {
1300 triton::sint512 op1Signed = 0;
1301 triton::sint512 op2Signed = 0;
1302
1303 if (this->children.size() < 2)
1304 throw triton::exceptions::Ast("BvsgtNode::init(): Must take at least two children.");
1305
1306 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
1307 throw triton::exceptions::Ast("BvsgtNode::init(): Must take two nodes of same size.");
1308
1309 if (this->children[0]->isArray() || this->children[1]->isArray())
1310 throw triton::exceptions::Ast("BvsgtNode::init(): Cannot take an array as argument.");
1311
1312 /* Sign extend */
1313 op1Signed = triton::ast::modularSignExtend(this->children[0].get());
1314 op2Signed = triton::ast::modularSignExtend(this->children[1].get());
1315
1316 /* Init attributes */
1317 this->size = 1;
1318 this->eval = (op1Signed > op2Signed);
1319 this->level = 1;
1320 this->symbolized = false;
1321
1322 /* Init children and spread information */
1323 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1324 this->children[index]->setParent(this);
1325 this->symbolized |= this->children[index]->isSymbolized();
1326 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
1327 }
1328
1329 /* Init parents if needed */
1330 if (withParents) {
1331 this->initParents();
1332 }
1333
1334 this->initHash();
1335 }
1336
1337
1338 void BvsgtNode::initHash(void) {
1339 triton::uint512 s = this->children.size();
1340
1341 this->hash = static_cast<triton::uint64>(this->type);
1342 if (s) this->hash = this->hash * s;
1343 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1344 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
1345 }
1346
1347 this->hash = triton::ast::rotl(this->hash, this->level);
1348 }
1349
1350
1351 /* ====== bvshl */
1352
1353
1354 BvshlNode::BvshlNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(BVSHL_NODE, expr1->getContext()) {
1355 this->addChild(expr1);
1356 this->addChild(expr2);
1357 }
1358
1359
1360 void BvshlNode::init(bool withParents) {
1361 if (this->children.size() < 2)
1362 throw triton::exceptions::Ast("BvshlNode::init(): Must take at least two children.");
1363
1364 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
1365 throw triton::exceptions::Ast("BvshlNode::init(): Must take two nodes of same size.");
1366
1367 if (this->children[0]->isArray() || this->children[1]->isArray())
1368 throw triton::exceptions::Ast("BvshlNode::init(): Cannot take an array as argument.");
1369
1370 /* Init attributes */
1371 this->size = this->children[0]->getBitvectorSize();
1372 this->eval = ((this->children[0]->evaluate() << static_cast<triton::uint32>(this->children[1]->evaluate())) & this->getBitvectorMask());
1373 this->level = 1;
1374 this->symbolized = false;
1375
1376 /* Init children and spread information */
1377 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1378 this->children[index]->setParent(this);
1379 this->symbolized |= this->children[index]->isSymbolized();
1380 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
1381 }
1382
1383 /* Init parents if needed */
1384 if (withParents) {
1385 this->initParents();
1386 }
1387
1388 this->initHash();
1389 }
1390
1391
1392 void BvshlNode::initHash(void) {
1393 triton::uint512 s = this->children.size();
1394
1395 this->hash = static_cast<triton::uint64>(this->type);
1396 if (s) this->hash = this->hash * s;
1397 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1398 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
1399 }
1400
1401 this->hash = triton::ast::rotl(this->hash, this->level);
1402 }
1403
1404
1405 /* ====== bvsle */
1406
1407
1408 BvsleNode::BvsleNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(BVSLE_NODE, expr1->getContext()) {
1409 this->addChild(expr1);
1410 this->addChild(expr2);
1411 }
1412
1413
1414 void BvsleNode::init(bool withParents) {
1415 triton::sint512 op1Signed = 0;
1416 triton::sint512 op2Signed = 0;
1417
1418 if (this->children.size() < 2)
1419 throw triton::exceptions::Ast("BvsleNode::init(): Must take at least two children.");
1420
1421 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
1422 throw triton::exceptions::Ast("BvsleNode::init(): Must take two nodes of same size.");
1423
1424 if (this->children[0]->isArray() || this->children[1]->isArray())
1425 throw triton::exceptions::Ast("BvsleNode::init(): Cannot take an array as argument.");
1426
1427 /* Sign extend */
1428 op1Signed = triton::ast::modularSignExtend(this->children[0].get());
1429 op2Signed = triton::ast::modularSignExtend(this->children[1].get());
1430
1431 /* Init attributes */
1432 this->size = 1;
1433 this->eval = (op1Signed <= op2Signed);
1434 this->level = 1;
1435 this->symbolized = false;
1436
1437 /* Init children and spread information */
1438 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1439 this->children[index]->setParent(this);
1440 this->symbolized |= this->children[index]->isSymbolized();
1441 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
1442 }
1443
1444 /* Init parents if needed */
1445 if (withParents) {
1446 this->initParents();
1447 }
1448
1449 this->initHash();
1450 }
1451
1452
1453 void BvsleNode::initHash(void) {
1454 triton::uint512 s = this->children.size();
1455
1456 this->hash = static_cast<triton::uint64>(this->type);
1457 if (s) this->hash = this->hash * s;
1458 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1459 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
1460 }
1461
1462 this->hash = triton::ast::rotl(this->hash, this->level);
1463 }
1464
1465
1466 /* ====== bvslt */
1467
1468
1469 BvsltNode::BvsltNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(BVSLT_NODE, expr1->getContext()) {
1470 this->addChild(expr1);
1471 this->addChild(expr2);
1472 }
1473
1474
1475 void BvsltNode::init(bool withParents) {
1476 triton::sint512 op1Signed = 0;
1477 triton::sint512 op2Signed = 0;
1478
1479 if (this->children.size() < 2)
1480 throw triton::exceptions::Ast("BvsltNode::init(): Must take at least two children.");
1481
1482 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
1483 throw triton::exceptions::Ast("BvsltNode::init(): Must take two nodes of same size.");
1484
1485 if (this->children[0]->isArray() || this->children[1]->isArray())
1486 throw triton::exceptions::Ast("BvsltNode::init(): Cannot take an array as argument.");
1487
1488 /* Sign extend */
1489 op1Signed = triton::ast::modularSignExtend(this->children[0].get());
1490 op2Signed = triton::ast::modularSignExtend(this->children[1].get());
1491
1492 /* Init attributes */
1493 this->size = 1;
1494 this->eval = (op1Signed < op2Signed);
1495 this->level = 1;
1496 this->symbolized = false;
1497
1498 /* Init children and spread information */
1499 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1500 this->children[index]->setParent(this);
1501 this->symbolized |= this->children[index]->isSymbolized();
1502 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
1503 }
1504
1505 /* Init parents if needed */
1506 if (withParents) {
1507 this->initParents();
1508 }
1509
1510 this->initHash();
1511 }
1512
1513
1514 void BvsltNode::initHash(void) {
1515 triton::uint512 s = this->children.size();
1516
1517 this->hash = static_cast<triton::uint64>(this->type);
1518 if (s) this->hash = this->hash * s;
1519 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1520 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
1521 }
1522
1523 this->hash = triton::ast::rotl(this->hash, this->level);
1524 }
1525
1526
1527 /* ====== bvsmod - 2's complement signed remainder (sign follows divisor) */
1528
1529
1530 BvsmodNode::BvsmodNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(BVSMOD_NODE, expr1->getContext()) {
1531 this->addChild(expr1);
1532 this->addChild(expr2);
1533 }
1534
1535
1536 void BvsmodNode::init(bool withParents) {
1537 triton::sint512 op1Signed = 0;
1538 triton::sint512 op2Signed = 0;
1539
1540 if (this->children.size() < 2)
1541 throw triton::exceptions::Ast("BvsmodNode::init(): Must take at least two children.");
1542
1543 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
1544 throw triton::exceptions::Ast("BvsmodNode::init(): Must take two nodes of same size.");
1545
1546 if (this->children[0]->isArray() || this->children[1]->isArray())
1547 throw triton::exceptions::Ast("BvsmodNode::init(): Cannot take an array as argument.");
1548
1549 /* Sign extend */
1550 op1Signed = triton::ast::modularSignExtend(this->children[0].get());
1551 op2Signed = triton::ast::modularSignExtend(this->children[1].get());
1552
1553 /* Init attributes */
1554 this->size = this->children[0]->getBitvectorSize();
1555 this->level = 1;
1556 this->symbolized = false;
1557
1558 if (this->children[1]->evaluate() == 0)
1559 this->eval = this->children[0]->evaluate();
1560 else
1561 this->eval = (static_cast<triton::uint512>((((op1Signed % op2Signed) + op2Signed) % op2Signed)) & this->getBitvectorMask());
1562
1563 /* Init children and spread information */
1564 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1565 this->children[index]->setParent(this);
1566 this->symbolized |= this->children[index]->isSymbolized();
1567 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
1568 }
1569
1570 /* Init parents if needed */
1571 if (withParents) {
1572 this->initParents();
1573 }
1574
1575 this->initHash();
1576 }
1577
1578
1579 void BvsmodNode::initHash(void) {
1580 triton::uint512 s = this->children.size();
1581
1582 this->hash = static_cast<triton::uint64>(this->type);
1583 if (s) this->hash = this->hash * s;
1584 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1585 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
1586 }
1587
1588 this->hash = triton::ast::rotl(this->hash, this->level);
1589 }
1590
1591
1592 /* ====== bvsrem - 2's complement signed remainder (sign follows dividend) */
1593
1594
1595 BvsremNode::BvsremNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(BVSREM_NODE, expr1->getContext()) {
1596 this->addChild(expr1);
1597 this->addChild(expr2);
1598 }
1599
1600
1601 void BvsremNode::init(bool withParents) {
1602 triton::sint512 op1Signed = 0;
1603 triton::sint512 op2Signed = 0;
1604
1605 if (this->children.size() < 2)
1606 throw triton::exceptions::Ast("BvsremNode::init(): Must take at least two children.");
1607
1608 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
1609 throw triton::exceptions::Ast("BvsremNode::init(): Must take two nodes of same size.");
1610
1611 if (this->children[0]->isArray() || this->children[1]->isArray())
1612 throw triton::exceptions::Ast("BvsremNode::init(): Cannot take an array as argument.");
1613
1614 /* Sign extend */
1615 op1Signed = triton::ast::modularSignExtend(this->children[0].get());
1616 op2Signed = triton::ast::modularSignExtend(this->children[1].get());
1617
1618 /* Init attributes */
1619 this->size = this->children[0]->getBitvectorSize();
1620 this->level = 1;
1621 this->symbolized = false;
1622
1623 if (this->children[1]->evaluate() == 0)
1624 this->eval = this->children[0]->evaluate();
1625 else
1626 this->eval = (static_cast<triton::uint512>((op1Signed - ((op1Signed / op2Signed) * op2Signed))) & this->getBitvectorMask());
1627
1628 /* Init children and spread information */
1629 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1630 this->children[index]->setParent(this);
1631 this->symbolized |= this->children[index]->isSymbolized();
1632 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
1633 }
1634
1635 /* Init parents if needed */
1636 if (withParents) {
1637 this->initParents();
1638 }
1639
1640 this->initHash();
1641 }
1642
1643
1644 void BvsremNode::initHash(void) {
1645 triton::uint512 s = this->children.size();
1646
1647 this->hash = static_cast<triton::uint64>(this->type);
1648 if (s) this->hash = this->hash * s;
1649 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1650 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
1651 }
1652
1653 this->hash = triton::ast::rotl(this->hash, this->level);
1654 }
1655
1656
1657 /* ====== bvsub */
1658
1659
1660 BvsubNode::BvsubNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(BVSUB_NODE, expr1->getContext()) {
1661 this->addChild(expr1);
1662 this->addChild(expr2);
1663 }
1664
1665
1666 void BvsubNode::init(bool withParents) {
1667 if (this->children.size() < 2)
1668 throw triton::exceptions::Ast("BvsubNode::init(): Must take at least two children.");
1669
1670 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
1671 throw triton::exceptions::Ast("BvsubNode::init(): Must take two nodes of same size.");
1672
1673 if (this->children[0]->isArray() || this->children[1]->isArray())
1674 throw triton::exceptions::Ast("BvsubNode::init(): Cannot take an array as argument.");
1675
1676 /* Init attributes */
1677 this->size = this->children[0]->getBitvectorSize();
1678 this->eval = ((this->children[0]->evaluate() - this->children[1]->evaluate()) & this->getBitvectorMask());
1679 this->level = 1;
1680 this->symbolized = false;
1681
1682 /* Init children and spread information */
1683 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1684 this->children[index]->setParent(this);
1685 this->symbolized |= this->children[index]->isSymbolized();
1686 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
1687 }
1688
1689 /* Init parents if needed */
1690 if (withParents) {
1691 this->initParents();
1692 }
1693
1694 this->initHash();
1695 }
1696
1697
1698 void BvsubNode::initHash(void) {
1699 triton::uint512 s = this->children.size();
1700
1701 this->hash = static_cast<triton::uint64>(this->type);
1702 if (s) this->hash = this->hash * s;
1703 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1704 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
1705 }
1706
1707 this->hash = triton::ast::rotl(this->hash, this->level);
1708 }
1709
1710
1711 /* ====== bvudiv */
1712
1713
1714 BvudivNode::BvudivNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(BVUDIV_NODE, expr1->getContext()) {
1715 this->addChild(expr1);
1716 this->addChild(expr2);
1717 }
1718
1719
1720 void BvudivNode::init(bool withParents) {
1721 if (this->children.size() < 2)
1722 throw triton::exceptions::Ast("BvudivNode::init(): Must take at least two children.");
1723
1724 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
1725 throw triton::exceptions::Ast("BvudivNode::init(): Must take two nodes of same size.");
1726
1727 if (this->children[0]->isArray() || this->children[1]->isArray())
1728 throw triton::exceptions::Ast("BvudivNode::init(): Cannot take an array as argument.");
1729
1730 /* Init attributes */
1731 this->size = this->children[0]->getBitvectorSize();
1732 this->level = 1;
1733 this->symbolized = false;
1734
1735 if (this->children[1]->evaluate() == 0)
1736 this->eval = (-1 & this->getBitvectorMask());
1737 else
1738 this->eval = (this->children[0]->evaluate() / this->children[1]->evaluate());
1739
1740 /* Init children and spread information */
1741 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1742 this->children[index]->setParent(this);
1743 this->symbolized |= this->children[index]->isSymbolized();
1744 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
1745 }
1746
1747 /* Init parents if needed */
1748 if (withParents) {
1749 this->initParents();
1750 }
1751
1752 this->initHash();
1753 }
1754
1755
1756 void BvudivNode::initHash(void) {
1757 triton::uint512 s = this->children.size();
1758
1759 this->hash = static_cast<triton::uint64>(this->type);
1760 if (s) this->hash = this->hash * s;
1761 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1762 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
1763 }
1764
1765 this->hash = triton::ast::rotl(this->hash, this->level);
1766 }
1767
1768
1769 /* ====== bvuge */
1770
1771
1772 BvugeNode::BvugeNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(BVUGE_NODE, expr1->getContext()) {
1773 this->addChild(expr1);
1774 this->addChild(expr2);
1775 }
1776
1777
1778 void BvugeNode::init(bool withParents) {
1779 if (this->children.size() < 2)
1780 throw triton::exceptions::Ast("BvugeNode::init(): Must take at least two children.");
1781
1782 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
1783 throw triton::exceptions::Ast("BvugeNode::init(): Must take two nodes of same size.");
1784
1785 if (this->children[0]->isArray() || this->children[1]->isArray())
1786 throw triton::exceptions::Ast("BvugeNode::init(): Cannot take an array as argument.");
1787
1788 /* Init attributes */
1789 this->size = 1;
1790 this->eval = (this->children[0]->evaluate() >= this->children[1]->evaluate());
1791 this->level = 1;
1792 this->symbolized = false;
1793
1794 /* Init children and spread information */
1795 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1796 this->children[index]->setParent(this);
1797 this->symbolized |= this->children[index]->isSymbolized();
1798 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
1799 }
1800
1801 /* Init parents if needed */
1802 if (withParents) {
1803 this->initParents();
1804 }
1805
1806 this->initHash();
1807 }
1808
1809
1810 void BvugeNode::initHash(void) {
1811 triton::uint512 s = this->children.size();
1812
1813 this->hash = static_cast<triton::uint64>(this->type);
1814 if (s) this->hash = this->hash * s;
1815 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1816 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
1817 }
1818
1819 this->hash = triton::ast::rotl(this->hash, this->level);
1820 }
1821
1822
1823 /* ====== bvugt */
1824
1825
1826 BvugtNode::BvugtNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(BVUGT_NODE, expr1->getContext()) {
1827 this->addChild(expr1);
1828 this->addChild(expr2);
1829 }
1830
1831
1832 void BvugtNode::init(bool withParents) {
1833 if (this->children.size() < 2)
1834 throw triton::exceptions::Ast("BvugtNode::init(): Must take at least two children.");
1835
1836 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
1837 throw triton::exceptions::Ast("BvugtNode::init(): Must take two nodes of same size.");
1838
1839 if (this->children[0]->isArray() || this->children[1]->isArray())
1840 throw triton::exceptions::Ast("BvugtNode::init(): Cannot take an array as argument.");
1841
1842 /* Init attributes */
1843 this->size = 1;
1844 this->eval = (this->children[0]->evaluate() > this->children[1]->evaluate());
1845 this->level = 1;
1846 this->symbolized = false;
1847
1848 /* Init children and spread information */
1849 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1850 this->children[index]->setParent(this);
1851 this->symbolized |= this->children[index]->isSymbolized();
1852 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
1853 }
1854
1855 /* Init parents if needed */
1856 if (withParents) {
1857 this->initParents();
1858 }
1859
1860 this->initHash();
1861 }
1862
1863
1864 void BvugtNode::initHash(void) {
1865 triton::uint512 s = this->children.size();
1866
1867 this->hash = static_cast<triton::uint64>(this->type);
1868 if (s) this->hash = this->hash * s;
1869 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1870 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
1871 }
1872
1873 this->hash = triton::ast::rotl(this->hash, this->level);
1874 }
1875
1876
1877 /* ====== bvule */
1878
1879
1880 BvuleNode::BvuleNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(BVULE_NODE, expr1->getContext()) {
1881 this->addChild(expr1);
1882 this->addChild(expr2);
1883 }
1884
1885
1886 void BvuleNode::init(bool withParents) {
1887 if (this->children.size() < 2)
1888 throw triton::exceptions::Ast("BvuleNode::init(): Must take at least two children.");
1889
1890 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
1891 throw triton::exceptions::Ast("BvuleNode::init(): Must take two nodes of same size.");
1892
1893 if (this->children[0]->isArray() || this->children[1]->isArray())
1894 throw triton::exceptions::Ast("BvuleNode::init(): Cannot take an array as argument.");
1895
1896 /* Init attributes */
1897 this->size = 1;
1898 this->eval = (this->children[0]->evaluate() <= this->children[1]->evaluate());
1899 this->level = 1;
1900 this->symbolized = false;
1901
1902 /* Init children and spread information */
1903 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1904 this->children[index]->setParent(this);
1905 this->symbolized |= this->children[index]->isSymbolized();
1906 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
1907 }
1908
1909 /* Init parents if needed */
1910 if (withParents) {
1911 this->initParents();
1912 }
1913
1914 this->initHash();
1915 }
1916
1917
1918 void BvuleNode::initHash(void) {
1919 triton::uint512 s = this->children.size();
1920
1921 this->hash = static_cast<triton::uint64>(this->type);
1922 if (s) this->hash = this->hash * s;
1923 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1924 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
1925 }
1926
1927 this->hash = triton::ast::rotl(this->hash, this->level);
1928 }
1929
1930
1931 /* ====== bvult */
1932
1933
1934 BvultNode::BvultNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(BVULT_NODE, expr1->getContext()) {
1935 this->addChild(expr1);
1936 this->addChild(expr2);
1937 }
1938
1939
1940 void BvultNode::init(bool withParents) {
1941 if (this->children.size() < 2)
1942 throw triton::exceptions::Ast("BvultNode::init(): Must take at least two children.");
1943
1944 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
1945 throw triton::exceptions::Ast("BvultNode::init(): Must take two nodes of same size.");
1946
1947 if (this->children[0]->isArray() || this->children[1]->isArray())
1948 throw triton::exceptions::Ast("BvultNode::init(): Cannot take an array as argument.");
1949
1950 /* Init attributes */
1951 this->size = 1;
1952 this->eval = (this->children[0]->evaluate() < this->children[1]->evaluate());
1953 this->level = 1;
1954 this->symbolized = false;
1955
1956 /* Init children and spread information */
1957 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1958 this->children[index]->setParent(this);
1959 this->symbolized |= this->children[index]->isSymbolized();
1960 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
1961 }
1962
1963 /* Init parents if needed */
1964 if (withParents) {
1965 this->initParents();
1966 }
1967
1968 this->initHash();
1969 }
1970
1971
1972 void BvultNode::initHash(void) {
1973 triton::uint512 s = this->children.size();
1974
1975 this->hash = static_cast<triton::uint64>(this->type);
1976 if (s) this->hash = this->hash * s;
1977 for (triton::uint32 index = 0; index < this->children.size(); index++) {
1978 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
1979 }
1980
1981 this->hash = triton::ast::rotl(this->hash, this->level);
1982 }
1983
1984
1985 /* ====== bvurem */
1986
1987
1988 BvuremNode::BvuremNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(BVUREM_NODE, expr1->getContext()) {
1989 this->addChild(expr1);
1990 this->addChild(expr2);
1991 }
1992
1993
1994 void BvuremNode::init(bool withParents) {
1995 if (this->children.size() < 2)
1996 throw triton::exceptions::Ast("BvuremNode::init(): Must take at least two children.");
1997
1998 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
1999 throw triton::exceptions::Ast("BvuremNode::init(): Must take two nodes of same size.");
2000
2001 if (this->children[0]->isArray() || this->children[1]->isArray())
2002 throw triton::exceptions::Ast("BvuremNode::init(): Cannot take an array as argument.");
2003
2004 /* Init attributes */
2005 this->size = this->children[0]->getBitvectorSize();
2006 this->level = 1;
2007 this->symbolized = false;
2008
2009 if (this->children[1]->evaluate() == 0)
2010 this->eval = this->children[0]->evaluate();
2011 else
2012 this->eval = (this->children[0]->evaluate() % this->children[1]->evaluate());
2013
2014 /* Init children and spread information */
2015 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2016 this->children[index]->setParent(this);
2017 this->symbolized |= this->children[index]->isSymbolized();
2018 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
2019 }
2020
2021 /* Init parents if needed */
2022 if (withParents) {
2023 this->initParents();
2024 }
2025
2026 this->initHash();
2027 }
2028
2029
2030 void BvuremNode::initHash(void) {
2031 triton::uint512 s = this->children.size();
2032
2033 this->hash = static_cast<triton::uint64>(this->type);
2034 if (s) this->hash = this->hash * s;
2035 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2036 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
2037 }
2038
2039 this->hash = triton::ast::rotl(this->hash, this->level);
2040 }
2041
2042
2043 /* ====== bvxnor */
2044
2045
2046 BvxnorNode::BvxnorNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(BVXNOR_NODE, expr1->getContext()) {
2047 this->addChild(expr1);
2048 this->addChild(expr2);
2049 }
2050
2051
2052 void BvxnorNode::init(bool withParents) {
2053 if (this->children.size() < 2)
2054 throw triton::exceptions::Ast("BvxnorNode::init(): Must take at least two children.");
2055
2056 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
2057 throw triton::exceptions::Ast("BvxnorNode::init(): Must take two nodes of same size.");
2058
2059 if (this->children[0]->isArray() || this->children[1]->isArray())
2060 throw triton::exceptions::Ast("BvxnorNode::init(): Cannot take an array as argument.");
2061
2062 /* Init attributes */
2063 this->size = this->children[0]->getBitvectorSize();
2064 this->eval = (~(this->children[0]->evaluate() ^ this->children[1]->evaluate()) & this->getBitvectorMask());
2065 this->level = 1;
2066 this->symbolized = false;
2067
2068 /* Init children and spread information */
2069 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2070 this->children[index]->setParent(this);
2071 this->symbolized |= this->children[index]->isSymbolized();
2072 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
2073 }
2074
2075 /* Init parents if needed */
2076 if (withParents) {
2077 this->initParents();
2078 }
2079
2080 this->initHash();
2081 }
2082
2083
2084 void BvxnorNode::initHash(void) {
2085 triton::uint512 s = this->children.size();
2086
2087 this->hash = static_cast<triton::uint64>(this->type);
2088 if (s) this->hash = this->hash * s;
2089 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2090 this->hash = this->hash * this->children[index]->getHash();
2091 }
2092
2093 this->hash = triton::ast::rotl(this->hash, this->level);
2094 }
2095
2096
2097 /* ====== bvxor */
2098
2099
2100 BvxorNode::BvxorNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(BVXOR_NODE, expr1->getContext()) {
2101 this->addChild(expr1);
2102 this->addChild(expr2);
2103 }
2104
2105
2106 void BvxorNode::init(bool withParents) {
2107 if (this->children.size() < 2)
2108 throw triton::exceptions::Ast("BvxorNode::init(): Must take at least two children.");
2109
2110 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
2111 throw triton::exceptions::Ast("BvxorNode::init(): Must take two nodes of same size.");
2112
2113 if (this->children[0]->isArray() || this->children[1]->isArray())
2114 throw triton::exceptions::Ast("BvxorNode::init(): Cannot take an array as argument.");
2115
2116 /* Init attributes */
2117 this->size = this->children[0]->getBitvectorSize();
2118 this->eval = (this->children[0]->evaluate() ^ this->children[1]->evaluate());
2119 this->level = 1;
2120 this->symbolized = false;
2121
2122 /* Init children and spread information */
2123 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2124 this->children[index]->setParent(this);
2125 this->symbolized |= this->children[index]->isSymbolized();
2126 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
2127 }
2128
2129 /* Init parents if needed */
2130 if (withParents) {
2131 this->initParents();
2132 }
2133
2134 this->initHash();
2135 }
2136
2137
2138 void BvxorNode::initHash(void) {
2139 triton::uint512 s = this->children.size();
2140
2141 this->hash = static_cast<triton::uint64>(this->type);
2142 if (s) this->hash = this->hash * s;
2143 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2144 this->hash = this->hash * this->children[index]->getHash();
2145 }
2146
2147 this->hash = triton::ast::rotl(this->hash, this->level);
2148 }
2149
2150
2151 /* ====== bv */
2152
2153
2154 BvNode::BvNode(const triton::uint512& value, triton::uint32 size, const SharedAstContext& ctxt): AbstractNode(BV_NODE, ctxt) {
2155 this->size = size;
2156 this->addChild(this->ctxt->integer(value & this->getBitvectorMask()));
2157 this->addChild(this->ctxt->integer(size));
2158 }
2159
2160
2161 void BvNode::init(bool withParents) {
2162 triton::uint512 value = 0;
2163 triton::uint32 size = 0;
2164
2165 if (this->children.size() < 2)
2166 throw triton::exceptions::Ast("BvNode::init(): Must take at least two children.");
2167
2168 value = triton::ast::getInteger<triton::uint512>(this->children[0]);
2169 size = triton::ast::getInteger<triton::uint32>(this->children[1]);
2170
2171 if (!size)
2172 throw triton::exceptions::Ast("BvNode::init(): Size cannot be equal to zero.");
2173
2175 throw triton::exceptions::Ast("BvNode::init(): Size cannot be greater than triton::bitsize::max_supported.");
2176
2177 /* Init attributes */
2178 this->size = size;
2179 this->eval = (value & this->getBitvectorMask());
2180 this->level = 1;
2181 this->symbolized = false;
2182
2183 /* Init children and spread information */
2184 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2185 this->children[index]->setParent(this);
2186 this->symbolized |= this->children[index]->isSymbolized();
2187 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
2188 }
2189
2190 /* Init parents if needed */
2191 if (withParents) {
2192 this->initParents();
2193 }
2194
2195 this->initHash();
2196 }
2197
2198
2199 void BvNode::initHash(void) {
2200 triton::uint512 s = this->children.size();
2201
2202 this->hash = static_cast<triton::uint64>(this->type);
2203 if (s) this->hash = this->hash * s;
2204 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2205 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
2206 }
2207
2208 this->hash = triton::ast::rotl(this->hash, this->level);
2209 }
2210
2211
2212 /* ====== compound */
2213
2214
2215 void CompoundNode::init(bool withParents) {
2216 if (this->children.size() < 1)
2217 throw triton::exceptions::Ast("CompoundNode::init(): Must take at least one child.");
2218
2219 /* Init attributes */
2220 this->eval = 0;
2221 this->size = 0;
2222 this->level = 1;
2223 this->symbolized = false;
2224
2225 /* Init children and spread information */
2226 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2227 this->children[index]->setParent(this);
2228 this->symbolized |= this->children[index]->isSymbolized();
2229 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
2230 }
2231
2232 /* Init parents if needed */
2233 if (withParents) {
2234 this->initParents();
2235 }
2236
2237 this->initHash();
2238 }
2239
2240
2241 void CompoundNode::initHash(void) {
2242 triton::uint512 s = this->children.size();
2243
2244 this->hash = static_cast<triton::uint64>(this->type);
2245 if (s) this->hash = this->hash * s;
2246 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2247 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
2248 }
2249
2250 this->hash = triton::ast::rotl(this->hash, this->level);
2251 }
2252
2253
2254 /* ====== concat */
2255
2256
2257 ConcatNode::ConcatNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(CONCAT_NODE, expr1->getContext()) {
2258 this->addChild(expr1);
2259 this->addChild(expr2);
2260 }
2261
2262
2263 void ConcatNode::init(bool withParents) {
2264 if (this->children.size() < 2)
2265 throw triton::exceptions::Ast("ConcatNode::init(): Must take at least two children.");
2266
2267 /* Init attributes */
2268 this->level = 1;
2269 this->symbolized = false;
2270 this->size = 0;
2271 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2272 this->size += this->children[index]->getBitvectorSize();
2273 }
2274
2276 throw triton::exceptions::Ast("ConcatNode::init(): Size cannot be greater than triton::bitsize::max_supported.");
2277
2278 this->eval = this->children[0]->evaluate();
2279 for (triton::uint32 index = 0; index < this->children.size()-1; index++)
2280 this->eval = ((this->eval << this->children[index+1]->getBitvectorSize()) | this->children[index+1]->evaluate());
2281
2282 /* Init children and spread information */
2283 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2284 if (this->children[index]->isArray()) {
2285 throw triton::exceptions::Ast("ConcatNode::init(): Cannot take an array as argument.");
2286 }
2287 this->children[index]->setParent(this);
2288 this->symbolized |= this->children[index]->isSymbolized();
2289 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
2290 }
2291
2292 /* Init parents if needed */
2293 if (withParents) {
2294 this->initParents();
2295 }
2296
2297 this->initHash();
2298 }
2299
2300
2301 void ConcatNode::initHash(void) {
2302 triton::uint512 s = this->children.size();
2303
2304 this->hash = static_cast<triton::uint64>(this->type);
2305 if (s) this->hash = this->hash * s;
2306 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2307 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
2308 }
2309
2310 this->hash = triton::ast::rotl(this->hash, this->level);
2311 }
2312
2313
2314 /* ====== Declare */
2315
2316
2317 DeclareNode::DeclareNode(const SharedAbstractNode& var): AbstractNode(DECLARE_NODE, var->getContext()) {
2318 this->addChild(var);
2319 }
2320
2321
2322 void DeclareNode::init(bool withParents) {
2323 if (this->children.size() < 1)
2324 throw triton::exceptions::Ast("DeclareNode::init(): Must take at least one child.");
2325
2326 if (this->children[0]->getType() != VARIABLE_NODE && this->children[0]->getType() != ARRAY_NODE)
2327 throw triton::exceptions::Ast("DeclareNode::init(): The child node must be a VARIABLE_NODE or an ARRAY_NODE.");
2328
2329 /* Init attributes */
2330 this->size = this->children[0]->getBitvectorSize();
2331 this->eval = this->children[0]->evaluate();
2332 this->level = 1;
2333 this->symbolized = false;
2334
2335 /* Init children and spread information */
2336 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2337 this->children[index]->setParent(this);
2338 this->symbolized |= this->children[index]->isSymbolized();
2339 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
2340 }
2341
2342 /* Init parents if needed */
2343 if (withParents) {
2344 this->initParents();
2345 }
2346
2347 this->initHash();
2348 }
2349
2350
2351 void DeclareNode::initHash(void) {
2352 triton::uint512 s = this->children.size();
2353
2354 this->hash = static_cast<triton::uint64>(this->type);
2355 if (s) this->hash = this->hash * s;
2356 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2357 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
2358 }
2359
2360 this->hash = triton::ast::rotl(this->hash, this->level);
2361 }
2362
2363
2364 /* ====== Distinct node */
2365
2366
2367 DistinctNode::DistinctNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(DISTINCT_NODE, expr1->getContext()) {
2368 this->addChild(expr1);
2369 this->addChild(expr2);
2370 }
2371
2372
2373 void DistinctNode::init(bool withParents) {
2374 if (this->children.size() < 2)
2375 throw triton::exceptions::Ast("DistinctNode::init(): Must take at least two children.");
2376
2377 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
2378 throw triton::exceptions::Ast("DistinctNode::init(): Must take two nodes of same size.");
2379
2380 if (this->children[0]->isArray() || this->children[1]->isArray())
2381 throw triton::exceptions::Ast("DistinctNode::init(): Cannot take an array as argument.");
2382
2383 /* Init attributes */
2384 this->size = 1;
2385 this->eval = (this->children[0]->evaluate() != this->children[1]->evaluate());
2386 this->level = 1;
2387 this->symbolized = false;
2388
2389 /* Init children and spread information */
2390 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2391 this->children[index]->setParent(this);
2392 this->symbolized |= this->children[index]->isSymbolized();
2393 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
2394 }
2395
2396 /* Init parents if needed */
2397 if (withParents) {
2398 this->initParents();
2399 }
2400
2401 this->initHash();
2402 }
2403
2404
2405 void DistinctNode::initHash(void) {
2406 triton::uint512 s = this->children.size();
2407
2408 this->hash = static_cast<triton::uint64>(this->type);
2409 if (s) this->hash = this->hash * s;
2410 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2411 this->hash = this->hash * this->children[index]->getHash();
2412 }
2413
2414 this->hash = triton::ast::rotl(this->hash, this->level);
2415 }
2416
2417
2418 /* ====== equal */
2419
2420
2421 EqualNode::EqualNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(EQUAL_NODE, expr1->getContext()) {
2422 this->addChild(expr1);
2423 this->addChild(expr2);
2424 }
2425
2426
2427 void EqualNode::init(bool withParents) {
2428 if (this->children.size() < 2)
2429 throw triton::exceptions::Ast("EqualNode::init(): Must take at least two children.");
2430
2431 if (this->children[0]->getBitvectorSize() != this->children[1]->getBitvectorSize())
2432 throw triton::exceptions::Ast("EqualNode::init(): Must take two nodes of same size.");
2433
2434 if (this->children[0]->isArray() || this->children[1]->isArray())
2435 throw triton::exceptions::Ast("EqualNode::init(): Cannot take an array as argument.");
2436
2437 /* Init attributes */
2438 this->size = 1;
2439 this->eval = (this->children[0]->evaluate() == this->children[1]->evaluate());
2440 this->level = 1;
2441 this->symbolized = false;
2442
2443 /* Init children and spread information */
2444 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2445 this->children[index]->setParent(this);
2446 this->symbolized |= this->children[index]->isSymbolized();
2447 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
2448 }
2449
2450 /* Init parents if needed */
2451 if (withParents) {
2452 this->initParents();
2453 }
2454
2455 this->initHash();
2456 }
2457
2458
2459 void EqualNode::initHash(void) {
2460 triton::uint512 s = this->children.size();
2461
2462 this->hash = static_cast<triton::uint64>(this->type);
2463 if (s) this->hash = this->hash * s;
2464 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2465 this->hash = this->hash * this->children[index]->getHash();
2466 }
2467
2468 this->hash = triton::ast::rotl(this->hash, this->level);
2469 }
2470
2471
2472 /* ====== extract */
2473
2474
2475 ExtractNode::ExtractNode(triton::uint32 high, triton::uint32 low, const SharedAbstractNode& expr): AbstractNode(EXTRACT_NODE, expr->getContext()) {
2476 this->addChild(this->ctxt->integer(high));
2477 this->addChild(this->ctxt->integer(low));
2478 this->addChild(expr);
2479 }
2480
2481
2482 void ExtractNode::init(bool withParents) {
2483 triton::uint32 high = 0;
2484 triton::uint32 low = 0;
2485
2486 if (this->children.size() < 3)
2487 throw triton::exceptions::Ast("ExtractNode::init(): Must take at least three children.");
2488
2489 if (this->children[2]->isArray())
2490 throw triton::exceptions::Ast("ExtractNode::init(): Cannot take an array as argument.");
2491
2492 high = triton::ast::getInteger<triton::uint32>(this->children[0]);
2493 low = triton::ast::getInteger<triton::uint32>(this->children[1]);
2494
2495 if (low > high)
2496 throw triton::exceptions::Ast("ExtractNode::init(): The high bit must be greater than the low bit.");
2497
2498 /* Init attributes */
2499 this->size = ((high - low) + 1);
2500 this->eval = ((this->children[2]->evaluate() >> low) & this->getBitvectorMask());
2501 this->level = 1;
2502 this->symbolized = false;
2503
2504 if (this->size > this->children[2]->getBitvectorSize() || high >= this->children[2]->getBitvectorSize())
2505 throw triton::exceptions::Ast("ExtractNode::init(): The size of the extraction is higher than the child expression.");
2506
2507 /* Init children and spread information */
2508 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2509 this->children[index]->setParent(this);
2510 this->symbolized |= this->children[index]->isSymbolized();
2511 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
2512 }
2513
2514 /* Init parents if needed */
2515 if (withParents) {
2516 this->initParents();
2517 }
2518
2519 this->initHash();
2520 }
2521
2522
2523 void ExtractNode::initHash(void) {
2524 triton::uint512 s = this->children.size();
2525
2526 this->hash = static_cast<triton::uint64>(this->type);
2527 if (s) this->hash = this->hash * s;
2528 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2529 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
2530 }
2531
2532 this->hash = triton::ast::rotl(this->hash, this->level);
2533 }
2534
2535
2536 /* ====== forall */
2537
2538
2539 void ForallNode::init(bool withParents) {
2540 triton::usize size = this->children.size();
2541
2542 if (size < 2)
2543 throw triton::exceptions::Ast("ForallNode::init(): Must take at least two children.");
2544
2545 for (triton::uint32 i = 0; i != size - 1; i++) {
2546 if (this->children[i]->getType() != VARIABLE_NODE)
2547 throw triton::exceptions::Ast("ForallNode::init(): Must take a variable node as first arguments.");
2548 }
2549
2550 if (this->children[size - 1]->isLogical() == false)
2551 throw triton::exceptions::Ast("ForallNode::init(): Must take a logical node as body.");
2552
2553 this->size = 1;
2554 this->eval = 0;
2555 this->level = 1;
2556 this->symbolized = false;
2557
2558 /* Init children and spread information */
2559 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2560 this->children[index]->setParent(this);
2561 this->symbolized |= this->children[index]->isSymbolized();
2562 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
2563 }
2564
2565 /* Init parents if needed */
2566 if (withParents) {
2567 this->initParents();
2568 }
2569
2570 this->initHash();
2571 }
2572
2573
2574 void ForallNode::initHash(void) {
2575 triton::uint512 s = this->children.size();
2576
2577 this->hash = static_cast<triton::uint64>(this->type);
2578 if (s) this->hash = this->hash * s;
2579 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2580 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
2581 }
2582
2583 this->hash = triton::ast::rotl(this->hash, this->level);
2584 }
2585
2586
2587 /* ====== iff */
2588
2589
2590 IffNode::IffNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(IFF_NODE, expr1->getContext()) {
2591 this->addChild(expr1);
2592 this->addChild(expr2);
2593 }
2594
2595
2596 void IffNode::init(bool withParents) {
2597 if (this->children.size() < 2)
2598 throw triton::exceptions::Ast("IffNode::init(): Must take at least two children.");
2599
2600 if (this->children[0]->isLogical() == false)
2601 throw triton::exceptions::Ast("IffNode::init(): Must take a logical node as first argument.");
2602
2603 if (this->children[1]->isLogical() == false)
2604 throw triton::exceptions::Ast("IffNode::init(): Must take a logical node as second argument.");
2605
2606 /* Init attributes */
2607 triton::uint512 P = this->children[0]->evaluate();
2608 triton::uint512 Q = this->children[1]->evaluate();
2609
2610 this->size = 1;
2611 this->eval = (P && Q) || (!P && !Q);
2612 this->level = 1;
2613 this->symbolized = false;
2614
2615 /* Init children and spread information */
2616 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2617 this->children[index]->setParent(this);
2618 this->symbolized |= this->children[index]->isSymbolized();
2619 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
2620 }
2621
2622 /* Init parents if needed */
2623 if (withParents) {
2624 this->initParents();
2625 }
2626
2627 this->initHash();
2628 }
2629
2630
2631 void IffNode::initHash(void) {
2632 triton::uint512 s = this->children.size();
2633
2634 this->hash = static_cast<triton::uint64>(this->type);
2635 if (s) this->hash = this->hash * s;
2636 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2637 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
2638 }
2639
2640 this->hash = triton::ast::rotl(this->hash, this->level);
2641 }
2642
2643
2644 /* ====== Integer node */
2645
2646
2647 IntegerNode::IntegerNode(const triton::uint512& value, const SharedAstContext& ctxt): AbstractNode(INTEGER_NODE, ctxt) {
2648 this->value = value;
2649 }
2650
2651
2652 void IntegerNode::init(bool withParents) {
2653 /* Init attributes */
2654 this->eval = 0;
2655 this->size = 0;
2656 this->level = 1;
2657 this->symbolized = false;
2658
2659 /* Init parents if needed */
2660 if (withParents) {
2661 this->initParents();
2662 }
2663
2664 this->initHash();
2665 }
2666
2667
2668 triton::uint512 IntegerNode::getInteger(void) {
2669 return this->value;
2670 }
2671
2672
2673 void IntegerNode::initHash(void) {
2674 this->hash = static_cast<triton::uint64>(this->type) ^ this->value;
2675 }
2676
2677
2678 /* ====== ite */
2679
2680
2681 IteNode::IteNode(const SharedAbstractNode& ifExpr, const SharedAbstractNode& thenExpr, const SharedAbstractNode& elseExpr): AbstractNode(ITE_NODE, ifExpr->getContext()) {
2682 this->addChild(ifExpr);
2683 this->addChild(thenExpr);
2684 this->addChild(elseExpr);
2685 }
2686
2687
2688 void IteNode::init(bool withParents) {
2689 if (this->children.size() < 3)
2690 throw triton::exceptions::Ast("IteNode::init(): Must take at least three children.");
2691
2692 if (this->children[0]->isLogical() == false)
2693 throw triton::exceptions::Ast("IteNode::init(): Must take a logical node as first argument.");
2694
2695 if (this->children[1]->getBitvectorSize() != this->children[2]->getBitvectorSize())
2696 throw triton::exceptions::Ast("IteNode::init(): Must take two nodes of same size as 'then' and 'else' branches.");
2697
2698 if (this->children[1]->isArray() || this->children[2]->isArray())
2699 throw triton::exceptions::Ast("IteNode::init(): Cannot take an array as argument.");
2700
2701 if (this->children[1]->isLogical() != this->children[2]->isLogical())
2702 throw triton::exceptions::Ast("IteNode::init(): Must take either two logical nodes or two bv nodes as 'then' and 'else' branches.");
2703
2704 /* Init attributes */
2705 this->size = this->children[1]->getBitvectorSize();
2706 this->eval = this->children[0]->evaluate() ? this->children[1]->evaluate() : this->children[2]->evaluate();
2707 this->logical = this->children[1]->isLogical();
2708 this->level = 1;
2709 this->symbolized = false;
2710
2711 /* Init children and spread information */
2712 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2713 this->children[index]->setParent(this);
2714 this->symbolized |= this->children[index]->isSymbolized();
2715 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
2716 }
2717
2718 /* Init parents if needed */
2719 if (withParents) {
2720 this->initParents();
2721 }
2722
2723 this->initHash();
2724 }
2725
2726
2727 void IteNode::initHash(void) {
2728 triton::uint512 s = this->children.size();
2729
2730 this->hash = static_cast<triton::uint64>(this->type);
2731 if (s) this->hash = this->hash * s;
2732 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2733 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
2734 }
2735
2736 this->hash = triton::ast::rotl(this->hash, this->level);
2737 }
2738
2739
2740 /* ====== Land */
2741
2742
2743 LandNode::LandNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(LAND_NODE, expr1->getContext()) {
2744 this->addChild(expr1);
2745 this->addChild(expr2);
2746 }
2747
2748
2749 void LandNode::init(bool withParents) {
2750 if (this->children.size() < 2)
2751 throw triton::exceptions::Ast("LandNode::init(): Must take at least two children.");
2752
2753 /* Init attributes */
2754 this->size = 1;
2755 this->eval = 1;
2756 this->level = 1;
2757 this->symbolized = false;
2758
2759 /* Init children and spread information */
2760 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2761 if (this->children[index]->isLogical() == false) {
2762 throw triton::exceptions::Ast("LandNode::init(): Must take logical nodes as arguments.");
2763 }
2764 this->children[index]->setParent(this);
2765 this->symbolized |= this->children[index]->isSymbolized();
2766 this->eval = this->eval && this->children[index]->evaluate();
2767 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
2768 }
2769
2770 /* Init parents if needed */
2771 if (withParents) {
2772 this->initParents();
2773 }
2774
2775 this->initHash();
2776 }
2777
2778
2779 void LandNode::initHash(void) {
2780 triton::uint512 s = this->children.size();
2781
2782 this->hash = static_cast<triton::uint64>(this->type);
2783 if (s) this->hash = this->hash * s;
2784 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2785 this->hash = this->hash * this->children[index]->getHash();
2786 }
2787
2788 this->hash = triton::ast::rotl(this->hash, this->level);
2789 }
2790
2791
2792 /* ====== Let */
2793
2794
2795 LetNode::LetNode(std::string alias, const SharedAbstractNode& expr2, const SharedAbstractNode& expr3): AbstractNode(LET_NODE, expr2->getContext()) {
2796 this->addChild(this->ctxt->string(alias));
2797 this->addChild(expr2);
2798 this->addChild(expr3);
2799 }
2800
2801
2802 void LetNode::init(bool withParents) {
2803 if (this->children.size() < 3)
2804 throw triton::exceptions::Ast("LetNode::init(): Must take at least three children.");
2805
2806 if (this->children[0]->getType() != STRING_NODE)
2807 throw triton::exceptions::Ast("LetNode::init(): The alias node must be a STRING_NODE.");
2808
2809 /* Init attributes */
2810 this->size = this->children[2]->getBitvectorSize();
2811 this->eval = this->children[2]->evaluate();
2812 this->level = 1;
2813 this->symbolized = false;
2814
2815 /* Init children and spread information */
2816 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2817 this->children[index]->setParent(this);
2818 this->symbolized |= this->children[index]->isSymbolized();
2819 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
2820 }
2821
2822 /* Init parents if needed */
2823 if (withParents) {
2824 this->initParents();
2825 }
2826
2827 this->initHash();
2828 }
2829
2830
2831 void LetNode::initHash(void) {
2832 triton::uint512 s = this->children.size();
2833
2834 this->hash = static_cast<triton::uint64>(this->type);
2835 if (s) this->hash = this->hash * s;
2836 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2837 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
2838 }
2839
2840 this->hash = triton::ast::rotl(this->hash, this->level);
2841 }
2842
2843
2844 /* ====== Lnot */
2845
2846
2847 LnotNode::LnotNode(const SharedAbstractNode& expr): AbstractNode(LNOT_NODE, expr->getContext()) {
2848 this->addChild(expr);
2849 }
2850
2851
2852 void LnotNode::init(bool withParents) {
2853 if (this->children.size() < 1)
2854 throw triton::exceptions::Ast("LnotNode::init(): Must take at least one child.");
2855
2856 /* Init attributes */
2857 this->size = 1;
2858 this->eval = !(this->children[0]->evaluate());
2859 this->level = 1;
2860 this->symbolized = false;
2861
2862 /* Init children and spread information */
2863 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2864 if (this->children[index]->isLogical() == false) {
2865 throw triton::exceptions::Ast("LnotNode::init(): Must take logical nodes arguments.");
2866 }
2867 this->children[index]->setParent(this);
2868 this->symbolized |= this->children[index]->isSymbolized();
2869 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
2870 }
2871
2872 /* Init parents if needed */
2873 if (withParents) {
2874 this->initParents();
2875 }
2876
2877 this->initHash();
2878 }
2879
2880
2881 void LnotNode::initHash(void) {
2882 triton::uint512 s = this->children.size();
2883
2884 this->hash = static_cast<triton::uint64>(this->type);
2885 if (s) this->hash = this->hash * s;
2886 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2887 this->hash = this->hash * this->children[index]->getHash();
2888 }
2889
2890 this->hash = triton::ast::rotl(this->hash, this->level);
2891 }
2892
2893
2894 /* ====== Lor */
2895
2896
2897 LorNode::LorNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2): AbstractNode(LOR_NODE, expr1->getContext()) {
2898 this->addChild(expr1);
2899 this->addChild(expr2);
2900 }
2901
2902
2903 void LorNode::init(bool withParents) {
2904 if (this->children.size() < 2)
2905 throw triton::exceptions::Ast("LorNode::init(): Must take at least two children.");
2906
2907 /* Init attributes */
2908 this->size = 1;
2909 this->eval = 0;
2910 this->level = 1;
2911 this->symbolized = false;
2912
2913 /* Init children and spread information */
2914 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2915 if (this->children[index]->isLogical() == false) {
2916 throw triton::exceptions::Ast("LorNode::init(): Must take logical nodes as arguments.");
2917 }
2918 this->children[index]->setParent(this);
2919 this->symbolized |= this->children[index]->isSymbolized();
2920 this->eval = this->eval || this->children[index]->evaluate();
2921 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
2922 }
2923
2924 /* Init parents if needed */
2925 if (withParents) {
2926 this->initParents();
2927 }
2928
2929 this->initHash();
2930 }
2931
2932
2933 void LorNode::initHash(void) {
2934 triton::uint512 s = this->children.size();
2935
2936 this->hash = static_cast<triton::uint64>(this->type);
2937 if (s) this->hash = this->hash * s;
2938 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2939 this->hash = this->hash * this->children[index]->getHash();
2940 }
2941
2942 this->hash = triton::ast::rotl(this->hash, this->level);
2943 }
2944
2945
2946 /* ====== Lxor */
2947
2948
2949 LxorNode::LxorNode(const SharedAbstractNode& expr1, const SharedAbstractNode& expr2) : AbstractNode(LXOR_NODE, expr1->getContext()) {
2950 this->addChild(expr1);
2951 this->addChild(expr2);
2952 }
2953
2954
2955 void LxorNode::init(bool withParents) {
2956 if (this->children.size() < 2)
2957 throw triton::exceptions::Ast("LxorNode::init(): Must take at least two children.");
2958
2959 /* Init attributes */
2960 this->size = 1;
2961 this->eval = 0;
2962 this->level = 1;
2963 this->symbolized = false;
2964
2965 /* Init children and spread information */
2966 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2967 if (this->children[index]->isLogical() == false) {
2968 throw triton::exceptions::Ast("LxorNode::init(): Must take logical nodes as arguments.");
2969 }
2970 this->children[index]->setParent(this);
2971 this->symbolized |= this->children[index]->isSymbolized();
2972 this->eval = !this->eval != !this->children[index]->evaluate();
2973 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
2974 }
2975
2976 /* Init parents if needed */
2977 if (withParents) {
2978 this->initParents();
2979 }
2980
2981 this->initHash();
2982 }
2983
2984
2985 void LxorNode::initHash(void) {
2986 triton::uint512 s = this->children.size();
2987
2988 this->hash = static_cast<triton::uint64>(this->type);
2989 if (s) this->hash = this->hash * s;
2990 for (triton::uint32 index = 0; index < this->children.size(); index++) {
2991 this->hash = this->hash * this->children[index]->getHash();
2992 }
2993
2994 this->hash = triton::ast::rotl(this->hash, this->level);
2995 }
2996
2997
2998 /* ====== Reference node */
2999
3000
3001 ReferenceNode::ReferenceNode(const triton::engines::symbolic::SharedSymbolicExpression& expr)
3002 : AbstractNode(REFERENCE_NODE, expr->getAst()->getContext())
3003 , expr(expr) {
3004 }
3005
3006
3007 void ReferenceNode::init(bool withParents) {
3008 /* Init attributes */
3009 this->array = this->expr->getAst()->isArray();
3010 this->eval = this->expr->getAst()->evaluate();
3011 this->logical = this->expr->getAst()->isLogical();
3012 this->size = this->expr->getAst()->getBitvectorSize();
3013 this->symbolized = this->expr->getAst()->isSymbolized();
3014 this->level = 1 + this->expr->getAst()->getLevel();
3015
3016 this->expr->getAst()->setParent(this);
3017
3018 /* Init parents if needed */
3019 if (withParents) {
3020 this->initParents();
3021 }
3022
3023 this->initHash();
3024 }
3025
3026
3027 void ReferenceNode::initHash(void) {
3028 this->hash = this->expr->getAst()->getHash();
3029 }
3030
3031
3032 const triton::engines::symbolic::SharedSymbolicExpression& ReferenceNode::getSymbolicExpression(void) const {
3033 return this->expr;
3034 }
3035
3036
3037 /* ====== Select node */
3038
3039 SelectNode::SelectNode(const SharedAbstractNode& array, triton::usize index): AbstractNode(SELECT_NODE, array->getContext()) {
3040 this->addChild(array);
3041 this->addChild(this->ctxt->bv(index, triton::ast::getIndexSize(array)));
3042 }
3043
3044
3045 SelectNode::SelectNode(const SharedAbstractNode& array, const SharedAbstractNode& index): AbstractNode(SELECT_NODE, array->getContext()) {
3046 this->addChild(array);
3047 this->addChild(index);
3048 }
3049
3050
3051 void SelectNode::init(bool withParents) {
3052 if (this->children.size() != 2)
3053 throw triton::exceptions::Ast("SelectNode::init(): Must take two children.");
3054
3055 if (this->children[0]->isArray() == false)
3056 throw triton::exceptions::Ast("SelectNode::init(): Must take an array as first argument.");
3057
3058 if (triton::ast::getIndexSize(this->children[0]) != this->children[1]->getBitvectorSize())
3059 throw triton::exceptions::Ast("SelectNode::init(): Size of indexing must be equal.");
3060
3061 /* Init attributes */
3062 this->size = 8; /* Size of a memory cell */
3063 this->level = 1;
3064 this->symbolized = false;
3065
3066 auto node = triton::ast::dereference(this->children[0]);
3067 switch(node->getType()) {
3068 case ARRAY_NODE:
3069 this->eval = reinterpret_cast<ArrayNode*>(node.get())->select(this->children[1]);
3070 break;
3071 case STORE_NODE:
3072 this->eval = reinterpret_cast<StoreNode*>(node.get())->select(this->children[1]);
3073 break;
3074 default:
3075 throw triton::exceptions::Ast("SelectNode::init(): Invalid sort");
3076 }
3077
3078 /* Init children and spread information */
3079 for (triton::uint32 index = 0; index < this->children.size(); index++) {
3080 this->children[index]->setParent(this);
3081 this->symbolized |= this->children[index]->isSymbolized();
3082 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
3083 }
3084
3085 /* Init parents if needed */
3086 if (withParents) {
3087 this->initParents();
3088 }
3089
3090 this->initHash();
3091 }
3092
3093
3094 void SelectNode::initHash(void) {
3095 triton::uint512 s = this->children.size();
3096
3097 this->hash = static_cast<triton::uint64>(this->type);
3098 if (s) this->hash = this->hash * s;
3099 for (triton::uint32 index = 0; index < this->children.size(); index++) {
3100 this->hash = this->hash * this->children[index]->getHash();
3101 }
3102
3103 this->hash = triton::ast::rotl(this->hash, this->level);
3104 }
3105
3106
3107 /* ====== Store node */
3108
3109
3110 StoreNode::StoreNode(const SharedAbstractNode& array, triton::usize index, const SharedAbstractNode& expr): AbstractNode(STORE_NODE, array->getContext()) {
3111 this->addChild(array);
3112 this->addChild(this->ctxt->bv(index, triton::ast::getIndexSize(array)));
3113 this->addChild(expr);
3114 }
3115
3116
3117 StoreNode::StoreNode(const SharedAbstractNode& array, const SharedAbstractNode& index, const SharedAbstractNode& expr): AbstractNode(STORE_NODE, array->getContext()) {
3118 this->addChild(array);
3119 this->addChild(index);
3120 this->addChild(expr);
3121 }
3122
3123
3124 void StoreNode::init(bool withParents) {
3125 if (this->children.size() != 3)
3126 throw triton::exceptions::Ast("StoreNode::init(): Must take three children.");
3127
3128 if (this->children[0]->isArray() == false)
3129 throw triton::exceptions::Ast("StoreNode::init(): Must take an array as first argument.");
3130
3131 if (triton::ast::getIndexSize(this->children[0]) != this->children[1]->getBitvectorSize())
3132 throw triton::exceptions::Ast("StoreNode::init(): Size of indexing must be equal to the array indexing size.");
3133
3135 throw triton::exceptions::Ast("StoreNode::init(): The stored node must be 8-bit long");
3136
3137 /* Init attributes */
3138 this->eval = this->children[2]->evaluate();
3139 this->size = 0; // Array do not have size.
3140 this->level = 1;
3141 this->symbolized = false;
3142
3143 /* Spread the memory array from previous level */
3144 auto node = triton::ast::dereference(this->children[0]);
3145 switch(node->getType()) {
3146 case ARRAY_NODE:
3147 this->indexSize = reinterpret_cast<ArrayNode*>(node.get())->getIndexSize();
3148 this->memory = reinterpret_cast<ArrayNode*>(node.get())->getMemory();
3149 break;
3150 case STORE_NODE:
3151 this->indexSize = reinterpret_cast<StoreNode*>(node.get())->getIndexSize();
3152 this->memory = reinterpret_cast<StoreNode*>(node.get())->getMemory();
3153 break;
3154 default:
3155 throw triton::exceptions::Ast("StoreNode::init(): Invalid sort");
3156 }
3157
3158 /* Store the value to the memory array */
3159 this->memory[static_cast<triton::uint64>(this->children[1]->evaluate())] = static_cast<triton::uint8>(this->eval);
3160
3161 /* Init children and spread information */
3162 for (triton::uint32 index = 0; index < this->children.size(); index++) {
3163 this->children[index]->setParent(this);
3164 this->symbolized |= this->children[index]->isSymbolized();
3165 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
3166 }
3167
3168 /* Init parents if needed */
3169 if (withParents) {
3170 this->initParents();
3171 }
3172
3173 this->initHash();
3174 }
3175
3176
3177 void StoreNode::initHash(void) {
3178 triton::uint512 s = this->children.size();
3179
3180 this->hash = static_cast<triton::uint64>(this->type);
3181 if (s) this->hash = this->hash * s;
3182 for (triton::uint32 index = 0; index < this->children.size(); index++) {
3183 this->hash = this->hash * this->children[index]->getHash();
3184 }
3185
3186 this->hash = triton::ast::rotl(this->hash, this->level);
3187 }
3188
3189
3191 if (this->memory.find(addr) != this->memory.end()) {
3192 return this->memory.at(addr);
3193 }
3194 return 0;
3195 }
3196
3197
3199 return this->select(static_cast<triton::uint64>(addr));
3200 }
3201
3202
3204 return this->select(static_cast<triton::uint64>(node->evaluate()));
3205 }
3206
3207
3208 std::unordered_map<triton::uint64, triton::uint8>& StoreNode::getMemory(void) {
3209 return this->memory;
3210 }
3211
3212
3214 return this->indexSize;
3215 }
3216
3217
3218 /* ====== String node */
3219
3220
3221 StringNode::StringNode(std::string value, const SharedAstContext& ctxt): AbstractNode(STRING_NODE, ctxt) {
3222 this->value = value;
3223 }
3224
3225
3226 void StringNode::init(bool withParents) {
3227 /* Init attributes */
3228 this->eval = 0;
3229 this->size = 0;
3230 this->level = 1;
3231 this->symbolized = false;
3232
3233 /* Init parents if needed */
3234 if (withParents) {
3235 this->initParents();
3236 }
3237
3238 this->initHash();
3239 }
3240
3241
3242 std::string StringNode::getString(void) {
3243 return this->value;
3244 }
3245
3246
3247 void StringNode::initHash(void) {
3248 triton::uint32 index = 1;
3249
3250 this->hash = static_cast<triton::uint64>(this->type);
3251 for (std::string::const_iterator it=this->value.cbegin(); it != this->value.cend(); it++) {
3252 this->hash = triton::ast::rotl(*it ^ this->hash ^ triton::ast::hash2n(this->hash, index++), *it);
3253 }
3254
3255 this->hash = triton::ast::rotl(this->hash, this->level);
3256 }
3257
3258
3259 /* ====== sx */
3260
3261
3262 SxNode::SxNode(triton::uint32 sizeExt, const SharedAbstractNode& expr): AbstractNode(SX_NODE, expr->getContext()) {
3263 this->addChild(this->ctxt->integer(sizeExt));
3264 this->addChild(expr);
3265 }
3266
3267
3268 void SxNode::init(bool withParents) {
3269 triton::uint32 sizeExt = 0;
3270
3271 if (this->children.size() < 2)
3272 throw triton::exceptions::Ast("SxNode::init(): Must take at least two children.");
3273
3274 if (this->children[1]->isArray())
3275 throw triton::exceptions::Ast("SxNode::init(): Cannot take an array as argument.");
3276
3277 sizeExt = triton::ast::getInteger<triton::uint32>(this->children[0]);
3278
3279 /* Init attributes */
3280 this->size = sizeExt + this->children[1]->getBitvectorSize();
3282 throw triton::exceptions::Ast("SxNode::SxNode(): Size cannot be greater than triton::bitsize::max_supported.");
3283
3284 this->level = 1;
3285 this->symbolized = false;
3286 this->eval = ((((this->children[1]->evaluate() >> (this->children[1]->getBitvectorSize()-1)) == 0) ?
3287 this->children[1]->evaluate() : (this->children[1]->evaluate() | ~(this->children[1]->getBitvectorMask()))) & this->getBitvectorMask());
3288
3289 /* Init children and spread information */
3290 for (triton::uint32 index = 0; index < this->children.size(); index++) {
3291 this->children[index]->setParent(this);
3292 this->symbolized |= this->children[index]->isSymbolized();
3293 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
3294 }
3295
3296 /* Init parents if needed */
3297 if (withParents) {
3298 this->initParents();
3299 }
3300
3301 this->initHash();
3302 }
3303
3304
3305 void SxNode::initHash(void) {
3306 triton::uint512 s = this->children.size();
3307
3308 this->hash = static_cast<triton::uint64>(this->type);
3309 if (s) this->hash = this->hash * s;
3310 for (triton::uint32 index = 0; index < this->children.size(); index++) {
3311 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
3312 }
3313
3314 this->hash = triton::ast::rotl(this->hash, this->level);
3315 }
3316
3317
3318 /* ====== Variable node */
3319
3320
3321 VariableNode::VariableNode(const triton::engines::symbolic::SharedSymbolicVariable& symVar, const SharedAstContext& ctxt)
3322 : AbstractNode(VARIABLE_NODE, ctxt),
3323 symVar(symVar) {
3324 }
3325
3326
3327 void VariableNode::init(bool withParents) {
3328 this->size = this->symVar->getSize();
3329 this->eval = this->ctxt->getVariableValue(this->symVar->getName()) & this->getBitvectorMask();
3330 this->symbolized = true;
3331 this->level = 1;
3332
3333 /* Init parents if needed */
3334 if (withParents) {
3335 this->initParents();
3336 }
3337
3338 this->initHash();
3339 }
3340
3341
3342 const triton::engines::symbolic::SharedSymbolicVariable& VariableNode::getSymbolicVariable() {
3343 return this->symVar;
3344 }
3345
3346
3347 void VariableNode::initHash(void) {
3348 triton::uint32 index = 1;
3349 triton::usize id = this->symVar->getId();
3350
3351 this->hash = static_cast<triton::uint64>(this->type);
3352 for (char c : this->symVar->getName()) {
3353 this->hash = triton::ast::rotl(c ^ this->hash ^ triton::ast::hash2n(this->hash, index++), (id & 511));
3354 }
3355
3356 this->hash = triton::ast::rotl(this->hash, this->level);
3357 }
3358
3359
3360 /* ====== zx */
3361
3362
3363 ZxNode::ZxNode(triton::uint32 sizeExt, const SharedAbstractNode& expr): AbstractNode(ZX_NODE, expr->getContext()) {
3364 this->addChild(this->ctxt->integer(sizeExt));
3365 this->addChild(expr);
3366 }
3367
3368
3369 void ZxNode::init(bool withParents) {
3370 triton::uint32 sizeExt = 0;
3371
3372 if (this->children.size() < 2)
3373 throw triton::exceptions::Ast("ZxNode::init(): Must take at least two children.");
3374
3375 if (this->children[1]->isArray())
3376 throw triton::exceptions::Ast("ZxNode::init(): Cannot take an array as argument.");
3377
3378 sizeExt = triton::ast::getInteger<triton::uint32>(this->children[0]);
3379
3380 /* Init attributes */
3381 this->size = sizeExt + this->children[1]->getBitvectorSize();
3383 throw triton::exceptions::Ast("ZxNode::init(): Size cannot be greater than triton::bitsize::max_supported.");
3384
3385 this->eval = (this->children[1]->evaluate() & this->getBitvectorMask());
3386 this->level = 1;
3387 this->symbolized = false;
3388
3389 /* Init children and spread information */
3390 for (triton::uint32 index = 0; index < this->children.size(); index++) {
3391 this->children[index]->setParent(this);
3392 this->symbolized |= this->children[index]->isSymbolized();
3393 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
3394 }
3395
3396 /* Init parents if needed */
3397 if (withParents) {
3398 this->initParents();
3399 }
3400
3401 this->initHash();
3402 }
3403
3404
3405 void ZxNode::initHash(void) {
3406 triton::uint512 s = this->children.size();
3407
3408 this->hash = static_cast<triton::uint64>(this->type);
3409 if (s) this->hash = this->hash * s;
3410 for (triton::uint32 index = 0; index < this->children.size(); index++) {
3411 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
3412 }
3413
3414 this->hash = triton::ast::rotl(this->hash, this->level);
3415 }
3416
3417 }; /* ast namespace */
3418}; /* triton namespace */
3419
3420
3421
3422/* ====== Force templates declarations */
3423
3424namespace triton {
3425 namespace ast {
3426
3427 template TRITON_EXPORT CompoundNode::CompoundNode(const std::list<SharedAbstractNode>& exprs, const SharedAstContext& ctxt);
3428 template TRITON_EXPORT CompoundNode::CompoundNode(const std::vector<SharedAbstractNode>& exprs, const SharedAstContext& ctxt);
3429 template TRITON_EXPORT ConcatNode::ConcatNode(const std::list<SharedAbstractNode>& exprs, const SharedAstContext& ctxt);
3430 template TRITON_EXPORT ConcatNode::ConcatNode(const std::vector<SharedAbstractNode>& exprs, const SharedAstContext& ctxt);
3431 template TRITON_EXPORT ForallNode::ForallNode(const std::list<SharedAbstractNode>& vars, const SharedAbstractNode& body);
3432 template TRITON_EXPORT ForallNode::ForallNode(const std::vector<SharedAbstractNode>& vars, const SharedAbstractNode& body);
3433 template TRITON_EXPORT LandNode::LandNode(const std::list<SharedAbstractNode>& exprs, const SharedAstContext& ctxt);
3434 template TRITON_EXPORT LandNode::LandNode(const std::vector<SharedAbstractNode>& exprs, const SharedAstContext& ctxt);
3435 template TRITON_EXPORT LorNode::LorNode(const std::list<SharedAbstractNode>& exprs, const SharedAstContext& ctxt);
3436 template TRITON_EXPORT LorNode::LorNode(const std::vector<SharedAbstractNode>& exprs, const SharedAstContext& ctxt);
3437 template TRITON_EXPORT LxorNode::LxorNode(const std::list<SharedAbstractNode>& exprs, const SharedAstContext& ctxt);
3438 template TRITON_EXPORT LxorNode::LxorNode(const std::vector<SharedAbstractNode>& exprs, const SharedAstContext& ctxt);
3439
3440 }; /* ast namespace */
3441}; /* triton namespace */
3442
3443
3444
3445/* ====== Operators */
3446
3447namespace triton {
3448 namespace ast {
3449
3450 /* Representation dispatcher from an abstract node */
3451 std::ostream& operator<<(std::ostream& stream, AbstractNode* node) {
3452 return node->getContext()->print(stream, node);
3453 }
3454
3455 }; /* ast namespace */
3456}; /* triton namespace */
3457
3458
3459
3460/* ====== Math utils */
3461
3462namespace triton {
3463 namespace ast {
3464
3466 triton::uint512 mask = -1;
3467 for (triton::uint32 i = 0; i < n; i++)
3468 hash = ((hash * hash) & mask);
3469 return hash;
3470 }
3471
3472
3474 if ((shift &= 511) == 0)
3475 return value;
3476 return ((value << shift) | (value >> (512 - shift)));
3477 }
3478
3479
3481 triton::sint512 value = 0;
3482
3483 if ((node->evaluate() >> (node->getBitvectorSize()-1)) & 1) {
3484 value = -1;
3485 value = ((value << node->getBitvectorSize()) | static_cast<triton::sint512>(node->evaluate()));
3486 }
3487 else {
3488 value = node->evaluate();
3489 }
3490
3491 return value;
3492 }
3493
3494 }; /* ast namespace */
3495}; /* triton namespace */
3496
3497
3498
3499/* ====== Node utilities */
3500
3501namespace triton {
3502 namespace ast {
3503
3504 /* Returns a new instance of a given node. */
3505 static SharedAbstractNode shallowCopy(AbstractNode* node, bool unroll) {
3506 SharedAbstractNode newNode = nullptr;
3507
3508 if (node == nullptr)
3509 throw triton::exceptions::Ast("triton::ast::shallowCopy(): node cannot be null.");
3510
3511 switch (node->getType()) {
3512 case ARRAY_NODE: newNode = std::make_shared<ArrayNode>(*reinterpret_cast<ArrayNode*>(node)); break;
3513 case ASSERT_NODE: newNode = std::make_shared<AssertNode>(*reinterpret_cast<AssertNode*>(node)); break;
3514 case BSWAP_NODE: newNode = std::make_shared<BswapNode>(*reinterpret_cast<BswapNode*>(node)); break;
3515 case BVADD_NODE: newNode = std::make_shared<BvaddNode>(*reinterpret_cast<BvaddNode*>(node)); break;
3516 case BVAND_NODE: newNode = std::make_shared<BvandNode>(*reinterpret_cast<BvandNode*>(node)); break;
3517 case BVASHR_NODE: newNode = std::make_shared<BvashrNode>(*reinterpret_cast<BvashrNode*>(node)); break;
3518 case BVLSHR_NODE: newNode = std::make_shared<BvlshrNode>(*reinterpret_cast<BvlshrNode*>(node)); break;
3519 case BVMUL_NODE: newNode = std::make_shared<BvmulNode>(*reinterpret_cast<BvmulNode*>(node)); break;
3520 case BVNAND_NODE: newNode = std::make_shared<BvnandNode>(*reinterpret_cast<BvnandNode*>(node)); break;
3521 case BVNEG_NODE: newNode = std::make_shared<BvnegNode>(*reinterpret_cast<BvnegNode*>(node)); break;
3522 case BVNOR_NODE: newNode = std::make_shared<BvnorNode>(*reinterpret_cast<BvnorNode*>(node)); break;
3523 case BVNOT_NODE: newNode = std::make_shared<BvnotNode>(*reinterpret_cast<BvnotNode*>(node)); break;
3524 case BVOR_NODE: newNode = std::make_shared<BvorNode>(*reinterpret_cast<BvorNode*>(node)); break;
3525 case BVROL_NODE: newNode = std::make_shared<BvrolNode>(*reinterpret_cast<BvrolNode*>(node)); break;
3526 case BVROR_NODE: newNode = std::make_shared<BvrorNode>(*reinterpret_cast<BvrorNode*>(node)); break;
3527 case BVSDIV_NODE: newNode = std::make_shared<BvsdivNode>(*reinterpret_cast<BvsdivNode*>(node)); break;
3528 case BVSGE_NODE: newNode = std::make_shared<BvsgeNode>(*reinterpret_cast<BvsgeNode*>(node)); break;
3529 case BVSGT_NODE: newNode = std::make_shared<BvsgtNode>(*reinterpret_cast<BvsgtNode*>(node)); break;
3530 case BVSHL_NODE: newNode = std::make_shared<BvshlNode>(*reinterpret_cast<BvshlNode*>(node)); break;
3531 case BVSLE_NODE: newNode = std::make_shared<BvsleNode>(*reinterpret_cast<BvsleNode*>(node)); break;
3532 case BVSLT_NODE: newNode = std::make_shared<BvsltNode>(*reinterpret_cast<BvsltNode*>(node)); break;
3533 case BVSMOD_NODE: newNode = std::make_shared<BvsmodNode>(*reinterpret_cast<BvsmodNode*>(node)); break;
3534 case BVSREM_NODE: newNode = std::make_shared<BvsremNode>(*reinterpret_cast<BvsremNode*>(node)); break;
3535 case BVSUB_NODE: newNode = std::make_shared<BvsubNode>(*reinterpret_cast<BvsubNode*>(node)); break;
3536 case BVUDIV_NODE: newNode = std::make_shared<BvudivNode>(*reinterpret_cast<BvudivNode*>(node)); break;
3537 case BVUGE_NODE: newNode = std::make_shared<BvugeNode>(*reinterpret_cast<BvugeNode*>(node)); break;
3538 case BVUGT_NODE: newNode = std::make_shared<BvugtNode>(*reinterpret_cast<BvugtNode*>(node)); break;
3539 case BVULE_NODE: newNode = std::make_shared<BvuleNode>(*reinterpret_cast<BvuleNode*>(node)); break;
3540 case BVULT_NODE: newNode = std::make_shared<BvultNode>(*reinterpret_cast<BvultNode*>(node)); break;
3541 case BVUREM_NODE: newNode = std::make_shared<BvuremNode>(*reinterpret_cast<BvuremNode*>(node)); break;
3542 case BVXNOR_NODE: newNode = std::make_shared<BvxnorNode>(*reinterpret_cast<BvxnorNode*>(node)); break;
3543 case BVXOR_NODE: newNode = std::make_shared<BvxorNode>(*reinterpret_cast<BvxorNode*>(node)); break;
3544 case BV_NODE: newNode = std::make_shared<BvNode>(*reinterpret_cast<BvNode*>(node)); break;
3545 case COMPOUND_NODE: newNode = std::make_shared<CompoundNode>(*reinterpret_cast<CompoundNode*>(node)); break;
3546 case CONCAT_NODE: newNode = std::make_shared<ConcatNode>(*reinterpret_cast<ConcatNode*>(node)); break;
3547 case DECLARE_NODE: newNode = std::make_shared<DeclareNode>(*reinterpret_cast<DeclareNode*>(node)); break;
3548 case DISTINCT_NODE: newNode = std::make_shared<DistinctNode>(*reinterpret_cast<DistinctNode*>(node)); break;
3549 case EQUAL_NODE: newNode = std::make_shared<EqualNode>(*reinterpret_cast<EqualNode*>(node)); break;
3550 case EXTRACT_NODE: newNode = std::make_shared<ExtractNode>(*reinterpret_cast<ExtractNode*>(node)); break;
3551 case FORALL_NODE: newNode = std::make_shared<ForallNode>(*reinterpret_cast<ForallNode*>(node)); break;
3552 case IFF_NODE: newNode = std::make_shared<IffNode>(*reinterpret_cast<IffNode*>(node)); break;
3553 case INTEGER_NODE: newNode = std::make_shared<IntegerNode>(*reinterpret_cast<IntegerNode*>(node)); break;
3554 case ITE_NODE: newNode = std::make_shared<IteNode>(*reinterpret_cast<IteNode*>(node)); break;
3555 case LAND_NODE: newNode = std::make_shared<LandNode>(*reinterpret_cast<LandNode*>(node)); break;
3556 case LET_NODE: newNode = std::make_shared<LetNode>(*reinterpret_cast<LetNode*>(node)); break;
3557 case LNOT_NODE: newNode = std::make_shared<LnotNode>(*reinterpret_cast<LnotNode*>(node)); break;
3558 case LOR_NODE: newNode = std::make_shared<LorNode>(*reinterpret_cast<LorNode*>(node)); break;
3559 case LXOR_NODE: newNode = std::make_shared<LxorNode>(*reinterpret_cast<LxorNode*>(node)); break;
3560 case REFERENCE_NODE: {
3561 if (unroll)
3562 return triton::ast::shallowCopy(reinterpret_cast<ReferenceNode*>(node)->getSymbolicExpression()->getAst().get(), unroll);
3563 else
3564 newNode = std::make_shared<ReferenceNode>(*reinterpret_cast<ReferenceNode*>(node));
3565 break;
3566 }
3567 case SELECT_NODE: newNode = std::make_shared<SelectNode>(*reinterpret_cast<SelectNode*>(node)); break;
3568 case STORE_NODE: newNode = std::make_shared<StoreNode>(*reinterpret_cast<StoreNode*>(node)); break;
3569 case STRING_NODE: newNode = std::make_shared<StringNode>(*reinterpret_cast<StringNode*>(node)); break;
3570 case SX_NODE: newNode = std::make_shared<SxNode>(*reinterpret_cast<SxNode*>(node)); break;
3571 case VARIABLE_NODE: newNode = node->shared_from_this(); /* Do not duplicate shared var (see #792) */ break;
3572 case ZX_NODE: newNode = std::make_shared<ZxNode>(*reinterpret_cast<ZxNode*>(node)); break;
3573 default:
3574 throw triton::exceptions::Ast("triton::ast::shallowCopy(): Invalid type node.");
3575 }
3576
3577 if (newNode == nullptr)
3578 throw triton::exceptions::Ast("triton::ast::shallowCopy(): Not enough memory.");
3579
3580 /* Remove parents as this is a new node which has no connections with original AST */
3581 if (node->getType() != VARIABLE_NODE) {
3582 /* VARIABLE_NODE are not duplicated (see #792), so don't remove their parents */
3583 auto parents = newNode->getParents();
3584 for (auto& p : parents) {
3585 newNode->removeParent(p.get());
3586 }
3587 }
3588
3589 return node->getContext()->collect(newNode);
3590 }
3591
3592
3594 std::unordered_map<AbstractNode*, SharedAbstractNode> exprs;
3595 auto nodes = childrenExtraction(node->shared_from_this(), unroll, true);
3596
3597 for (auto&& n : nodes) {
3598 /* Do a copy of all children */
3599 const auto& newNode = shallowCopy(n.get(), unroll);
3600 exprs[n.get()] = newNode;
3601
3602 /* For each child, set its parent */
3603 auto& children = newNode->getChildren();
3604 for (auto& child : children) {
3605 child = exprs[child.get()];
3606 child->setParent(newNode.get());
3607 }
3608 }
3609
3610 /* Return the root node */
3611 return exprs.at(node);
3612 }
3613
3614
3616 return triton::ast::newInstance(node.get(), true);
3617 }
3618
3619
3620 /* Returns a vector of unique AST-nodes sorted topologically
3621 *
3622 * Depending on @descent argument this function produces topologically sorted vector of nodes from DAG consisting of
3623 * either parents or children of given @node. This helps to prevent exponential complexity when complex AST are
3624 * parsed during z3 conversion, copying and parents reinitialization.
3625 *
3626 * @unroll - traverses through ReferenceNodes
3627 * @revert - reverses the result
3628 * @descent - if true we traverse through children of nodes, otherwise parents
3629 */
3630 static std::vector<SharedAbstractNode> nodesExtraction(const SharedAbstractNode& node, bool unroll, bool revert, bool descend) {
3631 std::vector<SharedAbstractNode> result;
3632 std::unordered_set<AbstractNode*> visited;
3633 std::stack<std::pair<SharedAbstractNode, bool>> worklist;
3634
3635 if (node == nullptr)
3636 throw triton::exceptions::Ast("triton::ast::nodesExtraction(): Node cannot be null.");
3637
3638 /*
3639 * We use a worklist strategy to avoid recursive calls
3640 * and so stack overflow when going through a big AST.
3641 */
3642 worklist.push({node, false});
3643
3644 while (!worklist.empty()) {
3645 SharedAbstractNode ast;
3646 bool postOrder;
3647 std::tie(ast, postOrder) = worklist.top();
3648 worklist.pop();
3649
3650 /* It means that we visited all children of this node and we can put it in the result */
3651 if (postOrder) {
3652 result.push_back(ast);
3653 continue;
3654 }
3655
3656 if (!visited.insert(ast.get()).second) {
3657 continue;
3658 }
3659
3660 worklist.push({ast, true});
3661
3662 const auto& relatives = descend ? ast->getChildren() : ast->getParents();
3663
3664 /* Proceed relatives */
3665 for (const auto& r : relatives) {
3666 if (visited.find(r.get()) == visited.end()) {
3667 worklist.push({r, false});
3668 }
3669 }
3670
3671 /* If unroll is true, we unroll all references */
3672 if (unroll && ast->getType() == REFERENCE_NODE) {
3673 const SharedAbstractNode& ref = reinterpret_cast<ReferenceNode*>(ast.get())->getSymbolicExpression()->getAst();
3674 if (visited.find(ref.get()) == visited.end()) {
3675 worklist.push({ref, false});
3676 }
3677 }
3678 }
3679
3680 /* The result is in reversed topological sort meaning that children go before parents */
3681 if (!revert) {
3682 std::reverse(result.begin(), result.end());
3683 }
3684
3685 return result;
3686 }
3687
3688
3689 std::vector<SharedAbstractNode> childrenExtraction(const SharedAbstractNode& node, bool unroll, bool revert) {
3690 return nodesExtraction(node, unroll, revert, true);
3691 }
3692
3693
3694 std::vector<SharedAbstractNode> parentsExtraction(const SharedAbstractNode& node, bool revert) {
3695 return nodesExtraction(node, false, revert, false);
3696 }
3697
3698
3699 std::deque<SharedAbstractNode> search(const SharedAbstractNode& node, triton::ast::ast_e match) {
3700 std::stack<AbstractNode*> worklist;
3701 std::deque<SharedAbstractNode> result;
3702 std::unordered_set<const AbstractNode*> visited;
3703
3704 worklist.push(node.get());
3705 while (!worklist.empty()) {
3706 AbstractNode* current = worklist.top();
3707 worklist.pop();
3708
3709 // This means that node is already visited and we will not need to visited it second time
3710 if (visited.find(current) != visited.end()) {
3711 continue;
3712 }
3713
3714 visited.insert(current);
3715 if (match == triton::ast::ANY_NODE || current->getType() == match)
3716 result.push_front(current->shared_from_this());
3717
3718 if (current->getType() == REFERENCE_NODE) {
3719 worklist.push(reinterpret_cast<triton::ast::ReferenceNode*>(current)->getSymbolicExpression()->getAst().get());
3720 }
3721 else {
3722 for (const SharedAbstractNode& child : current->getChildren()) {
3723 worklist.push(child.get());
3724 }
3725 }
3726 }
3727
3728 return result;
3729 }
3730
3731
3733 AbstractNode* ptr = node.get();
3734
3735 while (ptr->getType() == REFERENCE_NODE) {
3736 const ReferenceNode* ref = reinterpret_cast<const ReferenceNode*>(ptr);
3737 ptr = ref->getSymbolicExpression()->getAst().get();
3738 }
3739
3740 return ptr->shared_from_this();
3741 }
3742
3743
3745 auto nref = triton::ast::dereference(node);
3746 switch(nref->getType()) {
3747 case ARRAY_NODE: return reinterpret_cast<ArrayNode*>(nref.get())->getIndexSize();
3748 case STORE_NODE: return reinterpret_cast<StoreNode*>(nref.get())->getIndexSize();
3749 default:
3750 throw triton::exceptions::Ast("triton::ast::getIndexSize(): The given node is not an array.");
3751 }
3752 }
3753
3754 }; /* ast namespace */
3755}; /* triton namespace */
Abstract node.
Definition: ast.hpp:68
TRITON_EXPORT bool canReplaceNodeWithoutUpdate(const SharedAbstractNode &other) const
Returns true if the node's value, value type and properties match those of the second one.
Definition: ast.cpp:145
TRITON_EXPORT triton::uint32 getLevel(void) const
Returns the deep level of the tree.
Definition: ast.cpp:169
bool symbolized
True if the tree contains a symbolic variable.
Definition: ast.hpp:97
TRITON_EXPORT bool hasSameConcreteValueAndTypeAs(const SharedAbstractNode &other) const
Returns true if the node's concrete value and value type match those of the second one.
Definition: ast.cpp:138
TRITON_EXPORT SharedAstContext getContext(void) const
Access to its context.
Definition: ast.cpp:50
TRITON_EXPORT AbstractNode(triton::ast::ast_e type, const SharedAstContext &ctxt)
Constructor.
Definition: ast.cpp:31
triton::ast::ast_e type
The type of the node.
Definition: ast.hpp:78
TRITON_EXPORT void setParent(AbstractNode *p)
Sets a parent node.
Definition: ast.cpp:205
TRITON_EXPORT bool equalTo(const SharedAbstractNode &other) const
Returns true if the current tree is equal to the second one.
Definition: ast.cpp:151
TRITON_EXPORT void setChild(triton::uint32 index, const SharedAbstractNode &child)
Sets a child at an index.
Definition: ast.cpp:250
TRITON_EXPORT bool isSigned(void) const
According to the size of the expression, returns true if the MSB is 1.
Definition: ast.cpp:72
TRITON_EXPORT std::vector< SharedAbstractNode > getParents(void)
Returns the parents of node or an empty set if there is still no parent defined.
Definition: ast.cpp:187
TRITON_EXPORT triton::uint512 getHash(void) const
Returns the hash of the tree.
Definition: ast.cpp:164
bool array
True if it's an array node.
Definition: ast.hpp:103
SharedAstContext ctxt
Contect use to create this node.
Definition: ast.hpp:106
TRITON_EXPORT triton::uint512 getBitvectorMask(void) const
Returns the vector mask according the size of the node.
Definition: ast.cpp:65
TRITON_EXPORT bool isArray(void) const
Returns true if it's an array node.
Definition: ast.cpp:116
virtual TRITON_EXPORT ~AbstractNode()
Destructor.
Definition: ast.cpp:44
triton::uint32 size
The size of the node.
Definition: ast.hpp:88
TRITON_EXPORT bool isSymbolized(void) const
Returns true if the tree contains a symbolic variable.
Definition: ast.cpp:79
std::vector< SharedAbstractNode > children
The children of the node.
Definition: ast.hpp:81
TRITON_EXPORT triton::uint32 getBitvectorSize(void) const
Returns the size of the node.
Definition: ast.cpp:60
TRITON_EXPORT bool isLogical(void) const
Returns true if it's a logical node.
Definition: ast.cpp:84
TRITON_EXPORT std::vector< SharedAbstractNode > & getChildren(void)
Returns the children of the node.
Definition: ast.cpp:182
bool logical
True if it's a logical node.
Definition: ast.hpp:100
TRITON_EXPORT void setBitvectorSize(triton::uint32 size)
Sets the size of the node.
Definition: ast.cpp:273
triton::uint512 eval
The value of the tree from this root node.
Definition: ast.hpp:91
triton::uint512 hash
The hash of the tree.
Definition: ast.hpp:94
TRITON_EXPORT std::string str(void) const
Returns the string representation of the node.
Definition: ast.cpp:278
TRITON_EXPORT void addChild(const SharedAbstractNode &child)
Adds a child.
Definition: ast.cpp:245
TRITON_EXPORT void removeParent(AbstractNode *p)
Removes a parent node.
Definition: ast.cpp:226
void initParents(void)
Initializes parents.
Definition: ast.cpp:174
TRITON_EXPORT triton::uint512 evaluate(void) const
Evaluates the tree.
Definition: ast.cpp:159
TRITON_EXPORT triton::ast::ast_e getType(void) const
Returns the type of the node.
Definition: ast.cpp:55
triton::uint32 level
Deep level for computing hash.
Definition: ast.hpp:75
(Array (_ BitVec indexSize) (_ BitVec 8)) node
Definition: ast.hpp:193
TRITON_EXPORT void store(triton::uint64 addr, triton::uint8 value)
Stores a concrete value into the memory array.
Definition: ast.cpp:332
TRITON_EXPORT triton::uint8 select(triton::uint64 addr) const
Select a concrete value into the memory array.
Definition: ast.cpp:337
TRITON_EXPORT triton::uint32 getIndexSize(void) const
Gets the index size.
Definition: ast.cpp:360
TRITON_EXPORT std::unordered_map< triton::uint64, triton::uint8 > & getMemory(void)
Gets the concrete memory array.
Definition: ast.cpp:355
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:296
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:373
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:423
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:2161
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:483
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:537
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:591
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:677
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:731
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:785
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:838
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:889
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:942
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:993
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:1051
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:1113
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:1171
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:1238
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:1299
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:1360
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:1414
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:1475
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:1536
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:1601
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:1666
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:1720
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:1778
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:1832
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:1886
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:1940
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:1994
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:2052
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:2106
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:2215
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:2263
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:2322
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:2373
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:2427
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:2482
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:2539
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:2596
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:2652
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:2688
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:2749
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:2802
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:2852
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:2903
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:2955
Reference node.
Definition: ast.hpp:789
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:3007
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:3051
(store array index expr)
Definition: ast.hpp:816
TRITON_EXPORT triton::uint32 getIndexSize(void) const
Gets the index size.
Definition: ast.cpp:3213
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:3124
TRITON_EXPORT std::unordered_map< triton::uint64, triton::uint8 > & getMemory(void)
Gets the concrete memory array.
Definition: ast.cpp:3208
TRITON_EXPORT triton::uint8 select(triton::uint64 addr) const
Select a concrete value into the memory array.
Definition: ast.cpp:3190
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:3226
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:3268
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:3327
TRITON_EXPORT ZxNode(triton::uint32 sizeExt, const SharedAbstractNode &expr)
Create a zero extend of expr to sizeExt bits.
Definition: ast.cpp:3363
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:3369
The exception class used by all AST nodes.
Definition: exceptions.hpp:389
triton::uint32 getIndexSize(const SharedAbstractNode &node)
Gets the index size of an array.
Definition: ast.cpp:3744
SharedAbstractNode unroll(const triton::ast::SharedAbstractNode &node)
AST C++ API - Unrolls the SSA form of a given AST.
Definition: ast.cpp:3615
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:3732
std::weak_ptr< triton::ast::AbstractNode > WeakAbstractNode
Weak Abstract Node.
Definition: ast.hpp:62
triton::uint512 hash2n(triton::uint512 hash, triton::uint32 n)
Custom hash2n function for hash routine.
Definition: ast.cpp:3465
std::vector< SharedAbstractNode > parentsExtraction(const SharedAbstractNode &node, bool revert)
Returns node and all its parents of an AST sorted topologically. If revert is true,...
Definition: ast.cpp:3694
std::vector< SharedAbstractNode > childrenExtraction(const SharedAbstractNode &node, bool unroll, bool revert)
Returns node and all its children of an AST sorted topologically. If unroll is true,...
Definition: ast.cpp:3689
SharedAbstractNode newInstance(AbstractNode *node, bool unroll)
AST C++ API - Duplicates the AST.
Definition: ast.cpp:3593
triton::sint512 modularSignExtend(AbstractNode *node)
Custom modular sign extend for bitwise operation.
Definition: ast.cpp:3480
std::deque< SharedAbstractNode > search(const SharedAbstractNode &node, triton::ast::ast_e match)
Returns a deque of collected matched nodes via a depth-first pre order traversal.
Definition: ast.cpp:3699
triton::uint512 rotl(const triton::uint512 &value, triton::uint32 shift)
Custom rotate left function for hash routine.
Definition: ast.cpp:3473
std::shared_ptr< triton::ast::AstContext > SharedAstContext
Shared AST context.
Definition: ast.hpp:65
@ REFERENCE_NODE
Definition: astEnums.hpp:79
constexpr triton::uint32 byte
byte size in bit
Definition: cpuSize.hpp:60
constexpr triton::uint32 max_supported
max size supported in bit
Definition: cpuSize.hpp:76
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.
std::uint64_t uint64
unisgned 64-bits
Definition: tritonTypes.hpp:42
std::uint32_t uint32
unisgned 32-bits
Definition: tritonTypes.hpp:39
std::uint8_t uint8
unisgned 8-bits
Definition: tritonTypes.hpp:33
The Triton namespace.