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