Add new indirect control flow analysis code. The code is still using ParseAPI level...
[dyninst.git] / parseAPI / src / BoundFactData.C
1 #include "BoundFactData.h"
2 #include "debug_parse.h"
3
4 using namespace Dyninst::ParseAPI;
5
6 bool BoundValue::operator == (const BoundValue &bv) const {
7     return (type == bv.type) &&
8            (value == bv.value) &&
9            (tableBase == bv.tableBase) &&
10            (targetBase == bv.targetBase) &&
11            (coe == bv.coe) &&
12            (posi == bv.posi) &&
13            (tableLookup == bv.tableLookup) &&
14            (tableOffset == bv.tableOffset);
15 }
16
17 BoundValue BoundFact::GetBound(const Absloc &al) {
18         if (fact.find(al) == fact.end())
19             return BoundValue();
20         else
21             return fact[al];
22
23 }
24
25 void BoundFact::Intersect(BoundFact &bf) {
26         for (auto fit = fact.begin(); fit != fact.end(); ++fit) {
27             if (bf.IsBounded(fit->first)) {
28                 BoundValue &val1 = fit->second;
29                 BoundValue val2 = bf.GetBound(fit->first);
30                 if (val1.value != val2.value) val1.type = LessThan;
31                 if (val1.value < val2.value) val1.value = val2.value;
32                 if (val1.coe != val2.coe) val1.coe = 1;
33                 if (val1.tableBase != val2.tableBase) val1.tableBase = 0;
34                 if (val1.targetBase != val2.targetBase) val1.targetBase = 0;
35                 val1.tableLookup = val1.tableLookup && val2.tableLookup;
36                 val1.tableOffset = val1.tableOffset && val2.tableOffset;
37             }
38         }
39
40     cmpBoundFactLive = cmpBoundFactLive && bf.cmpBoundFactLive;
41     if (cmpBoundFactLive) {
42         if (cmpAST->equals(bf.cmpAST)) {
43             if (bf.cmpBound > cmpBound) cmpBound = bf.cmpBound;
44         }
45         else
46             cmpBoundFactLive = false;
47     }
48 }
49
50 void BoundFact::Print() {
51     if (cmpBoundFactLive) {
52         parsing_printf("\tcmp bound fact live");
53         parsing_printf(", cmpAST = %s", cmpAST->format().c_str());
54         parsing_printf(", cmpBound = %lu", cmpBound);
55         parsing_printf(", used regs:");
56         for (auto rit = cmpUsedRegs.begin(); rit != cmpUsedRegs.end(); ++rit)
57             parsing_printf(" %s", rit->name().c_str());
58         parsing_printf("\n");
59     } else {
60         parsing_printf("\tcmp bound fact dead\n");
61     }
62     for (auto fit = fact.begin(); fit != fact.end(); ++fit) {
63         parsing_printf("\tVar: %s, ", fit->first.format().c_str());
64         parsing_printf("Bound type %d, ",fit->second.type );
65         parsing_printf("Bound value: %lu, ",fit->second.value);
66         parsing_printf("coe %d, ", fit->second.coe);
67         parsing_printf("tableBase %lu, ",fit->second.tableBase);
68         parsing_printf("targetBase %lu, ",fit->second.targetBase);
69         parsing_printf("tableLookup %d, ",fit->second.tableLookup);
70         parsing_printf("tableOffset %d, ",fit->second.tableOffset);
71         parsing_printf("add %d\n", fit->second.posi);
72     }
73 }
74
75 void BoundFact::GenFact(const Absloc &al, BoundValue bv) {
76     fact[al] = bv;
77     if (al.type() == Absloc::Register)
78         CheckCmpValidity(al.reg());
79 }
80
81 void BoundFact::KillFact(const Absloc &al) { 
82     fact.erase(al); 
83     if (al.type() == Absloc::Register)
84         CheckCmpValidity(al.reg());
85 }
86
87 void BoundFact::CheckCmpValidity(const MachRegister &reg) {
88     if (cmpBoundFactLive) {
89         if (cmpUsedRegs.find(reg) != cmpUsedRegs.end()) cmpBoundFactLive = false;
90     }
91 }
92
93 bool BoundFact::CMPBoundMatch(AST *ast) {
94     if (!cmpBoundFactLive) return false;
95     return ast->equals(cmpAST);
96 }
97
98 bool BoundFact::operator != (const BoundFact &bf) const {
99     if (cmpBoundFactLive != bf.cmpBoundFactLive) return true;
100     if (cmpBoundFactLive)
101         if (cmpBound != bf.cmpBound || !cmpAST->equals(bf.cmpAST)) return true;
102     
103     if (fact.size() != bf.fact.size()) return true;
104     return !equal(fact.begin(), fact.end(), bf.fact.begin());
105 }
106
107