Ghidra Decompiler Analysis Engine
rulecompile.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_RULE_COMPILE__
17 #define __CPUI_RULE_COMPILE__
18 
19 #include "unify.hh"
20 
21 class RuleLexer {
22  static int4 identlist[256]; // 1 is identifier, 2 is digit, 4=namechar
23  map<string,int4> keywordmap;
24  istream *s;
25  char identifier[256];
26  int4 identlength;
27  int4 lookahead[4];
28  int4 pos;
29  bool endofstream;
30  int4 lineno;
31  int4 getNextChar(void) {
32  char c;
33  int4 ret = lookahead[pos];
34  if (!endofstream) {
35  (*s).get(c);
36  if ((*s).eof()||(c=='\0')) {
37  endofstream = true;
38  lookahead[pos] = '\n';
39  }
40  else
41  lookahead[pos] = c;
42  }
43  else
44  lookahead[pos] = -1;
45  pos = (pos+1)&3;
46  return ret;
47  }
48  int4 next(int4 i) { return lookahead[(pos+i)&3]; }
49  int4 scanIdentifier(void);
50  int4 scanNumber(void);
51  int4 buildString(int4 tokentype);
52  int4 otherIdentifiers(void);
53  void initKeywords(void);
54 public:
55  RuleLexer(void);
56  void initialize(istream &t);
57  int4 getLineNo(void) { return lineno; }
58  int4 nextToken(void);
59 };
60 
61 class DummyTranslate : public Translate {
62 public:
63  virtual void initialize(DocumentStorage &store) {}
64  virtual void addRegister(const string &nm,AddrSpace *base,uintb offset,int4 size) {}
65  virtual const VarnodeData &getRegister(const string &nm) const { throw LowlevelError("Cannot add register to DummyTranslate"); }
66  virtual string getRegisterName(AddrSpace *base,uintb off,int4 size) const { return ""; }
67  virtual void getAllRegisters(map<VarnodeData,string> &reglist) const {}
68  virtual void getUserOpNames(vector<string> &res) const {}
69  virtual int4 instructionLength(const Address &baseaddr) const { return -1; }
70  virtual int4 oneInstruction(PcodeEmit &emit,const Address &baseaddr) const { return -1; }
71  virtual int4 printAssembly(AssemblyEmit &emit,const Address &baseaddr) const { return -1; }
72 };
73 
74 class RuleCompile {
75  ostream *error_stream;
76  int4 errors;
77  RuleLexer lexer;
78  map<string,int4> namemap;
79  ConstraintGroup *finalrule;
80  vector<OpBehavior *> inst;
81 public:
82  RuleCompile(void);
83  ~RuleCompile(void);
84  void ruleError(const char *s);
85  int4 numErrors(void) const { return errors; }
86  int4 getLineNo(void) { return lexer.getLineNo(); }
87  void setFullRule(ConstraintGroup *full) { finalrule = full; }
88  ConstraintGroup *getRule(void) { return finalrule; }
89  ConstraintGroup *releaseRule(void) { ConstraintGroup *res = finalrule; finalrule = (ConstraintGroup *)0; return res; }
90  const map<string,int4> &getNameMap(void) const { return namemap; }
91 
92  int4 findIdentifier(string *nm);
93 
94  ConstraintGroup *newOp(int4 id);
95  ConstraintGroup *newVarnode(int4 id);
96  ConstraintGroup *newConst(int4 id);
97 
98  ConstraintGroup *opCopy(ConstraintGroup *base,int4 opid);
99  ConstraintGroup *opInput(ConstraintGroup *base,int8 *slot,int4 varid);
100  ConstraintGroup *opInputAny(ConstraintGroup *base,int4 varid);
101  ConstraintGroup *opInputConstVal(ConstraintGroup *base,int8 *slot,RHSConstant *rhs);
102  ConstraintGroup *opOutput(ConstraintGroup *base,int4 varid);
103 
104  ConstraintGroup *varCopy(ConstraintGroup *base,int4 varid);
105  ConstraintGroup *varConst(ConstraintGroup *base,RHSConstant *ex,RHSConstant *sz);
106  ConstraintGroup *varDef(ConstraintGroup *base,int4 opid);
107  ConstraintGroup *varDescend(ConstraintGroup *base,int4 opid);
108  ConstraintGroup *varUniqueDescend(ConstraintGroup *base,int4 opid);
109 
110  ConstraintGroup *opCodeConstraint(ConstraintGroup *base,vector<OpCode> *oplist);
111  ConstraintGroup *opCompareConstraint(ConstraintGroup *base,int4 opid,OpCode opc);
112  ConstraintGroup *varCompareConstraint(ConstraintGroup *base,int4 varid,OpCode opc);
113  ConstraintGroup *constCompareConstraint(ConstraintGroup *base,int4 constid,OpCode opc);
114  ConstraintGroup *constNamedExpression(int4 id,RHSConstant *expr);
115 
116  ConstraintGroup *emptyGroup(void);
117  ConstraintGroup *emptyOrGroup(void);
118  ConstraintGroup *mergeGroups(ConstraintGroup *a,ConstraintGroup *b);
119  ConstraintGroup *addOr(ConstraintGroup *base,ConstraintGroup *newor);
120  ConstraintGroup *opCreation(int4 newid,OpCode oc,bool iafter,int4 oldid);
121  ConstraintGroup *newUniqueOut(ConstraintGroup *base,int4 varid,int4 sz);
122  ConstraintGroup *newSetInput(ConstraintGroup *base,RHSConstant *slot,int4 varid);
123  ConstraintGroup *newSetInputConstVal(ConstraintGroup *base,RHSConstant *slot,RHSConstant *val,RHSConstant *sz);
124  ConstraintGroup *removeInput(ConstraintGroup *base,RHSConstant *slot);
125  ConstraintGroup *newSetOpcode(ConstraintGroup *base,OpCode opc);
126  ConstraintGroup *booleanConstraint(bool ist,RHSConstant *expr);
127 
128  RHSConstant *constNamed(int4 id);
129  RHSConstant *constAbsolute(int8 *val);
130  RHSConstant *constBinaryExpression(RHSConstant *ex1,OpCode opc,RHSConstant *ex2);
131  RHSConstant *constVarnodeSize(int4 varindex);
132  RHSConstant *dotIdentifier(int4 id,string *str);
133 
134  int4 nextToken(void) { return lexer.nextToken(); }
135 
136  void setErrorStream(ostream &t) { error_stream = &t; }
137  void run(istream &s,bool debug);
138  void postProcess(void);
139  int4 postProcessRule(vector<OpCode> &opcodelist);
140  static ConstraintGroup *buildUnifyer(const string &rule,const vector<string> &idlist,vector<int4> &res);
141 };
142 
143 class RuleGeneric : public Rule { // A user configurable rule, (a rule read in from a file)
144  vector<OpCode> starterops;
145  int4 opinit; // Index of initialized op
146  ConstraintGroup *constraint;
147  UnifyState state;
148 public:
149  RuleGeneric(const string &g,const string &nm,const vector<OpCode> &sops,int4 opi,ConstraintGroup *c);
150  virtual ~RuleGeneric(void) { delete constraint; }
151  virtual Rule *clone(const ActionGroupList &grouplist) const {
152  if (!grouplist.contains(getGroup())) return (Rule *)0; return new RuleGeneric(getGroup(),getName(),starterops,opinit,(ConstraintGroup *)constraint->clone()); }
153  virtual void getOpList(vector<uint4> &oplist) const;
154  virtual int4 applyOp(PcodeOp *op,Funcdata &data);
155  static RuleGeneric *build(const string &nm,const string &gp,const string &content);
156 };
157 
158 /*
159  Definition of the language
160 
161  Identifiers start with 'o' for named pcodeops
162  'v' for named varnodes
163  '#' for named constants
164 
165  A "statement" is a sequence of "steps", ending in a semicolon
166  Steps are sequential, proceeding left to right. Each step is either a
167  building step (which defines a new entity in terms of an existing entity), or a
168  constraint (which forces a condition to be true)
169 
170  Building steps:
171 
172  o -> v v is the output of o
173  o1 -> o2 o2 is a (named) copy of o1
174  o <- v v is ANY input of o
175  o <-(0) v v is input 0 of o
176  o <-(1) #c input 1 to o is a constant (now named c)
177  o <-(1) #0 input 1 to o is a constant with value 0
178 
179  v <- o o is the defining op of v
180  v -> o o is ANY of the ops taking v as an input (may be inefficient)
181  v ->! o o is the one and only op taking v as input
182  v1 -> v2 v2 is a (named) copy of v1
183 
184  Constraints:
185 
186  o(+) o must have an opcode equal '+'
187  o1(== o2) o1 and o2 must be the same pcode op
188  o1(!= o2) o1 and o2 must not be the same pcode op
189  v1(== v2) v1 and v2 must be the same varnode
190  v1(!= v2) v1 and v2 must not be the same varnode
191 
192  Statements can be grouped (into "statementlist") with parentheses '(' and ')'
193  There is an OR operator
194 
195  '[' statementlist
196  | statementlist
197  ...
198  ']'
199 
200  */
201 
202 #endif
PcodeEmit
Abstract class for emitting pcode to an application.
Definition: translate.hh:76
RuleGeneric
Definition: rulecompile.hh:143
AddrSpace
A region where processor data is stored.
Definition: space.hh:73
LowlevelError
The lowest level error generated by the decompiler.
Definition: error.hh:44
Rule
Class for performing a single transformation on a PcodeOp or Varnode.
Definition: action.hh:194
AssemblyEmit
Abstract class for emitting disassembly to an application.
Definition: translate.hh:118
DummyTranslate::getRegisterName
virtual string getRegisterName(AddrSpace *base, uintb off, int4 size) const
Get the name of a register given its location.
Definition: rulecompile.hh:66
DummyTranslate::instructionLength
virtual int4 instructionLength(const Address &baseaddr) const
Get the length of a machine instruction.
Definition: rulecompile.hh:69
DummyTranslate::getAllRegisters
virtual void getAllRegisters(map< VarnodeData, string > &reglist) const
Get a list of all register names and the corresponding location.
Definition: rulecompile.hh:67
ActionGroupList
The list of groups defining a root Action.
Definition: action.hh:29
DummyTranslate::getRegister
virtual const VarnodeData & getRegister(const string &nm) const
Get a register as VarnodeData given its name.
Definition: rulecompile.hh:65
DummyTranslate::addRegister
virtual void addRegister(const string &nm, AddrSpace *base, uintb offset, int4 size)
Add a named register to the model for this processor.
Definition: rulecompile.hh:64
ConstraintGroup
Definition: unify.hh:490
DummyTranslate::initialize
virtual void initialize(DocumentStorage &store)
Initialize the translator given XML configuration documents.
Definition: rulecompile.hh:63
PcodeOp
Lowest level operation of the p-code language.
Definition: op.hh:58
RuleGeneric::applyOp
virtual int4 applyOp(PcodeOp *op, Funcdata &data)
Attempt to apply this Rule.
ActionGroupList::contains
bool contains(const string &nm) const
Check if this ActionGroupList contains a given group.
Definition: action.hh:37
Address
A low-level machine address for labelling bytes and data.
Definition: address.hh:46
DummyTranslate::printAssembly
virtual int4 printAssembly(AssemblyEmit &emit, const Address &baseaddr) const
Disassemble a single machine instruction.
Definition: rulecompile.hh:71
Funcdata
Container for data structures associated with a single function.
Definition: funcdata.hh:45
RuleGeneric::clone
virtual Rule * clone(const ActionGroupList &grouplist) const
Clone the Rule.
Definition: rulecompile.hh:151
RHSConstant
Definition: unify.hh:58
Translate
The interface to a translation engine for a processor.
Definition: translate.hh:294
OpCode
OpCode
The op-code defining a specific p-code operation (PcodeOp)
Definition: opcodes.hh:35
UnifyState
Definition: unify.hh:607
RuleCompile
Definition: rulecompile.hh:74
VarnodeData
Data defining a specific memory location.
Definition: pcoderaw.hh:33
DocumentStorage
A container for parsed XML documents.
Definition: xml.hh:249
DummyTranslate::getUserOpNames
virtual void getUserOpNames(vector< string > &res) const
Get a list of all user-defined pcode ops.
Definition: rulecompile.hh:68
RuleLexer
Definition: rulecompile.hh:21
DummyTranslate::oneInstruction
virtual int4 oneInstruction(PcodeEmit &emit, const Address &baseaddr) const
Transform a single machine instruction into pcode.
Definition: rulecompile.hh:70
RuleGeneric::getOpList
virtual void getOpList(vector< uint4 > &oplist) const
List of op codes this rule operates on.
DummyTranslate
Definition: rulecompile.hh:61