Ghidra Decompiler Analysis Engine
grammar.hh
1 /* ###
2  * IP: GHIDRA
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #ifndef __CPUI_GRAMMAR__
17 #define __CPUI_GRAMMAR__
18 
19 #include "funcdata.hh"
20 
21 class GrammarToken {
22  friend class GrammarLexer;
23 public:
24  enum {
25  openparen = 0x28,
26  closeparen = 0x29,
27  star = 0x2a,
28  comma = 0x2c,
29  semicolon = 0x3b,
30  openbracket = 0x5b,
31  closebracket = 0x5d,
32  openbrace = 0x7b,
33  closebrace = 0x7d,
34 
35  badtoken = 0x100,
36  endoffile = 0x101,
37  dotdotdot = 0x102,
38 
39  integer = 0x103,
40  charconstant = 0x104,
41  identifier = 0x105,
42  stringval = 0x106,
43  };
44 private:
45  uint4 type;
46  union tokenvalue {
47  uintb integer;
48  string *stringval;
49  };
50  tokenvalue value;
51  int4 lineno; // Line number containing this token
52  int4 colno; // Column where this token starts
53  int4 filenum; // Which file were we in
54  void set(uint4 tp);
55  void set(uint4 tp,char *ptr,int4 len);
56  void setPosition(int4 file,int4 line,int4 col) { filenum=file; lineno=line; colno=col; }
57 public:
58  GrammarToken(void);
59  uint4 getType(void) const { return type; }
60  uintb getInteger(void) const { return value.integer; }
61  string *getString(void) const { return value.stringval; }
62  int4 getLineNo(void) const { return lineno; }
63  int4 getColNo(void) const { return colno; }
64  int4 getFileNum(void) const { return filenum; }
65 };
66 
67 class GrammarLexer {
68  map<int4,string> filenamemap; // All files ever seen
69  map<int4,istream *> streammap;
70  vector<int4> filestack; // Stack of current files
71  int4 buffersize; // maximum characters in buffer
72  char *buffer; // Current line being processed
73  int4 bufstart; // Next character to process
74  int4 bufend; // Next open position in buffer
75  int4 curlineno;
76  istream *in; // Current stream
77  bool endoffile;
78  uint4 state; // State of parser
79  string error;
80  enum {
81  start,
82  slash,
83  dot1,
84  dot2,
85  dot3,
86  punctuation,
87  endofline_comment,
88  c_comment,
89  doublequote,
90  doublequoteend,
91  singlequote,
92  singlequoteend,
93  singlebackslash,
94  number,
95  identifier
96  };
97  void bumpLine(void);
98  uint4 moveState(char lookahead);
99  void establishToken(GrammarToken &token,uint4 val);
100  void setError(const string &err) { error = err; }
101 public:
102  GrammarLexer(int4 maxbuffer);
103  ~GrammarLexer(void);
104  void clear(void);
105  istream *getCurStream(void) { return in; }
106  void pushFile(const string &filename,istream *i);
107  void popFile(void);
108  void getNextToken(GrammarToken &token);
109  void writeLocation(ostream &s,int4 line,int4 filenum);
110  void writeTokenLocation(ostream &s,int4 line,int4 colno);
111  const string &getError(void) const { return error; }
112 };
113 
114 class TypeDeclarator; // Forward declaration
115 
117 public:
118  enum {
119  pointer_mod,
120  array_mod,
121  function_mod,
122  struct_mod,
123  enum_mod
124  };
125  virtual ~TypeModifier(void) {}
126  virtual uint4 getType(void) const=0;
127  virtual bool isValid(void) const=0;
128  virtual Datatype *modType(Datatype *base,const TypeDeclarator *decl,Architecture *glb) const=0;
129 };
130 
132  uint4 flags;
133 public:
134  PointerModifier(uint4 fl) { flags = fl; }
135  virtual uint4 getType(void) const { return pointer_mod; }
136  virtual bool isValid(void) const { return true; }
137  virtual Datatype *modType(Datatype *base,const TypeDeclarator *decl,Architecture *glb) const;
138 };
139 
140 class ArrayModifier : public TypeModifier {
141  uint4 flags;
142  int4 arraysize;
143 public:
144  ArrayModifier(uint4 fl,int4 as) { flags=fl; arraysize = as; }
145  virtual uint4 getType(void) const { return array_mod; }
146  virtual bool isValid(void) const { return (arraysize>0); }
147  virtual Datatype *modType(Datatype *base,const TypeDeclarator *decl,Architecture *glb) const;
148 };
149 
151  vector<TypeDeclarator *> paramlist;
152  bool dotdotdot;
153 public:
154  FunctionModifier(const vector<TypeDeclarator *> *p,bool dtdtdt);
155  void getInTypes(vector<Datatype *> &intypes,Architecture *glb) const;
156  void getInNames(vector<string> &innames) const;
157  bool isDotdotdot(void) const { return dotdotdot; }
158  virtual uint4 getType(void) const { return function_mod; }
159  virtual bool isValid(void) const;
160  virtual Datatype *modType(Datatype *base,const TypeDeclarator *decl,Architecture *glb) const;
161 };
162 
164  friend class CParse;
165  vector<TypeModifier *> mods;
166  Datatype *basetype;
167  string ident; // variable identifier associated with type
168  string model; // name of model associated with function pointer
169  uint4 flags; // Specifiers qualifiers
170 public:
171  TypeDeclarator(void) { basetype=(Datatype *)0; flags=0; }
172  TypeDeclarator(const string &nm) { ident=nm; basetype=(Datatype *)0; flags=0; }
173  ~TypeDeclarator(void);
174  Datatype *getBaseType(void) const { return basetype; }
175  int4 numModifiers(void) const { return mods.size(); }
176  const string &getIdentifier(void) const { return ident; }
177  ProtoModel *getModel(Architecture *glb) const;
178  bool getPrototype(PrototypePieces &pieces,Architecture *glb) const;
179  bool hasProperty(uint4 mask) { return ((flags&mask)!=0); }
180  Datatype *buildType(Architecture *glb) const;
181  bool isValid(void) const;
182 };
183 
185  Datatype *type_specifier;
186  string function_specifier;
187  uint4 flags;
188  TypeSpecifiers(void) { type_specifier = (Datatype *)0; flags = 0; }
189 };
190 
191 struct Enumerator {
192  string enumconstant; // Identifier associated with constant
193  bool constantassigned; // True if user specified explicit constant
194  uintb value; // The actual constant
195  Enumerator(const string &nm) { constantassigned = false; enumconstant = nm; }
196  Enumerator(const string &nm,uintb val) { constantassigned = true; enumconstant=nm; value=val; }
197 };
198 
199 class CParse {
200 public:
201  enum {
202  f_typedef = 1,
203  f_extern = 2,
204  f_static = 4,
205  f_auto = 8,
206  f_register = 16,
207  f_const = 32,
208  f_restrict = 64,
209  f_volatile = 128,
210  f_inline = 256,
211  f_struct = 512,
212  f_union = 1024,
213  f_enum = 2048
214  };
215  enum {
216  doc_declaration,
217  doc_parameter_declaration
218  };
219 private:
220  Architecture *glb;
221  map<string,uint4> keywords;
222  GrammarLexer lexer;
223  int4 lineno,colno,filenum; // Location of last token
224  list<TypeDeclarator *> typedec_alloc;
225  list<TypeSpecifiers *> typespec_alloc;
226  list<vector<uint4> *> vecuint4_alloc;
227  list<vector<TypeDeclarator *> *> vecdec_alloc;
228  list<string *> string_alloc;
229  list<uintb *> num_alloc;
230  list<Enumerator *> enum_alloc;
231  list<vector<Enumerator *> *> vecenum_alloc;
232 
233  vector<TypeDeclarator *> *lastdecls;
234  int4 firsttoken; // Message to parser indicating desired object
235  string lasterror;
236  void setError(const string &msg);
237  int4 lookupIdentifier(const string &nm);
238  bool runParse(uint4 doctype);
239 public:
240  CParse(Architecture *g,int4 maxbuf);
241  ~CParse(void);
242  void clear(void);
243  vector<TypeDeclarator *> *mergeSpecDecVec(TypeSpecifiers *spec);
244  vector<TypeDeclarator *> *mergeSpecDecVec(TypeSpecifiers *spec,vector<TypeDeclarator *> *declist);
245  TypeDeclarator *mergeSpecDec(TypeSpecifiers *spec);
246  TypeDeclarator *mergeSpecDec(TypeSpecifiers *spec,TypeDeclarator *dec);
247  TypeSpecifiers *addSpecifier(TypeSpecifiers *spec,string *str);
248  TypeSpecifiers *addTypeSpecifier(TypeSpecifiers *spec,Datatype *tp);
249  TypeSpecifiers *addFuncSpecifier(TypeSpecifiers *spec,string *str);
250  TypeDeclarator *mergePointer(vector<uint4> *ptr,TypeDeclarator *dec);
251  TypeDeclarator *newDeclarator(string *str);
252  TypeDeclarator *newDeclarator(void);
253  TypeSpecifiers *newSpecifier(void);
254  vector<TypeDeclarator *> *newVecDeclarator(void);
255  vector<uint4> *newPointer(void);
256  TypeDeclarator *newArray(TypeDeclarator *dec,uint4 flags,uintb *num);
257  TypeDeclarator *newFunc(TypeDeclarator *dec,vector<TypeDeclarator *> *declist);
258  Datatype *newStruct(const string &ident,vector<TypeDeclarator *> *declist);
259  Datatype *oldStruct(const string &ident);
260  Datatype *newUnion(const string &ident,vector<TypeDeclarator *> *declist);
261  Datatype *oldUnion(const string &ident);
262  Enumerator *newEnumerator(const string &ident);
263  Enumerator *newEnumerator(const string &ident,uintb val);
264  vector<Enumerator *> *newVecEnumerator(void);
265  Datatype *newEnum(const string &ident,vector<Enumerator *> *vecenum);
266  Datatype *oldEnum(const string &ident);
267  uint4 convertFlag(string *str);
268 
269  void clearAllocation(void);
270  int4 lex(void);
271 
272  bool parseFile(const string &filename,uint4 doctype);
273  bool parseStream(istream &s,uint4 doctype);
274 
275  const string &getError(void) const { return lasterror; }
276  void setResultDeclarations(vector<TypeDeclarator *> *val) { lastdecls = val; }
277  vector<TypeDeclarator *> *getResultDeclarations(void) { return lastdecls; }
278 };
279 
280 extern Datatype *parse_type(istream &s,string &name,Architecture *glb);
281 extern void parse_protopieces(PrototypePieces &pieces,istream &s,Architecture *glb);
282 extern void parse_C(Architecture *glb,istream &s);
283 
284 // Routines to parse interface commands
285 
286 extern void parse_toseparator(istream &s,string &name);
287 extern Address parse_machaddr(istream &s,int4 &defaultsize,const TypeFactory &typegrp,bool ignorecolon=false);
288 extern Address parse_varnode(istream &s,int4 &size,Address &pc,uintm &uq,const TypeFactory &typegrp);
289 extern Address parse_op(istream &s,uintm &uq,const TypeFactory &typegrp);
290 
291 #endif
ArrayModifier
Definition: grammar.hh:140
FunctionModifier
Definition: grammar.hh:150
GrammarToken
Definition: grammar.hh:21
TypeSpecifiers
Definition: grammar.hh:184
Architecture
Manager for all the major decompiler subsystems.
Definition: architecture.hh:119
ProtoModel
A prototype model: a model for passing parameters between functions.
Definition: fspec.hh:622
funcdata.hh
Utilities for processing data structures associated with a single function.
Address
A low-level machine address for labelling bytes and data.
Definition: address.hh:46
PrototypePieces
Raw components of a function prototype (obtained from parsing source code)
Definition: fspec.hh:1144
Datatype
The base datatype class for the decompiler.
Definition: type.hh:62
TypeFactory
Container class for all Datatype objects in an Architecture.
Definition: type.hh:396
Datatype::size
int4 size
Size (of variable holding a value of this type)
Definition: type.hh:82
GrammarLexer
Definition: grammar.hh:67
TypeDeclarator
Definition: grammar.hh:163
TypeModifier
Definition: grammar.hh:116
CParse
Definition: grammar.hh:199
Enumerator
Definition: grammar.hh:191
PointerModifier
Definition: grammar.hh:131