Ghidra Decompiler Analysis Engine
context.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 __CONTEXT__
17 #define __CONTEXT__
18 
19 #include "globalcontext.hh"
20 #include "opcodes.hh"
21 
22 class Token { // A multiple-byte sized chunk of pattern in a bitstream
23  string name;
24  int4 size; // Number of bytes in token;
25  int4 index; // Index of this token, for resolving offsets
26  bool bigendian;
27 public:
28  Token(const string &nm,int4 sz,bool be,int4 ind) : name(nm) { size = sz; bigendian=be; index = ind; }
29  int4 getSize(void) const { return size; }
30  bool isBigEndian(void) const { return bigendian; }
31  int4 getIndex(void) const { return index; }
32  const string &getName(void) const { return name; }
33 };
34 
35 struct FixedHandle { // A handle that is fully resolved
36  AddrSpace *space;
37  uint4 size;
38  AddrSpace *offset_space; // Either null or where dynamic offset is stored
39  uintb offset_offset; // Either static offset or ptr offset
40  uint4 offset_size; // Size of pointer
41  AddrSpace *temp_space; // Consistent temporary location for value
42  uintb temp_offset;
43 };
44 
45 class Constructor;
47  Constructor *ct;
48  FixedHandle hand;
49  vector<ConstructState *> resolve;
50  ConstructState *parent;
51  int4 length; // Length of this instantiation of the constructor
52  uint4 offset; // Absolute offset (from start of instruction)
53 };
54 
55 class TripleSymbol;
56 struct ContextSet { // Instructions for setting a global context value
57  TripleSymbol *sym; // Resolves to address where setting takes effect
58  ConstructState *point; // Point at which context set was made
59  int4 num; // Number of context word affected
60  uintm mask; // Bits within word affected
61  uintm value; // New setting for bits
62  bool flow; // Does the new context flow from its set point
63 };
64 
65 class ParserWalker; // Forward declaration
66 class ParserWalkerChange;
67 
69  friend class ParserWalker;
70  friend class ParserWalkerChange;
71 public:
72  enum { // Possible states of the ParserContext
73  uninitialized = 0, // Instruction has not been parsed at all
74  disassembly = 1, // Instruction is parsed in preparation for disassembly
75  pcode = 2 // Instruction is parsed in preparation for generating p-code
76  };
77 private:
78  int4 parsestate;
79  AddrSpace *const_space;
80  uint1 buf[16]; // Buffer of bytes in the instruction stream
81  uintm *context; // Pointer to local context
82  int4 contextsize; // Number of entries in context array
83  ContextCache *contcache; // Interface for getting/setting context
84  vector<ContextSet> contextcommit;
85  Address addr; // Address of start of instruction
86  Address naddr; // Address of next instruction
87  Address calladdr; // For injections, this is the address of the call being overridden
88  vector<ConstructState> state; // Current resolved instruction
89  ConstructState *base_state;
90  int4 alloc; // Number of ConstructState's allocated
91  int4 delayslot; // delayslot depth
92 public:
93  ParserContext(ContextCache *ccache);
94  ~ParserContext(void) { if (context != (uintm *)0) delete [] context; }
95  uint1 *getBuffer(void) { return buf; }
96  void initialize(int4 maxstate,int4 maxparam,AddrSpace *spc);
97  int4 getParserState(void) const { return parsestate; }
98  void setParserState(int4 st) { parsestate = st; }
99  void deallocateState(ParserWalkerChange &walker);
100  void allocateOperand(int4 i,ParserWalkerChange &walker);
101  void setAddr(const Address &ad) { addr = ad; }
102  void setNaddr(const Address &ad) { naddr = ad; }
103  void setCalladdr(const Address &ad) { calladdr = ad; }
104  void addCommit(TripleSymbol *sym,int4 num,uintm mask,bool flow,ConstructState *point);
105  void clearCommits(void) { contextcommit.clear(); }
106  void applyCommits(void);
107  const Address &getAddr(void) const { return addr; }
108  const Address &getNaddr(void) const { return naddr; }
109  const Address &getDestAddr(void) const { return calladdr; }
110  const Address &getRefAddr(void) const { return calladdr; }
111  AddrSpace *getCurSpace(void) const { return addr.getSpace(); }
112  AddrSpace *getConstSpace(void) const { return const_space; }
113  uintm getInstructionBytes(int4 byteoff,int4 numbytes,uint4 off) const;
114  uintm getContextBytes(int4 byteoff,int4 numbytes) const;
115  uintm getInstructionBits(int4 startbit,int4 size,uint4 off) const;
116  uintm getContextBits(int4 startbit,int4 size) const;
117  void setContextWord(int4 i,uintm val,uintm mask) { context[i] = (context[i]&(~mask))|(mask&val); }
118  void loadContext(void) { contcache->getContext(addr,context); }
119  int4 getLength(void) const { return base_state->length; }
120  void setDelaySlot(int4 val) { delayslot = val; }
121  int4 getDelaySlot(void) const { return delayslot; }
122 };
123 
124 class ParserWalker { // A class for walking the ParserContext
125  const ParserContext *const_context;
126  const ParserContext *cross_context;
127 protected:
128  ConstructState *point; // The current node being visited
129  int4 depth; // Depth of the current node
130  int4 breadcrumb[32]; // Path of operands from root
131 public:
132  ParserWalker(const ParserContext *c) { const_context = c; cross_context = (const ParserContext *)0; }
133  ParserWalker(const ParserContext *c,const ParserContext *cross) { const_context = c; cross_context = cross; }
134  const ParserContext *getParserContext(void) const { return const_context; }
135  void baseState(void) { point = const_context->base_state; depth=0; breadcrumb[0] = 0; }
136  void setOutOfBandState(Constructor *ct,int4 index,ConstructState *tempstate,const ParserWalker &otherwalker);
137  bool isState(void) const { return (point != (ConstructState *)0); }
138  void pushOperand(int4 i) { breadcrumb[depth++] = i+1; point = point->resolve[i]; breadcrumb[depth] = 0; }
139  void popOperand(void) { point = point->parent; depth-= 1; }
140  uint4 getOffset(int4 i) const { if (i<0) return point->offset;
141  ConstructState *op=point->resolve[i]; return op->offset + op->length; }
142  Constructor *getConstructor(void) const { return point->ct; }
143  int4 getOperand(void) const { return breadcrumb[depth]; }
144  FixedHandle &getParentHandle(void) { return point->hand; }
145  const FixedHandle &getFixedHandle(int4 i) const { return point->resolve[i]->hand; }
146  AddrSpace *getCurSpace(void) const { return const_context->getCurSpace(); }
147  AddrSpace *getConstSpace(void) const { return const_context->getConstSpace(); }
148  const Address &getAddr(void) const { if (cross_context != (const ParserContext *)0) { return cross_context->getAddr(); } return const_context->getAddr(); }
149  const Address &getNaddr(void) const { if (cross_context != (const ParserContext *)0) { return cross_context->getNaddr();} return const_context->getNaddr(); }
150  const Address &getRefAddr(void) const { if (cross_context != (const ParserContext *)0) { return cross_context->getRefAddr();} return const_context->getRefAddr(); }
151  const Address &getDestAddr(void) const { if (cross_context != (const ParserContext *)0) { return cross_context->getDestAddr();} return const_context->getDestAddr(); }
152  int4 getLength(void) const { return const_context->getLength(); }
153  uintm getInstructionBytes(int4 byteoff,int4 numbytes) const {
154  return const_context->getInstructionBytes(byteoff,numbytes,point->offset); }
155  uintm getContextBytes(int4 byteoff,int4 numbytes) const {
156  return const_context->getContextBytes(byteoff,numbytes); }
157  uintm getInstructionBits(int4 startbit,int4 size) const {
158  return const_context->getInstructionBits(startbit,size,point->offset); }
159  uintm getContextBits(int4 startbit,int4 size) const {
160  return const_context->getContextBits(startbit,size); }
161 };
162 
163 class ParserWalkerChange : public ParserWalker { // Extension to walker that allows for on the fly modifications to tree
164  friend class ParserContext;
165  ParserContext *context;
166 public:
167  ParserWalkerChange(ParserContext *c) : ParserWalker(c) { context = c; }
168  ParserContext *getParserContext(void) { return context; }
169  ConstructState *getPoint(void) { return point; }
170  void setOffset(uint4 off) { point->offset = off; }
171  void setConstructor(Constructor *c) { point->ct = c; }
172  void setCurrentLength(int4 len) { point->length = len; }
173  void calcCurrentLength(int4 length,int4 numopers);
174 };
175 
176 struct SleighError : public LowlevelError {
177  SleighError(const string &s) : LowlevelError(s) {}
178 };
179 
180 inline void ParserContext::deallocateState(ParserWalkerChange &walker) {
181  alloc = 1;
182  walker.context=this;
183  walker.baseState();
184 }
185 
186 inline void ParserContext::allocateOperand(int4 i,ParserWalkerChange &walker) {
187  ConstructState *opstate = &state[alloc++];
188  opstate->parent = walker.point;
189  opstate->ct = (Constructor *)0;
190  walker.point->resolve[i] = opstate;
191  walker.breadcrumb[walker.depth++] += 1;
192  walker.point = opstate;
193  walker.breadcrumb[walker.depth] = 0;
194 }
195 
196 #endif
ContextSet
Definition: context.hh:56
Constructor
Definition: slghsymbol.hh:466
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
ConstructState
Definition: context.hh:46
SleighError
Definition: context.hh:176
TripleSymbol
Definition: slghsymbol.hh:146
ParserContext
Definition: context.hh:68
Token
Definition: context.hh:22
opcodes.hh
All the individual p-code operations.
ContextCache
A helper class for caching the active context blob to minimize database lookups.
Definition: globalcontext.hh:309
ParserWalkerChange
Definition: context.hh:163
Address::getSpace
AddrSpace * getSpace(void) const
Get the address space.
Definition: address.hh:294
Address
A low-level machine address for labelling bytes and data.
Definition: address.hh:46
LowlevelError::LowlevelError
LowlevelError(const string &s)
Initialize the error with an explanatory string.
Definition: error.hh:47
ContextCache::getContext
void getContext(const Address &addr, uintm *buf) const
Retrieve the context blob for the given address.
Definition: globalcontext.cc:582
globalcontext.hh
Utilities for getting address-based context to the disassembler and decompiler.
FixedHandle
Definition: context.hh:35
ParserWalker
Definition: context.hh:124