Ghidra Decompiler Analysis Engine
transform.hh
Go to the documentation of this file.
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  */
18 #ifndef __TRANSFORM__
19 #define __TRANSFORM__
20 
21 #include "varnode.hh"
22 class Funcdata; // Forward declaration
23 class TransformOp;
24 
26 class TransformVar {
27  friend class TransformManager;
28  friend class TransformOp;
29 public:
31  enum {
32  piece = 1,
35  piece_temp = 4,
36  constant = 5,
38  };
40  enum {
43  };
44 private:
45  Varnode *vn;
46  Varnode *replacement;
47  uint4 type;
48  uint4 flags;
49  int4 byteSize;
50  int4 bitSize;
51  uintb val;
52  TransformOp *def;
53  void createReplacement(Funcdata *fd);
54  void initialize(uint4 tp,Varnode *v,int4 bits,int4 bytes,uintb value);
55 public:
56  Varnode *getOriginal(void) const { return vn; }
57  TransformOp *getDef(void) const { return def; }
58 };
59 
61 class TransformOp {
62  friend class TransformManager;
63  friend class TransformVar;
64 public:
66  enum {
71  };
72 private:
73  PcodeOp *op;
74  PcodeOp *replacement;
75  OpCode opc;
76  uint4 special;
77  TransformVar *output;
78  vector<TransformVar *> input;
79  TransformOp *follow;
80  void createReplacement(Funcdata *fd);
81  bool attemptInsertion(Funcdata *fd);
82 public:
83  TransformVar *getOut(void) const { return output; }
84  TransformVar *getIn(int4 i) const { return input[i]; }
85 };
86 
89  friend class LanedIterator;
90 public:
92  class LanedIterator {
93  int4 size;
94  uint4 mask;
95  void normalize(void);
96  public:
97  LanedIterator(const LanedRegister *lanedR) { size = 0; mask = lanedR->sizeBitMask; normalize(); }
98  LanedIterator(void) { size = -1; mask = 0; }
99  LanedIterator &operator++(void) { size += 1; normalize(); return *this; }
100  int4 operator*(void) const { return size; }
101  LanedIterator &operator=(const LanedIterator &op2) { size = op2.size; mask = op2.mask; return *this; }
102  bool operator==(const LanedIterator &op2) const { return (size == op2.size); }
103  bool operator!=(const LanedIterator &op2) const { return (size != op2.size); }
104  };
106 private:
107  int4 wholeSize;
108  uint4 sizeBitMask;
109 public:
110  LanedRegister(void) { wholeSize = 0; sizeBitMask = 0; }
111  LanedRegister(int4 sz,uint4 mask) { wholeSize = sz; sizeBitMask = mask; }
112  bool restoreXml(const Element *el,const AddrSpaceManager *manage);
113  int4 getWholeSize(void) const { return wholeSize; }
114  uint4 getSizeBitMask(void) const { return sizeBitMask; }
115  void addLaneSize(int4 size) { sizeBitMask |= ((uint4)1 << size); }
116  bool allowedLane(int4 size) const { return (((sizeBitMask >> size) & 1) != 0); }
117  const_iterator begin(void) const { return LanedIterator(this); }
118  const_iterator end(void) const { return LanedIterator(); }
119 };
120 
127  int4 wholeSize;
128  vector<int4> laneSize;
129  vector<int4> lanePosition;
130 public:
131  LaneDescription(const LaneDescription &op2);
132  LaneDescription(int4 origSize,int4 sz);
133  LaneDescription(int4 origSize,int4 lo,int4 hi);
134  bool subset(int4 lsbOffset,int4 size);
135  int4 getNumLanes(void) const { return laneSize.size(); }
136  int4 getWholeSize(void) const { return wholeSize; }
137  int4 getSize(int4 i) const { return laneSize[i]; }
138  int4 getPosition(int4 i) const { return lanePosition[i]; }
139  int4 getBoundary(int4 bytePos) const;
140  bool restriction(int4 numLanes,int4 skipLanes,int4 bytePos,int4 size,int4 &resNumLanes,int4 &resSkipLanes) const;
141  bool extension(int4 numLanes,int4 skipLanes,int4 bytePos,int4 size,int4 &resNumLanes,int4 &resSkipLanes) const;
142 };
143 
151  Funcdata *fd;
152  map<int4,TransformVar *> pieceMap;
153  list<TransformVar> newVarnodes;
154  list<TransformOp> newOps;
155 
156  void specialHandling(TransformOp &rop);
157  void createOps(void);
158  void createVarnodes(vector<TransformVar *> &inputList);
159  void removeOld(void);
160  void transformInputVarnodes(vector<TransformVar *> &inputList);
161  void placeInputs(void);
162 public:
163  TransformManager(Funcdata *f) { fd = f; }
164  virtual ~TransformManager(void);
165  virtual bool preserveAddress(Varnode *vn,int4 bitSize,int4 lsbOffset) const;
166  Funcdata *getFunction(void) const { return fd; }
167  void clearVarnodeMarks(void);
169  TransformVar *newUnique(int4 size);
170  TransformVar *newConstant(int4 size,int4 lsbOffset,uintb val);
171  TransformVar *newIop(Varnode *vn);
172  TransformVar *newPiece(Varnode *vn,int4 bitSize,int4 lsbOffset);
173  TransformVar *newSplit(Varnode *vn,const LaneDescription &description);
174  TransformVar *newSplit(Varnode *vn,const LaneDescription &description,int4 numLanes,int4 startLane);
175  TransformOp *newOpReplace(int4 numParams,OpCode opc,PcodeOp *replace);
176  TransformOp *newOp(int4 numParams,OpCode opc,TransformOp *follow);
177  TransformOp *newPreexistingOp(int4 numParams,OpCode opc,PcodeOp *originalOp);
178 
180  TransformVar *getPiece(Varnode *vn,int4 bitSize,int4 lsbOffset);
181  TransformVar *getSplit(Varnode *vn,const LaneDescription &description);
182  TransformVar *getSplit(Varnode *vn,const LaneDescription &description,int4 numLanes,int4 startLane);
183  void opSetInput(TransformOp *rop,TransformVar *rvn,int4 slot);
184  void opSetOutput(TransformOp *rop,TransformVar *rvn);
185  static bool preexistingGuard(int4 slot,TransformVar *rvn);
186 
187  void apply(void);
188 };
189 
197 inline void TransformVar::initialize(uint4 tp,Varnode *v,int4 bits,int4 bytes,uintb value)
198 
199 {
200  type = tp;
201  vn = v;
202  val = value;
203  bitSize = bits;
204  byteSize = bytes;
205  flags = 0;
206  def = (TransformOp *)0;
207  replacement = (Varnode *)0;
208 }
209 
213 inline void TransformManager::opSetInput(TransformOp *rop,TransformVar *rvn,int4 slot)
214 
215 {
216  rop->input[slot] = rvn;
217 }
218 
224 
225 {
226  rop->output = rvn;
227  rvn->def = rop;
228 }
229 
241 
242 {
243  if (slot == 0) return true; // If we came in on the first slot, build the TransformOp
244  if (rvn->type == TransformVar::piece || rvn->type == TransformVar::piece_temp)
245  return false; // The op was/will be visited on slot 0, don't create TransformOp now
246  return true; // The op was not (will not be) visited on slot 0, build now
247 }
248 
249 #endif
LanedRegister::LanedIterator
Class for iterating over possible lane sizes.
Definition: transform.hh:92
TransformOp::op_preexisting
@ op_preexisting
Op already exists (but will be transformed)
Definition: transform.hh:68
LaneDescription::extension
bool extension(int4 numLanes, int4 skipLanes, int4 bytePos, int4 size, int4 &resNumLanes, int4 &resSkipLanes) const
Decide if a given subset of lanes can be extended naturally for this description.
Definition: transform.cc:154
TransformManager::newIop
TransformVar * newIop(Varnode *vn)
Make placeholder for special iop constant.
Definition: transform.cc:407
TransformManager::newOp
TransformOp * newOp(int4 numParams, OpCode opc, TransformOp *follow)
Create a new placeholder op that will not replace an existing op.
Definition: transform.cc:522
LaneDescription
Description of logical lanes within a big Varnode.
Definition: transform.hh:126
LaneDescription::LaneDescription
LaneDescription(const LaneDescription &op2)
Copy constructor.
Definition: transform.cc:20
TransformManager::newPreexistingOp
TransformOp * newPreexistingOp(int4 numParams, OpCode opc, PcodeOp *originalOp)
Create a new placeholder op for an existing PcodeOp.
Definition: transform.cc:546
TransformVar::constant_iop
@ constant_iop
Special iop constant encoding a PcodeOp reference.
Definition: transform.hh:37
LaneDescription::subset
bool subset(int4 lsbOffset, int4 size)
Trim this to a subset of the original lanes.
Definition: transform.cc:68
TransformVar::split_terminator
@ split_terminator
The last (most significant piece) of a split array.
Definition: transform.hh:41
TransformVar
Placeholder node for Varnode that will exist after a transform is applied to a function.
Definition: transform.hh:26
TransformVar::preexisting
@ preexisting
Varnode preexisted in the original data-flow.
Definition: transform.hh:33
LanedRegister::const_iterator
LanedIterator const_iterator
Iterator over possible lane sizes for this register.
Definition: transform.hh:105
TransformManager::newUnique
TransformVar * newUnique(int4 size)
Make placeholder for new unique space Varnode.
Definition: transform.cc:380
LaneDescription::getBoundary
int4 getBoundary(int4 bytePos) const
Get index of lane that starts at the given byte position.
Definition: transform.cc:96
TransformManager::newPiece
TransformVar * newPiece(Varnode *vn, int4 bitSize, int4 lsbOffset)
Make placeholder for piece of a Varnode.
Definition: transform.cc:422
TransformManager::opSetInput
void opSetInput(TransformOp *rop, TransformVar *rvn, int4 slot)
Mark given variable as input to given op.
Definition: transform.hh:213
Element
An XML element. A node in the DOM tree.
Definition: xml.hh:150
PcodeOp
Lowest level operation of the p-code language.
Definition: op.hh:58
TransformManager::clearVarnodeMarks
void clearVarnodeMarks(void)
Clear mark for all Varnodes in the map.
Definition: transform.cc:352
TransformVar::piece_temp
@ piece_temp
A temporary representing a piece of an original Varnode.
Definition: transform.hh:35
TransformManager::getPreexistingVarnode
TransformVar * getPreexistingVarnode(Varnode *vn)
Get (or create) placeholder for preexisting Varnode.
Definition: transform.cc:565
TransformOp::indirect_creation
@ indirect_creation
Mark op as indirect creation.
Definition: transform.hh:69
Varnode
A low-level variable or contiguous set of bytes described by an Address and a size.
Definition: varnode.hh:65
TransformManager::apply
void apply(void)
Apply the full transform to the function.
Definition: transform.cc:740
LanedRegister
Describes a (register) storage location and the ways it might be split into lanes.
Definition: transform.hh:88
TransformManager::newSplit
TransformVar * newSplit(Varnode *vn, const LaneDescription &description)
Create placeholder nodes splitting a Varnode into its lanes.
Definition: transform.cc:441
TransformManager::newOpReplace
TransformOp * newOpReplace(int4 numParams, OpCode opc, PcodeOp *replace)
Create a new placeholder op intended to replace an existing op.
Definition: transform.cc:499
LanedRegister::restoreXml
bool restoreXml(const Element *el, const AddrSpaceManager *manage)
Restore object from XML stream.
Definition: transform.cc:284
TransformManager
Class for splitting larger registers holding smaller logical lanes.
Definition: transform.hh:150
TransformManager::preexistingGuard
static bool preexistingGuard(int4 slot, TransformVar *rvn)
Should newPreexistingOp be called.
Definition: transform.hh:240
LaneDescription::restriction
bool restriction(int4 numLanes, int4 skipLanes, int4 bytePos, int4 size, int4 &resNumLanes, int4 &resSkipLanes) const
Decide if a given truncation is natural for this description.
Definition: transform.cc:129
TransformOp::op_replacement
@ op_replacement
Op replaces an existing op.
Definition: transform.hh:67
TransformManager::opSetOutput
void opSetOutput(TransformOp *rop, TransformVar *rvn)
Mark given variable as output of given op.
Definition: transform.hh:223
TransformManager::newConstant
TransformVar * newConstant(int4 size, int4 lsbOffset, uintb val)
Make placeholder for constant Varnode.
Definition: transform.cc:395
Funcdata
Container for data structures associated with a single function.
Definition: funcdata.hh:45
TransformManager::preserveAddress
virtual bool preserveAddress(Varnode *vn, int4 bitSize, int4 lsbOffset) const
Should the address of the given Varnode be preserved when constructing a piece.
Definition: transform.cc:344
TransformVar::piece
@ piece
New Varnode is a piece of an original Varnode.
Definition: transform.hh:32
OpCode
OpCode
The op-code defining a specific p-code operation (PcodeOp)
Definition: opcodes.hh:35
TransformVar::input_duplicate
@ input_duplicate
This is a piece of an input that has already been visited.
Definition: transform.hh:42
TransformVar::normal_temp
@ normal_temp
A new temporary (unique space) Varnode.
Definition: transform.hh:34
TransformManager::newPreexistingVarnode
TransformVar * newPreexistingVarnode(Varnode *vn)
Make placeholder for preexisting Varnode.
Definition: transform.cc:366
TransformManager::getPiece
TransformVar * getPiece(Varnode *vn, int4 bitSize, int4 lsbOffset)
Get (or create) placeholder piece.
Definition: transform.cc:583
TransformManager::~TransformManager
virtual ~TransformManager(void)
Destructor.
Definition: transform.cc:325
TransformVar::constant
@ constant
A new constant Varnode.
Definition: transform.hh:36
TransformOp::indirect_creation_possible_out
@ indirect_creation_possible_out
Mark op as indirect creation and possible call output.
Definition: transform.hh:70
AddrSpaceManager
A manager for different address spaces.
Definition: translate.hh:218
TransformOp
Placeholder node for PcodeOp that will exist after a transform is applied to a function.
Definition: transform.hh:61
TransformManager::getSplit
TransformVar * getSplit(Varnode *vn, const LaneDescription &description)
Find (or create) placeholder nodes splitting a Varnode into its lanes.
Definition: transform.cc:604
varnode.hh
The Varnode and VarnodeBank classes.