-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathslghpattern.hh
174 lines (164 loc) · 7.94 KB
/
slghpattern.hh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __SLGHPATTERN_HH__
#define __SLGHPATTERN_HH__
#include "context.hh"
namespace ghidra {
// A mask/value pair viewed as two bitstreams
class PatternBlock {
int4 offset; // Offset to non-zero byte of mask
int4 nonzerosize; // Last byte(+1) containing nonzero mask
vector<uintm> maskvec; // Mask
vector<uintm> valvec; // Value
void normalize(void);
public:
PatternBlock(int4 off,uintm msk,uintm val);
PatternBlock(bool tf);
PatternBlock(const PatternBlock *a,const PatternBlock *b);
PatternBlock(vector<PatternBlock *> &list);
PatternBlock *commonSubPattern(const PatternBlock *b) const;
PatternBlock *intersect(const PatternBlock *b) const;
bool specializes(const PatternBlock *op2) const;
bool identical(const PatternBlock *op2) const;
PatternBlock *clone(void) const;
void shift(int4 sa) { offset += sa; normalize(); }
int4 getLength(void) const { return offset+nonzerosize; }
uintm getMask(int4 startbit,int4 size) const;
uintm getValue(int4 startbit,int4 size) const;
bool alwaysTrue(void) const { return (nonzerosize==0); }
bool alwaysFalse(void) const { return (nonzerosize==-1); }
bool isInstructionMatch(ParserWalker &walker) const;
bool isContextMatch(ParserWalker &walker) const;
void saveXml(ostream &s) const;
void restoreXml(const Element *el);
};
class DisjointPattern;
class Pattern {
public:
virtual ~Pattern(void) {}
virtual Pattern *simplifyClone(void) const=0;
virtual void shiftInstruction(int4 sa)=0;
virtual Pattern *doOr(const Pattern *b,int4 sa) const=0;
virtual Pattern *doAnd(const Pattern *b,int4 sa) const=0;
virtual Pattern *commonSubPattern(const Pattern *b,int4 sa) const=0;
virtual bool isMatch(ParserWalker &walker) const=0; // Does this pattern match context
virtual int4 numDisjoint(void) const=0;
virtual DisjointPattern *getDisjoint(int4 i) const=0;
virtual bool alwaysTrue(void) const=0;
virtual bool alwaysFalse(void) const=0;
virtual bool alwaysInstructionTrue(void) const=0;
virtual void saveXml(ostream &s) const=0;
virtual void restoreXml(const Element *el)=0;
};
class DisjointPattern : public Pattern { // A pattern with no ORs in it
virtual PatternBlock *getBlock(bool context) const=0;
public:
virtual int4 numDisjoint(void) const { return 0; }
virtual DisjointPattern *getDisjoint(int4 i) const { return (DisjointPattern *)0; }
uintm getMask(int4 startbit,int4 size,bool context) const;
uintm getValue(int4 startbit,int4 size,bool context) const;
int4 getLength(bool context) const;
bool specializes(const DisjointPattern *op2) const;
bool identical(const DisjointPattern *op2) const;
bool resolvesIntersect(const DisjointPattern *op1,const DisjointPattern *op2) const;
static DisjointPattern *restoreDisjoint(const Element *el);
};
class InstructionPattern : public DisjointPattern { // Matches the instruction bitstream
PatternBlock *maskvalue;
virtual PatternBlock *getBlock(bool context) const { return context ? (PatternBlock *)0 : maskvalue; }
public:
InstructionPattern(void) { maskvalue = (PatternBlock *)0; } // For use with restoreXml
InstructionPattern(PatternBlock *mv) { maskvalue = mv; }
InstructionPattern(bool tf) { maskvalue = new PatternBlock(tf); }
PatternBlock *getBlock(void) { return maskvalue; }
virtual ~InstructionPattern(void) { if (maskvalue != (PatternBlock *)0) delete maskvalue; }
virtual Pattern *simplifyClone(void) const { return new InstructionPattern(maskvalue->clone()); }
virtual void shiftInstruction(int4 sa) { maskvalue->shift(sa); }
virtual Pattern *doOr(const Pattern *b,int4 sa) const;
virtual Pattern *doAnd(const Pattern *b,int4 sa) const;
virtual Pattern *commonSubPattern(const Pattern *b,int4 sa) const;
virtual bool isMatch(ParserWalker &walker) const { return maskvalue->isInstructionMatch(walker); }
virtual bool alwaysTrue(void) const { return maskvalue->alwaysTrue(); }
virtual bool alwaysFalse(void) const { return maskvalue->alwaysFalse(); }
virtual bool alwaysInstructionTrue(void) const { return maskvalue->alwaysTrue(); }
virtual void saveXml(ostream &s) const;
virtual void restoreXml(const Element *el);
};
class ContextPattern : public DisjointPattern { // Matches the context bitstream
PatternBlock *maskvalue;
virtual PatternBlock *getBlock(bool context) const { return context ? maskvalue : (PatternBlock *)0; }
public:
ContextPattern(void) { maskvalue = (PatternBlock *)0; } // For use with restoreXml
ContextPattern(PatternBlock *mv) { maskvalue = mv; }
PatternBlock *getBlock(void) { return maskvalue; }
virtual ~ContextPattern(void) { if (maskvalue != (PatternBlock *)0) delete maskvalue; }
virtual Pattern *simplifyClone(void) const { return new ContextPattern(maskvalue->clone()); }
virtual void shiftInstruction(int4 sa) { } // do nothing
virtual Pattern *doOr(const Pattern *b,int4 sa) const;
virtual Pattern *doAnd(const Pattern *b,int4 sa) const;
virtual Pattern *commonSubPattern(const Pattern *b,int4 sa) const;
virtual bool isMatch(ParserWalker &walker) const { return maskvalue->isContextMatch(walker); }
virtual bool alwaysTrue(void) const { return maskvalue->alwaysTrue(); }
virtual bool alwaysFalse(void) const { return maskvalue->alwaysFalse(); }
virtual bool alwaysInstructionTrue(void) const { return true; }
virtual void saveXml(ostream &s) const;
virtual void restoreXml(const Element *el);
};
// A pattern with a context piece and an instruction piece
class CombinePattern : public DisjointPattern {
ContextPattern *context; // Context piece
InstructionPattern *instr; // Instruction piece
virtual PatternBlock *getBlock(bool cont) const { return cont ? context->getBlock() : instr->getBlock(); }
public:
CombinePattern(void) { context = (ContextPattern *)0; instr = (InstructionPattern *)0; }
CombinePattern(ContextPattern *con,InstructionPattern *in) {
context = con; instr = in; }
virtual ~CombinePattern(void);
virtual Pattern *simplifyClone(void) const;
virtual void shiftInstruction(int4 sa) { instr->shiftInstruction(sa); }
virtual bool isMatch(ParserWalker &walker) const;
virtual bool alwaysTrue(void) const;
virtual bool alwaysFalse(void) const;
virtual bool alwaysInstructionTrue(void) const { return instr->alwaysInstructionTrue(); }
virtual Pattern *doOr(const Pattern *b,int4 sa) const;
virtual Pattern *doAnd(const Pattern *b,int4 sa) const;
virtual Pattern *commonSubPattern(const Pattern *b,int4 sa) const;
virtual void saveXml(ostream &s) const;
virtual void restoreXml(const Element *el);
};
class OrPattern : public Pattern {
vector<DisjointPattern *> orlist;
public:
OrPattern(void) {} // For use with restoreXml
OrPattern(DisjointPattern *a,DisjointPattern *b);
OrPattern(const vector<DisjointPattern *> &list);
virtual ~OrPattern(void);
virtual Pattern *simplifyClone(void) const;
virtual void shiftInstruction(int4 sa);
virtual bool isMatch(ParserWalker &walker) const;
virtual int4 numDisjoint(void) const { return orlist.size(); }
virtual DisjointPattern *getDisjoint(int4 i) const { return orlist[i]; }
virtual bool alwaysTrue(void) const;
virtual bool alwaysFalse(void) const;
virtual bool alwaysInstructionTrue(void) const;
virtual Pattern *doOr(const Pattern *b,int4 sa) const;
virtual Pattern *doAnd(const Pattern *b,int4 sa) const;
virtual Pattern *commonSubPattern(const Pattern *b,int4 sa) const;
virtual void saveXml(ostream &s) const;
virtual void restoreXml(const Element *el);
};
} // End namespace ghidra
#endif