My Project
translate.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  */
20 
21 #ifndef __CPUI_TRANSLATE__
22 #define __CPUI_TRANSLATE__
23 
24 #include "pcoderaw.hh"
25 #include "float.hh"
26 
27 // Some errors specific to the translation unit
28 
35 struct UnimplError : public LowlevelError {
37  UnimplError(const string &s,int4 l) : LowlevelError(s) { instruction_length = l; }
42 };
43 
50 struct BadDataError : public LowlevelError {
54  BadDataError(const string &s) : LowlevelError(s) {}
55 };
56 
57 class Translate;
58 
64  string spaceName;
65  uint4 size;
66 public:
67  void restoreXml(const Element *el);
68  const string &getName(void) const { return spaceName; }
69  uint4 getSize(void) const { return size; }
70 };
71 
76 class PcodeEmit {
77 public:
78  virtual ~PcodeEmit(void) {}
79 
92  virtual void dump(const Address &addr,OpCode opc,VarnodeData *outvar,VarnodeData *vars,int4 isize)=0;
93 
95  void restoreXmlOp(const Element *el,const AddrSpaceManager *trans);
96 
97  enum { // Tags for packed pcode format
98  unimpl_tag = 0x20,
99  inst_tag = 0x21,
100  op_tag = 0x22,
101  void_tag = 0x23,
102  spaceid_tag = 0x24,
103  addrsz_tag = 0x25,
104  end_tag = 0x60
105  };
107  static const uint1 *unpackOffset(const uint1 *ptr,uintb &off);
109  static const uint1 *unpackVarnodeData(const uint1 *ptr,VarnodeData &v,const AddrSpaceManager *trans);
111  const uint1 *restorePackedOp(const Address &addr,const uint1 *ptr,const AddrSpaceManager *trans);
112 };
113 
119 public:
120  virtual ~AssemblyEmit(void) {}
121 
131  virtual void dump(const Address &addr,const string &mnem,const string &body)=0;
132 };
133 
141 public:
142  virtual ~AddressResolver(void) {}
143 
156  virtual Address resolve(uintb val,int4 sz,const Address &point,uintb &fullEncoding)=0;
157 };
158 
170 class SpacebaseSpace : public AddrSpace {
171  friend class AddrSpaceManager;
172  AddrSpace *contain;
173  bool hasbaseregister;
174  bool isNegativeStack;
175  VarnodeData baseloc;
176  VarnodeData baseOrig;
177  void setBaseRegister(const VarnodeData &data,int4 origSize,bool stackGrowth);
178 public:
179  SpacebaseSpace(AddrSpaceManager *m,const Translate *t,const string &nm,int4 ind,int4 sz,AddrSpace *base,int4 dl);
181  virtual int4 numSpacebase(void) const;
182  virtual const VarnodeData &getSpacebase(int4 i) const;
183  virtual const VarnodeData &getSpacebaseFull(int4 i) const;
184  virtual bool stackGrowsNegative(void) const { return isNegativeStack; }
185  virtual AddrSpace *getContain(void) const { return contain; }
186  virtual void saveXml(ostream &s) const;
187  virtual void restoreXml(const Element *el);
188 };
189 
195 class JoinRecord {
196  friend class AddrSpaceManager;
197  vector<VarnodeData> pieces;
198  VarnodeData unified;
199 public:
200  int4 numPieces(void) const { return pieces.size(); }
201  bool isFloatExtension(void) const { return (pieces.size() == 1); }
202  const VarnodeData &getPiece(int4 i) const { return pieces[i]; }
203  const VarnodeData &getUnified(void) const { return unified; }
204  Address getEquivalentAddress(uintb offset,int4 &pos) const;
205  bool operator<(const JoinRecord &op2) const;
206 };
207 
210  bool operator()(const JoinRecord *a,const JoinRecord *b) const {
211  return *a < *b; }
212 };
213 
219  vector<AddrSpace *> baselist;
220  vector<AddressResolver *> resolvelist;
221  map<string,AddrSpace *> name2Space;
222  map<int4,AddrSpace *> shortcut2Space;
223  AddrSpace *constantspace;
224  AddrSpace *defaultcodespace;
225  AddrSpace *defaultdataspace;
226  AddrSpace *iopspace;
227  AddrSpace *fspecspace;
228  AddrSpace *joinspace;
229  AddrSpace *stackspace;
230  AddrSpace *uniqspace;
231  uintb joinallocate;
232  set<JoinRecord *,JoinRecordCompare> splitset;
233  vector<JoinRecord *> splitlist;
234 protected:
235  AddrSpace *restoreXmlSpace(const Element *el,const Translate *trans);
236  void restoreXmlSpaces(const Element *el,const Translate *trans);
237  void setDefaultCodeSpace(int4 index);
238  void setDefaultDataSpace(int4 index);
239  void setReverseJustified(AddrSpace *spc);
240  void assignShortcut(AddrSpace *spc);
241  void markNearPointers(AddrSpace *spc,int4 size);
242  void insertSpace(AddrSpace *spc);
243  void copySpaces(const AddrSpaceManager *op2);
244  void addSpacebasePointer(SpacebaseSpace *basespace,const VarnodeData &ptrdata,int4 truncSize,bool stackGrowth);
245  void insertResolver(AddrSpace *spc,AddressResolver *rsolv);
246  JoinRecord *findJoinInternal(uintb offset) const;
247 public:
248  AddrSpaceManager(void);
249  virtual ~AddrSpaceManager(void);
250  int4 getDefaultSize(void) const;
251  AddrSpace *getSpaceByName(const string &nm) const;
252  AddrSpace *getSpaceByShortcut(char sc) const;
253  AddrSpace *getIopSpace(void) const;
254  AddrSpace *getFspecSpace(void) const;
255  AddrSpace *getJoinSpace(void) const;
256  AddrSpace *getStackSpace(void) const;
257  AddrSpace *getUniqueSpace(void) const;
258  AddrSpace *getDefaultCodeSpace(void) const;
259  AddrSpace *getDefaultDataSpace(void) const;
260  AddrSpace *getConstantSpace(void) const;
261  Address getConstant(uintb val) const;
262  Address createConstFromSpace(AddrSpace *spc) const;
263  Address resolveConstant(AddrSpace *spc,uintb val,int4 sz,const Address &point,uintb &fullEncoding) const;
264  int4 numSpaces(void) const;
265  AddrSpace *getSpace(int4 i) const;
266  AddrSpace *getNextSpaceInOrder(AddrSpace *spc) const;
267  JoinRecord *findAddJoin(const vector<VarnodeData> &pieces,uint4 logicalsize);
268  JoinRecord *findJoin(uintb offset) const;
269  void setDeadcodeDelay(AddrSpace *spc,int4 delaydelta);
270  void truncateSpace(const TruncationTag &tag);
271 
273  Address constructFloatExtensionAddress(const Address &realaddr,int4 realsize,int4 logicalsize);
274 
276  Address constructJoinAddress(const Translate *translate,const Address &hiaddr,int4 hisz,const Address &loaddr,int4 losz);
277 
279  void renormalizeJoinAddress(Address &addr,int4 size);
280 };
281 
293 class Translate : public AddrSpaceManager {
294  bool target_isbigendian;
295  uintm unique_base;
296 protected:
297  int4 alignment;
298  vector<FloatFormat> floatformats;
299 
300  void setBigEndian(bool val);
301  void setUniqueBase(uintm val);
302 public:
303  Translate(void);
304  void setDefaultFloatFormats(void);
305  bool isBigEndian(void) const;
306  const FloatFormat *getFloatFormat(int4 size) const;
307  int4 getAlignment(void) const;
308  uintm getUniqueBase(void) const;
309 
315  virtual void initialize(DocumentStorage &store)=0;
316 
327  virtual void registerContext(const string &name,int4 sbit,int4 ebit) {}
328 
336  virtual void setContextDefault(const string &name,uintm val) {}
337 
346  virtual void allowContextSet(bool val) const {}
347 
356  virtual void addRegister(const string &nm,AddrSpace *base,uintb offset,int4 size)=0;
357 
363  virtual const VarnodeData &getRegister(const string &nm) const=0;
364 
375  virtual string getRegisterName(AddrSpace *base,uintb off,int4 size) const=0;
376 
383  virtual void getAllRegisters(map<VarnodeData,string> &reglist) const=0;
384 
393  virtual void getUserOpNames(vector<string> &res) const=0;
394 
402  virtual int4 instructionLength(const Address &baseaddr) const=0;
403 
417  virtual int4 oneInstruction(PcodeEmit &emit,const Address &baseaddr) const=0;
418 
427  virtual int4 printAssembly(AssemblyEmit &emit,const Address &baseaddr) const=0;
428 };
429 
433 inline int4 AddrSpaceManager::getDefaultSize(void) const {
434  return defaultcodespace->getAddrSize();
435 }
436 
443  return iopspace;
444 }
445 
452  return fspecspace;
453 }
454 
461  return joinspace;
462 }
463 
470  return stackspace;
471 }
472 
482  return uniqspace;
483 }
484 
491  return defaultcodespace;
492 }
493 
500  return defaultdataspace;
501 }
502 
508  return constantspace;
509 }
510 
517 inline Address AddrSpaceManager::getConstant(uintb val) const {
518  return Address(constantspace,val);
519 }
520 
528  return Address(constantspace,(uintb)(uintp)spc);
529 }
530 
535 inline int4 AddrSpaceManager::numSpaces(void) const {
536  return baselist.size();
537 }
538 
544 inline AddrSpace *AddrSpaceManager::getSpace(int4 i) const {
545  return baselist[i];
546 }
547 
552 inline void Translate::setBigEndian(bool val) {
553  target_isbigendian = val;
554 }
555 
563 inline void Translate::setUniqueBase(uintm val) {
564  if (val>unique_base) unique_base = val;
565 }
566 
571 inline bool Translate::isBigEndian(void) const {
572  return target_isbigendian;
573 }
574 
581 inline int4 Translate::getAlignment(void) const {
582  return alignment;
583 }
584 
591 inline uintm Translate::getUniqueBase(void) const {
592  return unique_base;
593 }
594 
595 #endif
A container for parsed XML documents.
Definition: xml.hh:249
int4 getAlignment(void) const
Get the instruction alignment for the processor.
Definition: translate.hh:581
A region where processor data is stored.
Definition: space.hh:73
int4 numPieces(void) const
Get number of pieces in this record.
Definition: translate.hh:200
AddrSpace * getJoinSpace(void) const
Get the joining space.
Definition: translate.hh:460
OpCode
The op-code defining a specific p-code operation (PcodeOp)
Definition: opcodes.hh:35
A manager for different address spaces.
Definition: translate.hh:218
virtual ~PcodeEmit(void)
Virtual destructor.
Definition: translate.hh:78
Abstract class for emitting pcode to an application.
Definition: translate.hh:76
Raw descriptions of varnodes and p-code ops.
int4 instruction_length
Definition: translate.hh:36
void setBigEndian(bool val)
Set general endianness to big if val is true.
Definition: translate.hh:552
AddrSpace * getSpace(int4 i) const
Get an address space via its index.
Definition: translate.hh:544
A virtual space stack space.
Definition: translate.hh:170
void setUniqueBase(uintm val)
Set the base offset for new temporary registers.
Definition: translate.hh:563
AddrSpace * getConstantSpace(void) const
Get the constant space.
Definition: translate.hh:507
const string & getName(void) const
Get name of address space being truncated.
Definition: translate.hh:68
virtual ~AssemblyEmit(void)
Virtual destructor.
Definition: translate.hh:120
uintm getUniqueBase(void) const
Get the base offset for new temporary registers.
Definition: translate.hh:591
AddrSpace * getStackSpace(void) const
Get the stack space for this processor.
Definition: translate.hh:469
AddrSpace * getIopSpace(void) const
Get the internal pcode op space.
Definition: translate.hh:442
Exception for encountering unimplemented pcode.
Definition: translate.hh:35
virtual void setContextDefault(const string &name, uintm val)
Set the default value for a particular context variable.
Definition: translate.hh:336
const VarnodeData & getUnified(void) const
Get the Varnode whole.
Definition: translate.hh:203
Abstract class for converting native constants to addresses.
Definition: translate.hh:140
int4 alignment
Byte modulo on which instructions are aligned.
Definition: translate.hh:297
A low-level machine address for labelling bytes and data.
Definition: address.hh:46
The interface to a translation engine for a processor.
Definition: translate.hh:293
vector< FloatFormat > floatformats
Floating point formats utilized by the processor.
Definition: translate.hh:298
virtual void registerContext(const string &name, int4 sbit, int4 ebit)
Add a new context variable to the model for this processor.
Definition: translate.hh:327
The lowest level error generated by the decompiler.
Definition: error.hh:44
A record describing how logical values are split.
Definition: translate.hh:195
Object for describing how a space should be truncated.
Definition: translate.hh:63
An XML element. A node in the DOM tree.
Definition: xml.hh:150
uint4 getSize(void) const
Size (of pointers) for new truncated space.
Definition: translate.hh:69
AddrSpace * getDefaultCodeSpace(void) const
Get the default address space of this processor.
Definition: translate.hh:490
int4 numSpaces(void) const
Get the number of address spaces for this processor.
Definition: translate.hh:535
AddrSpace * getUniqueSpace(void) const
Get the temporary register space for this processor.
Definition: translate.hh:481
UnimplError(const string &s, int4 l)
Constructor.
Definition: translate.hh:41
const VarnodeData & getPiece(int4 i) const
Get the i-th piece.
Definition: translate.hh:202
int4 getDefaultSize(void) const
Get size of addresses for the default space.
Definition: translate.hh:433
Address getConstant(uintb val) const
Get a constant encoded as an Address.
Definition: translate.hh:517
Address createConstFromSpace(AddrSpace *spc) const
Create a constant address encoding an address space.
Definition: translate.hh:527
bool isBigEndian(void) const
Is the processor big endian?
Definition: translate.hh:571
virtual bool stackGrowsNegative(void) const
Return true if a stack in this space grows negative.
Definition: translate.hh:184
bool isFloatExtension(void) const
Does this record extend a float varnode.
Definition: translate.hh:201
Support for decoding different floating-point formats.
BadDataError(const string &s)
Constructor.
Definition: translate.hh:54
Encoding information for a single floating-point format.
Definition: float.hh:30
bool operator()(const JoinRecord *a, const JoinRecord *b) const
Compare to JoinRecords using their built-in comparison.
Definition: translate.hh:210
Comparator for JoinRecord objects.
Definition: translate.hh:209
Abstract class for emitting disassembly to an application.
Definition: translate.hh:118
Exception for bad instruction data.
Definition: translate.hh:50
virtual AddrSpace * getContain(void) const
Return containing space.
Definition: translate.hh:185
virtual void allowContextSet(bool val) const
Toggle whether disassembly is allowed to affect context.
Definition: translate.hh:346
AddrSpace * getDefaultDataSpace(void) const
Get the default address space where data is stored.
Definition: translate.hh:499
Data defining a specific memory location.
Definition: pcoderaw.hh:33
AddrSpace * getFspecSpace(void) const
Get the internal callspec space.
Definition: translate.hh:451