Missing headers
[dyninst.git] / parseAPI / src / BoundFactData.C
1 #include "dyntypes.h"
2 #include "BoundFactData.h"
3 #include "debug_parse.h"
4
5 using namespace Dyninst::ParseAPI;
6
7 bool BoundValue::operator == (const BoundValue &bv) const {
8     return (type == bv.type) &&
9            (value == bv.value) &&
10            (tableBase == bv.tableBase) &&
11            (targetBase == bv.targetBase) &&
12            (coe == bv.coe) &&
13            (addIndexing == bv.addIndexing) &&
14            (addOffset == bv.addOffset) &&
15            (tableLookup == bv.tableLookup) &&
16            (tableOffset == bv.tableOffset);
17 }
18
19 BoundValue* BoundFact::GetBound(const Absloc &al) {
20         if (fact.find(al) == fact.end())
21             return NULL;
22         else
23             return fact.find(al)->second;
24
25 }
26
27 void BoundValue::Print() {
28     parsing_printf("Bound type %d, ",type );
29     parsing_printf("Bound value: %d, ",value);
30     parsing_printf("coe %d, ", coe);
31     parsing_printf("tableBase %lx, ",tableBase);
32     parsing_printf("targetBase %lx, ",targetBase);
33     parsing_printf("tableLookup %d, ",tableLookup);
34     parsing_printf("tableOffset %d, ",tableOffset);
35     parsing_printf("addIndexing %d, ", addIndexing);
36     parsing_printf("addOffset %d\n", addOffset);
37 }
38
39 void BoundFact::Intersect(BoundFact &bf) {
40         for (auto fit = fact.begin(); fit != fact.end(); ++fit) {
41             if (bf.IsBounded(fit->first)) {
42                 BoundValue *val1 = fit->second;
43                 BoundValue *val2 = bf.GetBound(fit->first);
44                 if (val1->value != val2->value) val1->type = LessThan;
45                 if (val1->value < val2->value) val1->value = val2->value;
46                 if (val1->coe != val2->coe) val1->coe = 1;
47                 if (val1->tableBase != val2->tableBase) val1->tableBase = 0;
48                 if (val1->targetBase != val2->targetBase) val1->targetBase = 0;
49                 val1->tableLookup = val1->tableLookup && val2->tableLookup;
50                 val1->tableOffset = val1->tableOffset && val2->tableOffset;
51                 val1->addIndexing = val1->addIndexing | val2->addIndexing;
52                 val1->addOffset = val1->addOffset | val2->addOffset;
53             }
54         }
55
56     cmpBoundFactLive = cmpBoundFactLive && bf.cmpBoundFactLive;
57     if (cmpBoundFactLive) {
58         if (cmpAST->equals(bf.cmpAST)) {
59             if (bf.cmpBound > cmpBound) cmpBound = bf.cmpBound;
60         }
61         else
62             cmpBoundFactLive = false;
63     }
64 }
65
66 void BoundFact::Print() {
67     if (cmpBoundFactLive) {
68         parsing_printf("\tcmp bound fact live");
69         parsing_printf(", cmpAST = %s", cmpAST->format().c_str());
70         parsing_printf(", cmpBound = %lu", cmpBound);
71         parsing_printf(", used regs:");
72         for (auto rit = cmpUsedRegs.begin(); rit != cmpUsedRegs.end(); ++rit)
73             parsing_printf(" %s", rit->name().c_str());
74         parsing_printf("\n");
75     } else {
76         parsing_printf("\tcmp bound fact dead\n");
77     }
78     for (auto fit = fact.begin(); fit != fact.end(); ++fit) {
79         parsing_printf("\tVar: %s, ", fit->first.format().c_str());
80         fit->second->Print();
81     }
82 }
83
84 void BoundFact::GenFact(const Absloc &al, BoundValue* bv) {
85     KillFact(al);
86     fact.insert(make_pair(al,bv));
87 }
88
89 void BoundFact::KillFact(const Absloc &al) {
90     if (fact.find(al) != fact.end() && fact[al] != NULL)
91         delete fact[al];
92     fact.erase(al); 
93     if (al.type() == Absloc::Register)
94         CheckCmpValidity(al.reg());
95 }
96
97 void BoundFact::CheckCmpValidity(const MachRegister &reg) {
98     if (cmpBoundFactLive) {
99         if (cmpUsedRegs.find(reg) != cmpUsedRegs.end()) cmpBoundFactLive = false;
100     }
101 }
102
103 bool BoundFact::CMPBoundMatch(AST *ast) {
104     if (!cmpBoundFactLive) return false;
105     return ast->equals(cmpAST);
106 }
107
108 bool BoundFact::operator != (const BoundFact &bf) const {
109     if (cmpBoundFactLive != bf.cmpBoundFactLive) return true;
110     if (cmpBoundFactLive)
111         if (cmpBound != bf.cmpBound || !cmpAST->equals(bf.cmpAST)) return true;
112     
113     if (fact.size() != bf.fact.size()) return true;
114     return !equal(fact.begin(), fact.end(), bf.fact.begin());
115 }
116
117 BoundFact::BoundFact():
118     cmpAST(AST::Ptr()) {
119     cmpBound = 0;
120     cmpBoundFactLive = false;
121     cmpUsedRegs.clear();
122     fact.clear();
123 }
124
125 BoundFact::~BoundFact() {
126     for (auto fit = fact.begin(); fit != fact.end(); ++fit)
127         if (fit->second != NULL)
128             delete fit->second;
129     fact.clear();   
130 }
131
132 BoundFact& BoundFact::operator = (const BoundFact &bf) {
133     if (bf.cmpAST == AST::Ptr())
134         cmpAST = AST::Ptr();
135     else
136         cmpAST = bf.cmpAST;
137     cmpBound = bf.cmpBound;
138     cmpBoundFactLive = bf.cmpBoundFactLive;
139     cmpUsedRegs = bf.cmpUsedRegs;
140     fact.clear();
141     for (auto fit = bf.fact.begin(); fit != bf.fact.end(); ++fit)     
142         fact.insert(make_pair(fit->first, new BoundValue(*(fit->second))));
143     return *this;
144 }
145
146 BoundFact::BoundFact(const BoundFact &bf) {
147     *this = bf;
148 }