ROSE  0.9.6a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DisassemblerX86.h
Go to the documentation of this file.
1 /* Disassembly specific to the x86 architecture. */
2 
3 #ifndef ROSE_DISASSEMBLER_X86_H
4 #define ROSE_DISASSEMBLER_X86_H
5 
6 #include "Disassembler.h"
7 #include "InstructionEnumsX86.h"
8 
12 
13 
14  /*========================================================================================================================
15  * Public methods
16  *========================================================================================================================*/
17 public:
18  DisassemblerX86(size_t wordsize)
21  rexR(false), rexX(false), rexB(false), sizeMustBe64Bit(false), operandSizeOverride(false), addressSizeOverride(false),
23  modrm(NULL), reg(NULL), isUnconditionalJump(false) {
24  init(wordsize);
25  }
26 
28  : Disassembler(other), insnSize(other.insnSize), ip(other.ip), insnbufat(other.insnbufat),
31  rexR(other.rexR), rexX(other.rexX), rexB(other.rexB), sizeMustBe64Bit(other.sizeMustBe64Bit),
34  modregrmByte(other.modregrmByte), modeField(other.modeField), rmField(other.rmField), modrm(other.modrm),
36  }
37 
38  virtual ~DisassemblerX86() {}
39 
40  virtual DisassemblerX86 *clone() const /*override*/ { return new DisassemblerX86(*this); }
41 
43  virtual bool can_disassemble(SgAsmGenericHeader*) const /*override*/;
44 
46  virtual SgAsmInstruction *disassembleOne(const MemoryMap *map, rose_addr_t start_va,
47  AddressSet *successors=NULL) /*override*/;
48 
50  virtual SgAsmInstruction *make_unknown_instruction(const Exception&) /*override*/;
51 
52 
53  /*========================================================================================================================
54  * Data types
55  *========================================================================================================================*/
56 private:
57 
61  class ExceptionX86: public Exception {
62  public:
63  ExceptionX86(const std::string &mesg, const DisassemblerX86 *d)
64  : Exception(mesg, d->ip, d->insnbuf, 8*d->insnbufat)
65  {}
66  ExceptionX86(const std::string &mesg, const DisassemblerX86 *d, size_t bit)
67  : Exception(mesg, d->ip, d->insnbuf, bit)
68  {}
69  };
70 
73  {
75  };
76 
77  /* MMX registers? See mmPrefix method */
78  enum MMPrefix
79  {
81  };
82 
83 
84 
85 
86  /*========================================================================================================================
87  * Methods for reading and writing bytes of the instruction. These keep track of how much has been read or written.
88  *========================================================================================================================*/
89 private:
90 
94  uint8_t getByte();
95 
99  uint16_t getWord();
100 
104  uint32_t getDWord();
105 
109  uint64_t getQWord();
110 
111  /*========================================================================================================================
112  * Miscellaneous helper methods
113  *========================================================================================================================*/
114 private:
118 
123 
127  }
128 
133 
137  }
138 
140  bool longMode() const {
141  return insnSize == x86_insnsize_64;
142  }
143 
144  /* FIXME: documentation? */
145  MMPrefix mmPrefix() const;
146 
148  void not64() const {
149  if (longMode())
150  throw ExceptionX86("not valid for 64-bit code", this);
151  }
152 
155  void setRex(uint8_t prefix);
156 
159 
163 
164 
165 
166  /*========================================================================================================================
167  * Methods that construct something. (Their names all start with "make".)
168  *========================================================================================================================*/
169 private:
170 
173  SgAsmExpression *makeAddrSizeValue(int64_t val, size_t bit_offset, size_t bit_size);
174 
179  SgAsmx86Instruction *makeInstruction(X86InstructionKind kind, const std::string &mnemonic,
180  SgAsmExpression *op1=NULL, SgAsmExpression *op2=NULL,
181  SgAsmExpression *op3=NULL, SgAsmExpression *op4=NULL);
182 
185 
186  /* FIXME: documentation? */
187  SgAsmx86RegisterReferenceExpression *makeOperandRegisterByte(bool rexExtension, uint8_t registerNumber);
188 
189  /* FIXME: documentation? */
190  SgAsmx86RegisterReferenceExpression *makeOperandRegisterFull(bool rexExtension, uint8_t registerNumber);
191 
194  SgAsmx86RegisterReferenceExpression *makeRegister(uint8_t fullRegisterNumber, RegisterMode, SgAsmType *registerType=NULL) const;
195 
196  /* FIXME: documentation? */
198  return makeRegister(fullRegisterNumber, effectiveOperandMode());
199  }
200 
201  /* FIXME: documentation? */
202  SgAsmx86RegisterReferenceExpression *makeRegisterEffective(bool rexExtension, uint8_t registerNumber) {
203  return makeRegister(registerNumber + (rexExtension ? 8 : 0), effectiveOperandMode());
204  }
205 
208 
209 
210 
211  /*========================================================================================================================
212  * Methods for operating on the ModR/M byte.
213  *========================================================================================================================*/
214 private:
215 
229  void getModRegRM(RegisterMode regMode, RegisterMode rmMode, SgAsmType *t, SgAsmType *tForReg = NULL);
230 
233 
236  void fillInModRM(RegisterMode rmMode, SgAsmType *t);
237 
240 
244 
246  void requireMemory() const {
247  if (!modregrmByteSet)
248  throw ExceptionX86("requires Mod/RM byte", this);
249  if (modeField == 3)
250  throw ExceptionX86("requires memory", this);
251  }
252 
253 
254 
255  /*========================================================================================================================
256  * Methods that construct an SgAsmExpression for an immediate operand.
257  *========================================================================================================================*/
258 private:
259 
270 
271 
272 
273 
274  /*========================================================================================================================
275  * Main disassembly functions, each generally containing a huge "switch" statement based on one of the opcode bytes.
276  *========================================================================================================================*/
277 private:
278 
282 
285 
288 
291 
294 
297 
300 
303 
306 
309 
312 
315 
318 
321 
324 
327 
330 
333 
337 
340 
343 
346 
349 
352 
353 
354 
355  /*========================================================================================================================
356  * Data members and their initialization.
357  *========================================================================================================================*/
358 private:
359 
361  void init(size_t wordsize);
362 
365  startInstruction(insn->get_address(), NULL, 0);
366  insnSize = insn->get_baseSize();
367  lock = insn->get_lockPrefix();
371  }
372 
374  void startInstruction(rose_addr_t start_va, const uint8_t *buf, size_t bufsz) {
375  ip = start_va;
376  insnbuf = SgUnsignedCharList(buf, buf+bufsz);
377  insnbufat = 0;
378 
379  /* Prefix flags */
382  branchPredictionEnabled = false;
383  rexPresent = rexW = rexR = rexX = rexB = false;
384  sizeMustBe64Bit = false;
385  operandSizeOverride = false;
386  addressSizeOverride = false;
387  lock = false;
389  modregrmByteSet = false;
390  modregrmByte = modeField = regField = rmField = 0; /*arbitrary since modregrmByteSet is false*/
391  modrm = reg = NULL;
392  isUnconditionalJump = false;
393  }
394 
395  /* Per-disassembler settings; see init() */
398  /* Per-instruction settings; see startInstruction() */
399  uint64_t ip;
401  size_t insnbufat;
403  /* Temporary flags set by the instruction; initialized by startInstruction() */
405  X86BranchPrediction branchPrediction; /*FIXME: this seems to set only to x86_branch_prediction_true [RPM 2009-06-16] */
411  bool lock;
414  uint8_t modregrmByte;
415  uint8_t modeField;
416  uint8_t regField;
417  uint8_t rmField;
421 };
422 
423 #endif