When we encounter instructions without instruction semantics, we should stop jump...
[dyninst.git] / parseAPI / src / JumpTablePred.h
1 #ifndef JUMP_TABLE_PRED_H
2 #define JUMP_TABLE_PRED_H
3
4 #include "CFG.h"
5 #include "slicing.h"
6 #include "Edge.h"
7 #include "ThunkData.h"
8 #include "Graph.h"
9 #include "BoundFactCalculator.h"
10 using namespace Dyninst;
11
12 class JumpTablePred : public Slicer::Predicates {
13
14     bool firstMemoryRead;
15     ParseAPI::Function *func;
16     ParseAPI::Block *block;
17     ReachFact &rf;
18     ThunkData &thunks;
19     std::vector<std::pair< Address, Dyninst::ParseAPI::EdgeTypeEnum > >& outEdges;
20     std::vector<AST::Ptr> readAST;
21
22         bool MatchReadAST(Assignment::Ptr a);
23
24         std::pair<AST::Ptr, bool> ExpandAssignment(Assignment::Ptr);
25
26 public:
27     bool jumpTableFormat;
28     bool unknownInstruction;
29     std::set<Assignment::Ptr> currentAssigns;
30
31 std::unordered_map<Assignment::Ptr, AST::Ptr, Assignment::AssignmentPtrHasher> expandCache;
32
33     virtual bool addNodeCallback(AssignmentPtr ap, std::set<ParseAPI::Edge*> &visitedEdges);
34 GraphPtr BuildAnalysisGraph(std::set<ParseAPI::Edge*> &visitedEdges);
35     bool IsJumpTable(GraphPtr slice, BoundFactsCalculator &bfc, BoundValue &target);
36     bool FillInOutEdges(BoundValue &target, std::vector<std::pair< Address, Dyninst::ParseAPI::EdgeTypeEnum > >& outEdges);
37
38
39     JumpTablePred(ParseAPI::Function *f,
40                   ParseAPI::Block *b,
41                   ReachFact &r,
42                   ThunkData &t,
43                   std::vector<std::pair< Address, Dyninst::ParseAPI::EdgeTypeEnum > >& out):
44             firstMemoryRead(true),  func(f), 
45             block(b), rf(r), thunks(t), outEdges(out),jumpTableFormat(true), unknownInstruction(false) {}
46 };
47
48
49 class TypedSliceEdge: public Dyninst::Edge {
50     ParseAPI::EdgeTypeEnum type_; 
51     
52     TypedSliceEdge(const SliceNode::Ptr source,
53               const SliceNode::Ptr target,
54               ParseAPI::EdgeTypeEnum t) 
55               : Dyninst::Edge(source, target), type_(t) {};
56   public:             
57    typedef boost::shared_ptr<TypedSliceEdge> Ptr; 
58    static TypedSliceEdge::Ptr create(SliceNode::Ptr source,
59                                      SliceNode::Ptr target,
60                                      ParseAPI::EdgeTypeEnum t) {
61         return Ptr(new TypedSliceEdge(source, target, t));       
62    }                                                
63
64   public:
65     ParseAPI::EdgeTypeEnum type() { return type_;}
66
67 };
68
69 #endif