libTriton  version 1.0 build 1549
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 switch(this->children[0]->getType()) {
3067 case ARRAY_NODE:
3068 this->eval = reinterpret_cast<ArrayNode*>(this->children[0].get())->select(this->children[1]);
3069 break;
3070 case STORE_NODE:
3071 this->eval = reinterpret_cast<StoreNode*>(this->children[0].get())->select(this->children[1]);
3072 break;
3073 default:
3074 throw triton::exceptions::Ast("SelectNode::init(): Invalid sort");
3075 }
3076
3077 /* Init children and spread information */
3078 for (triton::uint32 index = 0; index < this->children.size(); index++) {
3079 this->children[index]->setParent(this);
3080 this->symbolized |= this->children[index]->isSymbolized();
3081 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
3082 }
3083
3084 /* Init parents if needed */
3085 if (withParents) {
3086 this->initParents();
3087 }
3088
3089 this->initHash();
3090 }
3091
3092
3093 void SelectNode::initHash(void) {
3094 triton::uint512 s = this->children.size();
3095
3096 this->hash = static_cast<triton::uint64>(this->type);
3097 if (s) this->hash = this->hash * s;
3098 for (triton::uint32 index = 0; index < this->children.size(); index++) {
3099 this->hash = this->hash * this->children[index]->getHash();
3100 }
3101
3102 this->hash = triton::ast::rotl(this->hash, this->level);
3103 }
3104
3105
3106 /* ====== Store node */
3107
3108
3109 StoreNode::StoreNode(const SharedAbstractNode& array, triton::usize index, const SharedAbstractNode& expr): AbstractNode(STORE_NODE, array->getContext()) {
3110 this->addChild(array);
3111 this->addChild(this->ctxt->bv(index, triton::ast::getIndexSize(array)));
3112 this->addChild(expr);
3113 }
3114
3115
3116 StoreNode::StoreNode(const SharedAbstractNode& array, const SharedAbstractNode& index, const SharedAbstractNode& expr): AbstractNode(STORE_NODE, array->getContext()) {
3117 this->addChild(array);
3118 this->addChild(index);
3119 this->addChild(expr);
3120 }
3121
3122
3123 void StoreNode::init(bool withParents) {
3124 if (this->children.size() != 3)
3125 throw triton::exceptions::Ast("StoreNode::init(): Must take three children.");
3126
3127 if (this->children[0]->isArray() == false)
3128 throw triton::exceptions::Ast("StoreNode::init(): Must take an array as first argument.");
3129
3130 if (triton::ast::getIndexSize(this->children[0]) != this->children[1]->getBitvectorSize())
3131 throw triton::exceptions::Ast("StoreNode::init(): Size of indexing must be equal to the array indexing size.");
3132
3134 throw triton::exceptions::Ast("StoreNode::init(): The stored node must be 8-bit long");
3135
3136 /* Init attributes */
3137 this->eval = this->children[2]->evaluate();
3138 this->size = 0; // Array do not have size.
3139 this->level = 1;
3140 this->symbolized = false;
3141
3142 /* Spread the memory array from previous level */
3143 switch(this->children[0]->getType()) {
3144 case ARRAY_NODE:
3145 this->indexSize = reinterpret_cast<ArrayNode*>(this->children[0].get())->getIndexSize();
3146 this->memory = reinterpret_cast<ArrayNode*>(this->children[0].get())->getMemory();
3147 break;
3148 case STORE_NODE:
3149 this->indexSize = reinterpret_cast<StoreNode*>(this->children[0].get())->getIndexSize();
3150 this->memory = reinterpret_cast<StoreNode*>(this->children[0].get())->getMemory();
3151 break;
3152 default:
3153 throw triton::exceptions::Ast("StoreNode::init(): Invalid sort");
3154 }
3155
3156 /* Store the value to the memory array */
3157 this->memory[static_cast<triton::uint64>(this->children[1]->evaluate())] = static_cast<triton::uint8>(this->eval);
3158
3159 /* Init children and spread information */
3160 for (triton::uint32 index = 0; index < this->children.size(); index++) {
3161 this->children[index]->setParent(this);
3162 this->symbolized |= this->children[index]->isSymbolized();
3163 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
3164 }
3165
3166 /* Init parents if needed */
3167 if (withParents) {
3168 this->initParents();
3169 }
3170
3171 this->initHash();
3172 }
3173
3174
3175 void StoreNode::initHash(void) {
3176 triton::uint512 s = this->children.size();
3177
3178 this->hash = static_cast<triton::uint64>(this->type);
3179 if (s) this->hash = this->hash * s;
3180 for (triton::uint32 index = 0; index < this->children.size(); index++) {
3181 this->hash = this->hash * this->children[index]->getHash();
3182 }
3183
3184 this->hash = triton::ast::rotl(this->hash, this->level);
3185 }
3186
3187
3189 if (this->memory.find(addr) != this->memory.end()) {
3190 return this->memory.at(addr);
3191 }
3192 return 0;
3193 }
3194
3195
3197 return this->select(static_cast<triton::uint64>(addr));
3198 }
3199
3200
3202 return this->select(static_cast<triton::uint64>(node->evaluate()));
3203 }
3204
3205
3206 std::unordered_map<triton::uint64, triton::uint8>& StoreNode::getMemory(void) {
3207 return this->memory;
3208 }
3209
3210
3212 return this->indexSize;
3213 }
3214
3215
3216 /* ====== String node */
3217
3218
3219 StringNode::StringNode(std::string value, const SharedAstContext& ctxt): AbstractNode(STRING_NODE, ctxt) {
3220 this->value = value;
3221 }
3222
3223
3224 void StringNode::init(bool withParents) {
3225 /* Init attributes */
3226 this->eval = 0;
3227 this->size = 0;
3228 this->level = 1;
3229 this->symbolized = false;
3230
3231 /* Init parents if needed */
3232 if (withParents) {
3233 this->initParents();
3234 }
3235
3236 this->initHash();
3237 }
3238
3239
3240 std::string StringNode::getString(void) {
3241 return this->value;
3242 }
3243
3244
3245 void StringNode::initHash(void) {
3246 triton::uint32 index = 1;
3247
3248 this->hash = static_cast<triton::uint64>(this->type);
3249 for (std::string::const_iterator it=this->value.cbegin(); it != this->value.cend(); it++) {
3250 this->hash = triton::ast::rotl(*it ^ this->hash ^ triton::ast::hash2n(this->hash, index++), *it);
3251 }
3252
3253 this->hash = triton::ast::rotl(this->hash, this->level);
3254 }
3255
3256
3257 /* ====== sx */
3258
3259
3260 SxNode::SxNode(triton::uint32 sizeExt, const SharedAbstractNode& expr): AbstractNode(SX_NODE, expr->getContext()) {
3261 this->addChild(this->ctxt->integer(sizeExt));
3262 this->addChild(expr);
3263 }
3264
3265
3266 void SxNode::init(bool withParents) {
3267 triton::uint32 sizeExt = 0;
3268
3269 if (this->children.size() < 2)
3270 throw triton::exceptions::Ast("SxNode::init(): Must take at least two children.");
3271
3272 if (this->children[1]->isArray())
3273 throw triton::exceptions::Ast("SxNode::init(): Cannot take an array as argument.");
3274
3275 sizeExt = triton::ast::getInteger<triton::uint32>(this->children[0]);
3276
3277 /* Init attributes */
3278 this->size = sizeExt + this->children[1]->getBitvectorSize();
3280 throw triton::exceptions::Ast("SxNode::SxNode(): Size cannot be greater than triton::bitsize::max_supported.");
3281
3282 this->level = 1;
3283 this->symbolized = false;
3284 this->eval = ((((this->children[1]->evaluate() >> (this->children[1]->getBitvectorSize()-1)) == 0) ?
3285 this->children[1]->evaluate() : (this->children[1]->evaluate() | ~(this->children[1]->getBitvectorMask()))) & this->getBitvectorMask());
3286
3287 /* Init children and spread information */
3288 for (triton::uint32 index = 0; index < this->children.size(); index++) {
3289 this->children[index]->setParent(this);
3290 this->symbolized |= this->children[index]->isSymbolized();
3291 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
3292 }
3293
3294 /* Init parents if needed */
3295 if (withParents) {
3296 this->initParents();
3297 }
3298
3299 this->initHash();
3300 }
3301
3302
3303 void SxNode::initHash(void) {
3304 triton::uint512 s = this->children.size();
3305
3306 this->hash = static_cast<triton::uint64>(this->type);
3307 if (s) this->hash = this->hash * s;
3308 for (triton::uint32 index = 0; index < this->children.size(); index++) {
3309 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
3310 }
3311
3312 this->hash = triton::ast::rotl(this->hash, this->level);
3313 }
3314
3315
3316 /* ====== Variable node */
3317
3318
3319 VariableNode::VariableNode(const triton::engines::symbolic::SharedSymbolicVariable& symVar, const SharedAstContext& ctxt)
3320 : AbstractNode(VARIABLE_NODE, ctxt),
3321 symVar(symVar) {
3322 }
3323
3324
3325 void VariableNode::init(bool withParents) {
3326 this->size = this->symVar->getSize();
3327 this->eval = this->ctxt->getVariableValue(this->symVar->getName()) & this->getBitvectorMask();
3328 this->symbolized = true;
3329 this->level = 1;
3330
3331 /* Init parents if needed */
3332 if (withParents) {
3333 this->initParents();
3334 }
3335
3336 this->initHash();
3337 }
3338
3339
3340 const triton::engines::symbolic::SharedSymbolicVariable& VariableNode::getSymbolicVariable() {
3341 return this->symVar;
3342 }
3343
3344
3345 void VariableNode::initHash(void) {
3346 triton::uint32 index = 1;
3347 triton::usize id = this->symVar->getId();
3348
3349 this->hash = static_cast<triton::uint64>(this->type);
3350 for (char c : this->symVar->getName()) {
3351 this->hash = triton::ast::rotl(c ^ this->hash ^ triton::ast::hash2n(this->hash, index++), (id & 511));
3352 }
3353
3354 this->hash = triton::ast::rotl(this->hash, this->level);
3355 }
3356
3357
3358 /* ====== zx */
3359
3360
3361 ZxNode::ZxNode(triton::uint32 sizeExt, const SharedAbstractNode& expr): AbstractNode(ZX_NODE, expr->getContext()) {
3362 this->addChild(this->ctxt->integer(sizeExt));
3363 this->addChild(expr);
3364 }
3365
3366
3367 void ZxNode::init(bool withParents) {
3368 triton::uint32 sizeExt = 0;
3369
3370 if (this->children.size() < 2)
3371 throw triton::exceptions::Ast("ZxNode::init(): Must take at least two children.");
3372
3373 if (this->children[1]->isArray())
3374 throw triton::exceptions::Ast("ZxNode::init(): Cannot take an array as argument.");
3375
3376 sizeExt = triton::ast::getInteger<triton::uint32>(this->children[0]);
3377
3378 /* Init attributes */
3379 this->size = sizeExt + this->children[1]->getBitvectorSize();
3381 throw triton::exceptions::Ast("ZxNode::init(): Size cannot be greater than triton::bitsize::max_supported.");
3382
3383 this->eval = (this->children[1]->evaluate() & this->getBitvectorMask());
3384 this->level = 1;
3385 this->symbolized = false;
3386
3387 /* Init children and spread information */
3388 for (triton::uint32 index = 0; index < this->children.size(); index++) {
3389 this->children[index]->setParent(this);
3390 this->symbolized |= this->children[index]->isSymbolized();
3391 this->level = std::max(this->children[index]->getLevel() + 1, this->level);
3392 }
3393
3394 /* Init parents if needed */
3395 if (withParents) {
3396 this->initParents();
3397 }
3398
3399 this->initHash();
3400 }
3401
3402
3403 void ZxNode::initHash(void) {
3404 triton::uint512 s = this->children.size();
3405
3406 this->hash = static_cast<triton::uint64>(this->type);
3407 if (s) this->hash = this->hash * s;
3408 for (triton::uint32 index = 0; index < this->children.size(); index++) {
3409 this->hash = this->hash * triton::ast::hash2n(this->children[index]->getHash(), index+1);
3410 }
3411
3412 this->hash = triton::ast::rotl(this->hash, this->level);
3413 }
3414
3415 }; /* ast namespace */
3416}; /* triton namespace */
3417
3418
3419
3420/* ====== Force templates declarations */
3421
3422namespace triton {
3423 namespace ast {
3424
3425 template TRITON_EXPORT CompoundNode::CompoundNode(const std::list<SharedAbstractNode>& exprs, const SharedAstContext& ctxt);
3426 template TRITON_EXPORT CompoundNode::CompoundNode(const std::vector<SharedAbstractNode>& exprs, const SharedAstContext& ctxt);
3427 template TRITON_EXPORT ConcatNode::ConcatNode(const std::list<SharedAbstractNode>& exprs, const SharedAstContext& ctxt);
3428 template TRITON_EXPORT ConcatNode::ConcatNode(const std::vector<SharedAbstractNode>& exprs, const SharedAstContext& ctxt);
3429 template TRITON_EXPORT ForallNode::ForallNode(const std::list<SharedAbstractNode>& vars, const SharedAbstractNode& body);
3430 template TRITON_EXPORT ForallNode::ForallNode(const std::vector<SharedAbstractNode>& vars, const SharedAbstractNode& body);
3431 template TRITON_EXPORT LandNode::LandNode(const std::list<SharedAbstractNode>& exprs, const SharedAstContext& ctxt);
3432 template TRITON_EXPORT LandNode::LandNode(const std::vector<SharedAbstractNode>& exprs, const SharedAstContext& ctxt);
3433 template TRITON_EXPORT LorNode::LorNode(const std::list<SharedAbstractNode>& exprs, const SharedAstContext& ctxt);
3434 template TRITON_EXPORT LorNode::LorNode(const std::vector<SharedAbstractNode>& exprs, const SharedAstContext& ctxt);
3435 template TRITON_EXPORT LxorNode::LxorNode(const std::list<SharedAbstractNode>& exprs, const SharedAstContext& ctxt);
3436 template TRITON_EXPORT LxorNode::LxorNode(const std::vector<SharedAbstractNode>& exprs, const SharedAstContext& ctxt);
3437
3438 }; /* ast namespace */
3439}; /* triton namespace */
3440
3441
3442
3443/* ====== Operators */
3444
3445namespace triton {
3446 namespace ast {
3447
3448 /* Representation dispatcher from an abstract node */
3449 std::ostream& operator<<(std::ostream& stream, AbstractNode* node) {
3450 return node->getContext()->print(stream, node);
3451 }
3452
3453 }; /* ast namespace */
3454}; /* triton namespace */
3455
3456
3457
3458/* ====== Math utils */
3459
3460namespace triton {
3461 namespace ast {
3462
3464 triton::uint512 mask = -1;
3465 for (triton::uint32 i = 0; i < n; i++)
3466 hash = ((hash * hash) & mask);
3467 return hash;
3468 }
3469
3470
3472 if ((shift &= 511) == 0)
3473 return value;
3474 return ((value << shift) | (value >> (512 - shift)));
3475 }
3476
3477
3479 triton::sint512 value = 0;
3480
3481 if ((node->evaluate() >> (node->getBitvectorSize()-1)) & 1) {
3482 value = -1;
3483 value = ((value << node->getBitvectorSize()) | static_cast<triton::sint512>(node->evaluate()));
3484 }
3485 else {
3486 value = node->evaluate();
3487 }
3488
3489 return value;
3490 }
3491
3492 }; /* ast namespace */
3493}; /* triton namespace */
3494
3495
3496
3497/* ====== Node utilities */
3498
3499namespace triton {
3500 namespace ast {
3501
3502 /* Returns a new instance of a given node. */
3503 static SharedAbstractNode shallowCopy(AbstractNode* node, bool unroll) {
3504 SharedAbstractNode newNode = nullptr;
3505
3506 if (node == nullptr)
3507 throw triton::exceptions::Ast("triton::ast::shallowCopy(): node cannot be null.");
3508
3509 switch (node->getType()) {
3510 case ARRAY_NODE: newNode = std::make_shared<ArrayNode>(*reinterpret_cast<ArrayNode*>(node)); break;
3511 case ASSERT_NODE: newNode = std::make_shared<AssertNode>(*reinterpret_cast<AssertNode*>(node)); break;
3512 case BSWAP_NODE: newNode = std::make_shared<BswapNode>(*reinterpret_cast<BswapNode*>(node)); break;
3513 case BVADD_NODE: newNode = std::make_shared<BvaddNode>(*reinterpret_cast<BvaddNode*>(node)); break;
3514 case BVAND_NODE: newNode = std::make_shared<BvandNode>(*reinterpret_cast<BvandNode*>(node)); break;
3515 case BVASHR_NODE: newNode = std::make_shared<BvashrNode>(*reinterpret_cast<BvashrNode*>(node)); break;
3516 case BVLSHR_NODE: newNode = std::make_shared<BvlshrNode>(*reinterpret_cast<BvlshrNode*>(node)); break;
3517 case BVMUL_NODE: newNode = std::make_shared<BvmulNode>(*reinterpret_cast<BvmulNode*>(node)); break;
3518 case BVNAND_NODE: newNode = std::make_shared<BvnandNode>(*reinterpret_cast<BvnandNode*>(node)); break;
3519 case BVNEG_NODE: newNode = std::make_shared<BvnegNode>(*reinterpret_cast<BvnegNode*>(node)); break;
3520 case BVNOR_NODE: newNode = std::make_shared<BvnorNode>(*reinterpret_cast<BvnorNode*>(node)); break;
3521 case BVNOT_NODE: newNode = std::make_shared<BvnotNode>(*reinterpret_cast<BvnotNode*>(node)); break;
3522 case BVOR_NODE: newNode = std::make_shared<BvorNode>(*reinterpret_cast<BvorNode*>(node)); break;
3523 case BVROL_NODE: newNode = std::make_shared<BvrolNode>(*reinterpret_cast<BvrolNode*>(node)); break;
3524 case BVROR_NODE: newNode = std::make_shared<BvrorNode>(*reinterpret_cast<BvrorNode*>(node)); break;
3525 case BVSDIV_NODE: newNode = std::make_shared<BvsdivNode>(*reinterpret_cast<BvsdivNode*>(node)); break;
3526 case BVSGE_NODE: newNode = std::make_shared<BvsgeNode>(*reinterpret_cast<BvsgeNode*>(node)); break;
3527 case BVSGT_NODE: newNode = std::make_shared<BvsgtNode>(*reinterpret_cast<BvsgtNode*>(node)); break;
3528 case BVSHL_NODE: newNode = std::make_shared<BvshlNode>(*reinterpret_cast<BvshlNode*>(node)); break;
3529 case BVSLE_NODE: newNode = std::make_shared<BvsleNode>(*reinterpret_cast<BvsleNode*>(node)); break;
3530 case BVSLT_NODE: newNode = std::make_shared<BvsltNode>(*reinterpret_cast<BvsltNode*>(node)); break;
3531 case BVSMOD_NODE: newNode = std::make_shared<BvsmodNode>(*reinterpret_cast<BvsmodNode*>(node)); break;
3532 case BVSREM_NODE: newNode = std::make_shared<BvsremNode>(*reinterpret_cast<BvsremNode*>(node)); break;
3533 case BVSUB_NODE: newNode = std::make_shared<BvsubNode>(*reinterpret_cast<BvsubNode*>(node)); break;
3534 case BVUDIV_NODE: newNode = std::make_shared<BvudivNode>(*reinterpret_cast<BvudivNode*>(node)); break;
3535 case BVUGE_NODE: newNode = std::make_shared<BvugeNode>(*reinterpret_cast<BvugeNode*>(node)); break;
3536 case BVUGT_NODE: newNode = std::make_shared<BvugtNode>(*reinterpret_cast<BvugtNode*>(node)); break;
3537 case BVULE_NODE: newNode = std::make_shared<BvuleNode>(*reinterpret_cast<BvuleNode*>(node)); break;
3538 case BVULT_NODE: newNode = std::make_shared<BvultNode>(*reinterpret_cast<BvultNode*>(node)); break;
3539 case BVUREM_NODE: newNode = std::make_shared<BvuremNode>(*reinterpret_cast<BvuremNode*>(node)); break;
3540 case BVXNOR_NODE: newNode = std::make_shared<BvxnorNode>(*reinterpret_cast<BvxnorNode*>(node)); break;
3541 case BVXOR_NODE: newNode = std::make_shared<BvxorNode>(*reinterpret_cast<BvxorNode*>(node)); break;
3542 case BV_NODE: newNode = std::make_shared<BvNode>(*reinterpret_cast<BvNode*>(node)); break;
3543 case COMPOUND_NODE: newNode = std::make_shared<CompoundNode>(*reinterpret_cast<CompoundNode*>(node)); break;
3544 case CONCAT_NODE: newNode = std::make_shared<ConcatNode>(*reinterpret_cast<ConcatNode*>(node)); break;
3545 case DECLARE_NODE: newNode = std::make_shared<DeclareNode>(*reinterpret_cast<DeclareNode*>(node)); break;
3546 case DISTINCT_NODE: newNode = std::make_shared<DistinctNode>(*reinterpret_cast<DistinctNode*>(node)); break;
3547 case EQUAL_NODE: newNode = std::make_shared<EqualNode>(*reinterpret_cast<EqualNode*>(node)); break;
3548 case EXTRACT_NODE: newNode = std::make_shared<ExtractNode>(*reinterpret_cast<ExtractNode*>(node)); break;
3549 case FORALL_NODE: newNode = std::make_shared<ForallNode>(*reinterpret_cast<ForallNode*>(node)); break;
3550 case IFF_NODE: newNode = std::make_shared<IffNode>(*reinterpret_cast<IffNode*>(node)); break;
3551 case INTEGER_NODE: newNode = std::make_shared<IntegerNode>(*reinterpret_cast<IntegerNode*>(node)); break;
3552 case ITE_NODE: newNode = std::make_shared<IteNode>(*reinterpret_cast<IteNode*>(node)); break;
3553 case LAND_NODE: newNode = std::make_shared<LandNode>(*reinterpret_cast<LandNode*>(node)); break;
3554 case LET_NODE: newNode = std::make_shared<LetNode>(*reinterpret_cast<LetNode*>(node)); break;
3555 case LNOT_NODE: newNode = std::make_shared<LnotNode>(*reinterpret_cast<LnotNode*>(node)); break;
3556 case LOR_NODE: newNode = std::make_shared<LorNode>(*reinterpret_cast<LorNode*>(node)); break;
3557 case LXOR_NODE: newNode = std::make_shared<LxorNode>(*reinterpret_cast<LxorNode*>(node)); break;
3558 case REFERENCE_NODE: {
3559 if (unroll)
3560 return triton::ast::shallowCopy(reinterpret_cast<ReferenceNode*>(node)->getSymbolicExpression()->getAst().get(), unroll);
3561 else
3562 newNode = std::make_shared<ReferenceNode>(*reinterpret_cast<ReferenceNode*>(node));
3563 break;
3564 }
3565 case SELECT_NODE: newNode = std::make_shared<SelectNode>(*reinterpret_cast<SelectNode*>(node)); break;
3566 case STORE_NODE: newNode = std::make_shared<StoreNode>(*reinterpret_cast<StoreNode*>(node)); break;
3567 case STRING_NODE: newNode = std::make_shared<StringNode>(*reinterpret_cast<StringNode*>(node)); break;
3568 case SX_NODE: newNode = std::make_shared<SxNode>(*reinterpret_cast<SxNode*>(node)); break;
3569 case VARIABLE_NODE: newNode = node->shared_from_this(); /* Do not duplicate shared var (see #792) */ break;
3570 case ZX_NODE: newNode = std::make_shared<ZxNode>(*reinterpret_cast<ZxNode*>(node)); break;
3571 default:
3572 throw triton::exceptions::Ast("triton::ast::shallowCopy(): Invalid type node.");
3573 }
3574
3575 if (newNode == nullptr)
3576 throw triton::exceptions::Ast("triton::ast::shallowCopy(): Not enough memory.");
3577
3578 /* Remove parents as this is a new node which has no connections with original AST */
3579 if (node->getType() != VARIABLE_NODE) {
3580 /* VARIABLE_NODE are not duplicated (see #792), so don't remove their parents */
3581 auto parents = newNode->getParents();
3582 for (auto& p : parents) {
3583 newNode->removeParent(p.get());
3584 }
3585 }
3586
3587 return node->getContext()->collect(newNode);
3588 }
3589
3590
3592 std::unordered_map<AbstractNode*, SharedAbstractNode> exprs;
3593 auto nodes = childrenExtraction(node->shared_from_this(), unroll, true);
3594
3595 for (auto&& n : nodes) {
3596 /* Do a copy of all children */
3597 const auto& newNode = shallowCopy(n.get(), unroll);
3598 exprs[n.get()] = newNode;
3599
3600 /* For each child, set its parent */
3601 auto& children = newNode->getChildren();
3602 for (auto& child : children) {
3603 child = exprs[child.get()];
3604 child->setParent(newNode.get());
3605 }
3606 }
3607
3608 /* Return the root node */
3609 return exprs.at(node);
3610 }
3611
3612
3614 return triton::ast::newInstance(node.get(), true);
3615 }
3616
3617
3618 /* Returns a vector of unique AST-nodes sorted topologically
3619 *
3620 * Depending on @descent argument this function produces topologically sorted vector of nodes from DAG consisting of
3621 * either parents or children of given @node. This helps to prevent exponential complexity when complex AST are
3622 * parsed during z3 conversion, copying and parents reinitialization.
3623 *
3624 * @unroll - traverses through ReferenceNodes
3625 * @revert - reverses the result
3626 * @descent - if true we traverse through children of nodes, otherwise parents
3627 */
3628 static std::vector<SharedAbstractNode> nodesExtraction(const SharedAbstractNode& node, bool unroll, bool revert, bool descend) {
3629 std::vector<SharedAbstractNode> result;
3630 std::unordered_set<AbstractNode*> visited;
3631 std::stack<std::pair<SharedAbstractNode, bool>> worklist;
3632
3633 if (node == nullptr)
3634 throw triton::exceptions::Ast("triton::ast::nodesExtraction(): Node cannot be null.");
3635
3636 /*
3637 * We use a worklist strategy to avoid recursive calls
3638 * and so stack overflow when going through a big AST.
3639 */
3640 worklist.push({node, false});
3641
3642 while (!worklist.empty()) {
3644 bool postOrder;
3645 std::tie(ast, postOrder) = worklist.top();
3646 worklist.pop();
3647
3648 /* It means that we visited all children of this node and we can put it in the result */
3649 if (postOrder) {
3650 result.push_back(ast);
3651 continue;
3652 }
3653
3654 if (!visited.insert(ast.get()).second) {
3655 continue;
3656 }
3657
3658 worklist.push({ast, true});
3659
3660 const auto& relatives = descend ? ast->getChildren() : ast->getParents();
3661
3662 /* Proceed relatives */
3663 for (const auto& r : relatives) {
3664 if (visited.find(r.get()) == visited.end()) {
3665 worklist.push({r, false});
3666 }
3667 }
3668
3669 /* If unroll is true, we unroll all references */
3670 if (unroll && ast->getType() == REFERENCE_NODE) {
3671 const SharedAbstractNode& ref = reinterpret_cast<ReferenceNode*>(ast.get())->getSymbolicExpression()->getAst();
3672 if (visited.find(ref.get()) == visited.end()) {
3673 worklist.push({ref, false});
3674 }
3675 }
3676 }
3677
3678 /* The result is in reversed topological sort meaning that children go before parents */
3679 if (!revert) {
3680 std::reverse(result.begin(), result.end());
3681 }
3682
3683 return result;
3684 }
3685
3686
3687 std::vector<SharedAbstractNode> childrenExtraction(const SharedAbstractNode& node, bool unroll, bool revert) {
3688 return nodesExtraction(node, unroll, revert, true);
3689 }
3690
3691
3692 std::vector<SharedAbstractNode> parentsExtraction(const SharedAbstractNode& node, bool revert) {
3693 return nodesExtraction(node, false, revert, false);
3694 }
3695
3696
3697 std::deque<SharedAbstractNode> search(const SharedAbstractNode& node, triton::ast::ast_e match) {
3698 std::stack<AbstractNode*> worklist;
3699 std::deque<SharedAbstractNode> result;
3700 std::unordered_set<const AbstractNode*> visited;
3701
3702 worklist.push(node.get());
3703 while (!worklist.empty()) {
3704 AbstractNode* current = worklist.top();
3705 worklist.pop();
3706
3707 // This means that node is already visited and we will not need to visited it second time
3708 if (visited.find(current) != visited.end()) {
3709 continue;
3710 }
3711
3712 visited.insert(current);
3713 if (match == triton::ast::ANY_NODE || current->getType() == match)
3714 result.push_front(current->shared_from_this());
3715
3716 if (current->getType() == REFERENCE_NODE) {
3717 worklist.push(reinterpret_cast<triton::ast::ReferenceNode*>(current)->getSymbolicExpression()->getAst().get());
3718 }
3719 else {
3720 for (const SharedAbstractNode& child : current->getChildren()) {
3721 worklist.push(child.get());
3722 }
3723 }
3724 }
3725
3726 return result;
3727 }
3728
3729
3731 AbstractNode* ptr = node.get();
3732
3733 while (ptr->getType() == REFERENCE_NODE) {
3734 const ReferenceNode* ref = reinterpret_cast<const ReferenceNode*>(ptr);
3735 ptr = ref->getSymbolicExpression()->getAst().get();
3736 }
3737
3738 return ptr->shared_from_this();
3739 }
3740
3741
3743 switch(node->getType()) {
3744 case ARRAY_NODE: return reinterpret_cast<ArrayNode*>(node.get())->getIndexSize();
3745 case STORE_NODE: return reinterpret_cast<StoreNode*>(node.get())->getIndexSize();
3746 default:
3747 throw triton::exceptions::Ast("triton::ast::getIndexSize(): The given node is not an array.");
3748 }
3749 }
3750
3751 }; /* ast namespace */
3752}; /* 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:3211
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:3123
TRITON_EXPORT std::unordered_map< triton::uint64, triton::uint8 > & getMemory(void)
Gets the concrete memory array.
Definition: ast.cpp:3206
TRITON_EXPORT triton::uint8 select(triton::uint64 addr) const
Select a concrete value into the memory array.
Definition: ast.cpp:3188
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:3224
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:3266
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:3325
TRITON_EXPORT ZxNode(triton::uint32 sizeExt, const SharedAbstractNode &expr)
Create a zero extend of expr to sizeExt bits.
Definition: ast.cpp:3361
TRITON_EXPORT void init(bool withParents=false)
Init properties of the node. If withParents is true, init also properties of parents.
Definition: ast.cpp:3367
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:3742
SharedAbstractNode unroll(const triton::ast::SharedAbstractNode &node)
AST C++ API - Unrolls the SSA form of a given AST.
Definition: ast.cpp:3613
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:3730
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:3463
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:3692
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:3687
std::ostream & operator<<(std::ostream &stream, AbstractNode *node)
Displays the node in ast representation.
Definition: ast.cpp:3449
SharedAbstractNode newInstance(AbstractNode *node, bool unroll)
AST C++ API - Duplicates the AST.
Definition: ast.cpp:3591
triton::sint512 modularSignExtend(AbstractNode *node)
Custom modular sign extend for bitwise operation.
Definition: ast.cpp:3478
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:3697
triton::uint512 rotl(const triton::uint512 &value, triton::uint32 shift)
Custom rotate left function for hash routine.
Definition: ast.cpp:3471
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.