-
Notifications
You must be signed in to change notification settings - Fork 50
/
grammar.hh
294 lines (271 loc) · 9.58 KB
/
grammar.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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
/* ###
* 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 __GRAMMAR_HH__
#define __GRAMMAR_HH__
#include "funcdata.hh"
namespace ghidra {
class GrammarToken {
friend class GrammarLexer;
public:
enum {
openparen = 0x28,
closeparen = 0x29,
star = 0x2a,
comma = 0x2c,
semicolon = 0x3b,
openbracket = 0x5b,
closebracket = 0x5d,
openbrace = 0x7b,
closebrace = 0x7d,
badtoken = 0x100,
endoffile = 0x101,
dotdotdot = 0x102,
integer = 0x103,
charconstant = 0x104,
identifier = 0x105,
stringval = 0x106,
};
private:
uint4 type;
union tokenvalue {
uintb integer;
string *stringval;
};
tokenvalue value;
int4 lineno; // Line number containing this token
int4 colno; // Column where this token starts
int4 filenum; // Which file were we in
void set(uint4 tp);
void set(uint4 tp,char *ptr,int4 len);
void setPosition(int4 file,int4 line,int4 col) { filenum=file; lineno=line; colno=col; }
public:
GrammarToken(void);
uint4 getType(void) const { return type; }
uintb getInteger(void) const { return value.integer; }
string *getString(void) const { return value.stringval; }
int4 getLineNo(void) const { return lineno; }
int4 getColNo(void) const { return colno; }
int4 getFileNum(void) const { return filenum; }
};
class GrammarLexer {
map<int4,string> filenamemap; // All files ever seen
map<int4,istream *> streammap;
vector<int4> filestack; // Stack of current files
int4 buffersize; // maximum characters in buffer
char *buffer; // Current line being processed
int4 bufstart; // Next character to process
int4 bufend; // Next open position in buffer
int4 curlineno;
istream *in; // Current stream
bool endoffile;
uint4 state; // State of parser
string error;
enum {
start,
slash,
dot1,
dot2,
dot3,
punctuation,
endofline_comment,
c_comment,
doublequote,
doublequoteend,
singlequote,
singlequoteend,
singlebackslash,
number,
identifier
};
void bumpLine(void);
uint4 moveState(char lookahead);
void establishToken(GrammarToken &token,uint4 val);
void setError(const string &err) { error = err; }
public:
GrammarLexer(int4 maxbuffer);
~GrammarLexer(void);
void clear(void);
istream *getCurStream(void) { return in; }
void pushFile(const string &filename,istream *i);
void popFile(void);
void getNextToken(GrammarToken &token);
void writeLocation(ostream &s,int4 line,int4 filenum);
void writeTokenLocation(ostream &s,int4 line,int4 colno);
const string &getError(void) const { return error; }
};
class TypeDeclarator; // Forward declaration
class TypeModifier {
public:
enum {
pointer_mod,
array_mod,
function_mod,
struct_mod,
enum_mod
};
virtual ~TypeModifier(void) {}
virtual uint4 getType(void) const=0;
virtual bool isValid(void) const=0;
virtual Datatype *modType(Datatype *base,const TypeDeclarator *decl,Architecture *glb) const=0;
};
class PointerModifier : public TypeModifier {
uint4 flags;
public:
PointerModifier(uint4 fl) { flags = fl; }
virtual uint4 getType(void) const { return pointer_mod; }
virtual bool isValid(void) const { return true; }
virtual Datatype *modType(Datatype *base,const TypeDeclarator *decl,Architecture *glb) const;
};
class ArrayModifier : public TypeModifier {
uint4 flags;
int4 arraysize;
public:
ArrayModifier(uint4 fl,int4 as) { flags=fl; arraysize = as; }
virtual uint4 getType(void) const { return array_mod; }
virtual bool isValid(void) const { return (arraysize>0); }
virtual Datatype *modType(Datatype *base,const TypeDeclarator *decl,Architecture *glb) const;
};
class FunctionModifier : public TypeModifier {
vector<TypeDeclarator *> paramlist;
bool dotdotdot;
public:
FunctionModifier(const vector<TypeDeclarator *> *p,bool dtdtdt);
void getInTypes(vector<Datatype *> &intypes,Architecture *glb) const;
void getInNames(vector<string> &innames) const;
bool isDotdotdot(void) const { return dotdotdot; }
virtual uint4 getType(void) const { return function_mod; }
virtual bool isValid(void) const;
virtual Datatype *modType(Datatype *base,const TypeDeclarator *decl,Architecture *glb) const;
};
class TypeDeclarator {
friend class CParse;
vector<TypeModifier *> mods;
Datatype *basetype;
string ident; // variable identifier associated with type
string model; // name of model associated with function pointer
uint4 flags; // Specifiers qualifiers
public:
TypeDeclarator(void) { basetype=(Datatype *)0; flags=0; }
TypeDeclarator(const string &nm) { ident=nm; basetype=(Datatype *)0; flags=0; }
~TypeDeclarator(void);
Datatype *getBaseType(void) const { return basetype; }
int4 numModifiers(void) const { return mods.size(); }
const string &getIdentifier(void) const { return ident; }
ProtoModel *getModel(Architecture *glb) const;
bool getPrototype(PrototypePieces &pieces,Architecture *glb) const;
bool hasProperty(uint4 mask) { return ((flags&mask)!=0); }
Datatype *buildType(Architecture *glb) const;
bool isValid(void) const;
};
struct TypeSpecifiers {
Datatype *type_specifier;
string function_specifier;
uint4 flags;
TypeSpecifiers(void) { type_specifier = (Datatype *)0; flags = 0; }
};
struct Enumerator {
string enumconstant; // Identifier associated with constant
bool constantassigned; // True if user specified explicit constant
uintb value; // The actual constant
Enumerator(const string &nm) { constantassigned = false; enumconstant = nm; }
Enumerator(const string &nm,uintb val) { constantassigned = true; enumconstant=nm; value=val; }
};
class CParse {
public:
enum {
f_typedef = 1,
f_extern = 2,
f_static = 4,
f_auto = 8,
f_register = 16,
f_const = 32,
f_restrict = 64,
f_volatile = 128,
f_inline = 256,
f_struct = 512,
f_union = 1024,
f_enum = 2048
};
enum {
doc_declaration,
doc_parameter_declaration
};
private:
Architecture *glb;
map<string,uint4> keywords;
GrammarLexer lexer;
int4 lineno,colno,filenum; // Location of last token
list<TypeDeclarator *> typedec_alloc;
list<TypeSpecifiers *> typespec_alloc;
list<vector<uint4> *> vecuint4_alloc;
list<vector<TypeDeclarator *> *> vecdec_alloc;
list<string *> string_alloc;
list<uintb *> num_alloc;
list<Enumerator *> enum_alloc;
list<vector<Enumerator *> *> vecenum_alloc;
vector<TypeDeclarator *> *lastdecls;
int4 firsttoken; // Message to parser indicating desired object
string lasterror;
void setError(const string &msg);
int4 lookupIdentifier(const string &nm);
bool runParse(uint4 doctype);
public:
CParse(Architecture *g,int4 maxbuf);
~CParse(void);
void clear(void);
vector<TypeDeclarator *> *mergeSpecDecVec(TypeSpecifiers *spec);
vector<TypeDeclarator *> *mergeSpecDecVec(TypeSpecifiers *spec,vector<TypeDeclarator *> *declist);
TypeDeclarator *mergeSpecDec(TypeSpecifiers *spec);
TypeDeclarator *mergeSpecDec(TypeSpecifiers *spec,TypeDeclarator *dec);
TypeSpecifiers *addSpecifier(TypeSpecifiers *spec,string *str);
TypeSpecifiers *addTypeSpecifier(TypeSpecifiers *spec,Datatype *tp);
TypeSpecifiers *addFuncSpecifier(TypeSpecifiers *spec,string *str);
TypeDeclarator *mergePointer(vector<uint4> *ptr,TypeDeclarator *dec);
TypeDeclarator *newDeclarator(string *str);
TypeDeclarator *newDeclarator(void);
TypeSpecifiers *newSpecifier(void);
vector<TypeDeclarator *> *newVecDeclarator(void);
vector<uint4> *newPointer(void);
TypeDeclarator *newArray(TypeDeclarator *dec,uint4 flags,uintb *num);
TypeDeclarator *newFunc(TypeDeclarator *dec,vector<TypeDeclarator *> *declist);
Datatype *newStruct(const string &ident,vector<TypeDeclarator *> *declist);
Datatype *oldStruct(const string &ident);
Datatype *newUnion(const string &ident,vector<TypeDeclarator *> *declist);
Datatype *oldUnion(const string &ident);
Enumerator *newEnumerator(const string &ident);
Enumerator *newEnumerator(const string &ident,uintb val);
vector<Enumerator *> *newVecEnumerator(void);
Datatype *newEnum(const string &ident,vector<Enumerator *> *vecenum);
Datatype *oldEnum(const string &ident);
uint4 convertFlag(string *str);
void clearAllocation(void);
int4 lex(void);
bool parseFile(const string &filename,uint4 doctype);
bool parseStream(istream &s,uint4 doctype);
const string &getError(void) const { return lasterror; }
void setResultDeclarations(vector<TypeDeclarator *> *val) { lastdecls = val; }
vector<TypeDeclarator *> *getResultDeclarations(void) { return lastdecls; }
};
extern Datatype *parse_type(istream &s,string &name,Architecture *glb);
extern void parse_protopieces(PrototypePieces &pieces,istream &s,Architecture *glb);
extern void parse_C(Architecture *glb,istream &s);
// Routines to parse interface commands
extern void parse_toseparator(istream &s,string &name);
extern Address parse_machaddr(istream &s,int4 &defaultsize,const TypeFactory &typegrp,bool ignorecolon=false);
extern Address parse_varnode(istream &s,int4 &size,Address &pc,uintm &uq,const TypeFactory &typegrp);
extern Address parse_op(istream &s,uintm &uq,const TypeFactory &typegrp);
} // End namespace ghidra
#endif