ROSE  0.11.98.0
Disassembler/Powerpc.h
1 /* Disassembly specific to the PowerPC architecture. */
2 #ifndef ROSE_BinaryAnalysis_Disassembler_Powerpc_H
3 #define ROSE_BinaryAnalysis_Disassembler_Powerpc_H
4 #include <featureTests.h>
5 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
6 #include <Rose/BinaryAnalysis/Disassembler/Base.h>
7 
8 #include "integerOps.h"
9 #include "SageBuilderAsm.h"
10 
11 namespace Rose {
12 namespace BinaryAnalysis {
13 namespace Disassembler {
14 
16 class Powerpc: public Base {
17 public:
19  using Ptr = PowerpcPtr;
20 
21 private:
22  // Per-instruction state
23  struct State {
24  uint64_t ip; // Instruction pointer
25  uint32_t insn; // 4-byte instruction word
26  State(): ip(0), insn(0) {}
27  };
28 
29  PowerpcWordSize wordSize_;
30  ByteOrder::Endianness sex_;
31 
32 protected:
33  explicit Powerpc(PowerpcWordSize, ByteOrder::Endianness);
34 
35 public:
37  static Ptr instance(PowerpcWordSize wordSize, ByteOrder::Endianness sex);
38 
39  // Overrides documented in a super class
40  virtual ~Powerpc() {}
41  virtual Base::Ptr clone() const;
42  virtual bool canDisassemble(SgAsmGenericHeader*) const;
43  virtual Unparser::BasePtr unparser() const;
44  virtual SgAsmInstruction *disassembleOne(const MemoryMap::Ptr &map, rose_addr_t start_va, AddressSet *successors=NULL);
45  virtual void assembleOne(SgAsmInstruction*, SgUnsignedCharList&) {abort();}
47 
48 private:
49  // Same as Exception except with a different constructor for ease of use in Powerpc. This constructor should be used when
50  // an exception occurs during disassembly of an instruction; it is not suitable for errors that occur before or after (use
51  // superclass constructors for that case).
52  class ExceptionPowerpc: public Exception {
53  public:
54  ExceptionPowerpc(const std::string &mesg, const State &state, size_t bit=0)
55  : Exception(mesg, state.ip) {
56  // Convert four-byte instruction to big-endian buffer. Note that PowerPC is big-endian, but PowerPC can support
57  // both big- and little-endian processor modes (with much weirdness; e.g. PDP endian like propoerties). */
58  bytes.push_back((state.insn>>24) & 0xff);
59  bytes.push_back((state.insn>>16) & 0xff);
60  bytes.push_back((state.insn>>8) & 0xff);
61  bytes.push_back(state.insn & 0xff);
62  ASSERT_require(bit<=32);
63  this->bit = 8*(4-(bit/8)) + bit%8; // convert from native uint32_t bit position to big-endian
64  }
65  };
66 
68  makeRegister(State&, PowerpcRegisterClass reg_class, int reg_number,
69  PowerpcConditionRegisterAccessGranularity reg_grainularity = powerpc_condreggranularity_whole,
70  SgAsmType *type = NULL) const;
71 
76  bool is64bitInsn(PowerpcInstructionKind);
77 
79  SgAsmPowerpcInstruction* makeInstructionWithoutOperands(uint64_t address, const std::string& mnemonic, PowerpcInstructionKind,
80  uint32_t insnBytes);
81 
82  // Helper function to use field definitions (counted with bits from left and inclusive on both sides) from manual.
83  template <size_t First, size_t Last> uint64_t fld(State&) const;
84 
85  // Decoded fields from section 1.7.16 of the v2.01 UISA.
86  bool AA(State &state) const {
87  return fld<30, 30>(state);
88  }
89 
90  SgAsmRegisterReferenceExpression* BA(State &state) const {
91  return makeRegister(state, powerpc_regclass_cr, fld<11, 15>(state), powerpc_condreggranularity_bit);
92  }
93 
94  SgAsmRegisterReferenceExpression* BB(State &state) const {
95  return makeRegister(state, powerpc_regclass_cr, fld<16, 20>(state), powerpc_condreggranularity_bit);
96  }
97 
98  uint64_t BD(State &state) const {
99  return IntegerOps::signExtend<16, 64>((uint64_t)state.insn & 0xfffc);
100  }
101 
102  SgAsmRegisterReferenceExpression* BF_cr(State &state) const {
103  return makeRegister(state, powerpc_regclass_cr, fld<6, 8>(state), powerpc_condreggranularity_field);
104  }
105 
106  SgAsmRegisterReferenceExpression* BF_fpscr(State &state) const {
107  return makeRegister(state, powerpc_regclass_fpscr, fld<6, 8>(state), powerpc_condreggranularity_field);
108  }
109 
110  SgAsmRegisterReferenceExpression* BFA_cr(State &state) const {
111  return makeRegister(state, powerpc_regclass_cr, fld<11, 13>(state), powerpc_condreggranularity_field);
112  }
113 
114  SgAsmRegisterReferenceExpression* BFA_fpscr(State &state) const {
115  return makeRegister(state, powerpc_regclass_fpscr, fld<11, 13>(state), powerpc_condreggranularity_field);
116  }
117 
118  SgAsmValueExpression* BH(State &state) const {
119  return SageBuilderAsm::buildValueU8(fld<19, 20>(state));
120  }
121 
122  SgAsmRegisterReferenceExpression* BI(State &state) const {
123  return BA(state);
124  }
125 
126  SgAsmValueExpression* BO(State &state) const {
127  return SageBuilderAsm::buildValueU8(fld<6, 10>(state));
128  }
129 
130  SgAsmRegisterReferenceExpression* BT(State &state) const {
131  return makeRegister(state, powerpc_regclass_cr, fld<6, 10>(state), powerpc_condreggranularity_bit);
132  }
133 
134  SgAsmValueExpression* D(State &state) const {
135  switch (wordSize_) {
136  case powerpc_32:
137  return SageBuilderAsm::buildValueU32(IntegerOps::signExtend<16, 32>((uint64_t)fld<16, 31>(state)));
138  case powerpc_64:
139  return SageBuilderAsm::buildValueU64(IntegerOps::signExtend<16, 64>((uint64_t)fld<16, 31>(state)));
140  }
141  ASSERT_not_reachable("invalid word size");
142  }
143 
144  SgAsmValueExpression* DS(State &state) const {
145  switch (wordSize_) {
146  case powerpc_32:
147  return SageBuilderAsm::buildValueU32(IntegerOps::signExtend<16, 32>((uint64_t)fld<16, 31>(state) & 0xfffc));
148  case powerpc_64:
149  return SageBuilderAsm::buildValueU64(IntegerOps::signExtend<16, 64>((uint64_t)fld<16, 31>(state) & 0xfffc));
150  }
151  ASSERT_not_reachable("invalid word size");
152  }
153 
154  SgAsmValueExpression* FLM(State &state) const {
155  return SageBuilderAsm::buildValueU8(fld<7, 14>(state));
156  }
157 
158  SgAsmRegisterReferenceExpression* FRA(State &state) const {
159  return makeRegister(state, powerpc_regclass_fpr, fld<11, 15>(state));
160  }
161 
162  SgAsmRegisterReferenceExpression* FRB(State &state) const {
163  return makeRegister(state, powerpc_regclass_fpr, fld<16, 20>(state));
164  }
165 
166  SgAsmRegisterReferenceExpression* FRC(State &state) const {
167  return makeRegister(state, powerpc_regclass_fpr, fld<21, 25>(state));
168  }
169 
170  SgAsmRegisterReferenceExpression* FRS(State &state) const {
171  return makeRegister(state, powerpc_regclass_fpr, fld<6, 10>(state));
172  }
173 
174  SgAsmRegisterReferenceExpression* FRT(State &state) const {
175  return FRS(state);
176  }
177 
178  SgAsmValueExpression* FXM(State &state) const {
179  return SageBuilderAsm::buildValueU8(fld<12, 19>(state));
180  }
181 
182  SgAsmValueExpression* L_10(State &state) const {
183  return SageBuilderAsm::buildValueU8(fld<10, 10>(state));
184  }
185 
186  SgAsmValueExpression* L_15(State &state) const {
187  return SageBuilderAsm::buildValueU8(fld<15, 15>(state));
188  }
189 
190  uint8_t L_sync(State &state) const {
191  return fld<9, 10>(state);
192  }
193 
194  SgAsmValueExpression* LEV(State &state) const {
195  return SageBuilderAsm::buildValueU8(fld<20, 26>(state));
196  }
197 
198  uint64_t LI(State &state) const {
199  return IntegerOps::signExtend<26, 64>(uint64_t(fld<6, 29>(state) * 4));
200  }
201 
202  bool LK(State &state) const {
203  return fld<31, 31>(state);
204  }
205 
206  SgAsmValueExpression* MB_32bit(State &state) const {
207  return SageBuilderAsm::buildValueU8(fld<21, 25>(state));
208  }
209 
210  SgAsmValueExpression* ME_32bit(State &state) const {
211  return SageBuilderAsm::buildValueU8(fld<26, 30>(state));
212  }
213 
214  SgAsmValueExpression* MB_64bit(State &state) const {
215  return SageBuilderAsm::buildValueU8(fld<21, 25>(state) + 32 * fld<26, 26>(state));
216  }
217 
218  SgAsmValueExpression* ME_64bit(State &state) const {
219  return SageBuilderAsm::buildValueU8(fld<21, 25>(state) + 32 * fld<26, 26>(state));
220  }
221 
222  SgAsmValueExpression* NB(State &state) const {
223  return SageBuilderAsm::buildValueU8(fld<16, 20>(state) == 0 ? 32 : fld<16, 20>(state));
224  }
225 
226  bool OE(State &state) const {
227  return fld<21, 21>(state);
228  }
229 
230  SgAsmRegisterReferenceExpression* RA(State &state) const {
231  return makeRegister(state, powerpc_regclass_gpr, fld<11, 15>(state));
232  }
233 
234  SgAsmExpression* RA_or_zero(State &state) const {
235  return fld<11, 15>(state) == 0 ? (SgAsmExpression*)SageBuilderAsm::buildValueU8(0) : RA(state);
236  }
237 
238  SgAsmRegisterReferenceExpression* RB(State &state) const {
239  return makeRegister(state, powerpc_regclass_gpr, fld<16, 20>(state));
240  }
241 
242  bool Rc(State &state) const {
243  return fld<31, 31>(state);
244  }
245 
246  SgAsmRegisterReferenceExpression* RS(State &state) const {
247  return makeRegister(state, powerpc_regclass_gpr, fld<6, 10>(state));
248  }
249 
250  SgAsmRegisterReferenceExpression* RT(State &state) const {
251  return RS(state);
252  }
253 
254  SgAsmValueExpression* SH_32bit(State &state) const {
255  return SageBuilderAsm::buildValueU8(fld<16, 20>(state));
256  }
257 
258  SgAsmValueExpression* SH_64bit(State &state) const {
259  return SageBuilderAsm::buildValueU8(fld<16, 20>(state) + fld<30, 30>(state) * 32); // FIXME check
260  }
261 
262  SgAsmValueExpression* SI(State &state) const {
263  return D(state);
264  }
265 
266  SgAsmRegisterReferenceExpression* SPR(State &state) const {
267  return makeRegister(state, powerpc_regclass_spr, fld<16, 20>(state) * 32 + fld<11, 15>(state));
268  }
269 
270  SgAsmRegisterReferenceExpression* SR(State &state) const {
271  return makeRegister(state, powerpc_regclass_sr, fld<12, 15>(state));
272  }
273 
274  SgAsmRegisterReferenceExpression* TBR(State &state) const {
275  return makeRegister(state, powerpc_regclass_tbr, fld<16, 20>(state) * 32 + fld<11, 15>(state));
276  }
277 
278  SgAsmValueExpression* TH(State &state) const {
279  return SageBuilderAsm::buildValueU8(fld<9, 10>(state));
280  }
281 
282  SgAsmValueExpression* TO(State &state) const {
283  return SageBuilderAsm::buildValueU8(fld<6, 10>(state));
284  }
285 
286  SgAsmValueExpression* U(State &state) const {
287  return SageBuilderAsm::buildValueU8(fld<16, 19>(state));
288  }
289 
290  SgAsmValueExpression* UI(State &state) const {
291  switch (wordSize_) {
292  case powerpc_32:
293  return SageBuilderAsm::buildValueU32(fld<16, 31>(state));
294  case powerpc_64:
295  return SageBuilderAsm::buildValueU64(fld<16, 31>(state));
296  }
297  ASSERT_not_reachable("invalid word size");
298  }
299 
300  SgAsmMemoryReferenceExpression* memref(State &state, SgAsmType* t) const {
301  return SageBuilderAsm::buildMemoryReferenceExpression(SageBuilderAsm::buildAddExpression(RA_or_zero(state), D(state)), NULL, t);
302  }
303 
304  SgAsmMemoryReferenceExpression* memrefds(State &state, SgAsmType *t) const {
305  return SageBuilderAsm::buildMemoryReferenceExpression(SageBuilderAsm::buildAddExpression(RA_or_zero(state), DS(state)), NULL, t);
306  }
307 
308  SgAsmMemoryReferenceExpression* memrefra(State &state, SgAsmType *t) const {
309  return SageBuilderAsm::buildMemoryReferenceExpression(RA_or_zero(state), NULL, t);
310  }
311 
312  SgAsmMemoryReferenceExpression* memrefx(State &state, SgAsmType* t) const {
313  return SageBuilderAsm::buildMemoryReferenceExpression(SageBuilderAsm::buildAddExpression(RA_or_zero(state), RB(state)),
314  NULL, t);
315  }
316 
317  SgAsmMemoryReferenceExpression* memrefu(State &state, SgAsmType* t) const {
318  if (fld<11, 15>(state) == 0)
319  throw ExceptionPowerpc("bits 11-15 must be nonzero", state);
320  return SageBuilderAsm::buildMemoryReferenceExpression(SageBuilderAsm::buildAddExpression(RA(state), D(state)), NULL, t);
321  }
322 
323  SgAsmMemoryReferenceExpression* memrefux(State &state, SgAsmType* t) const {
324  if (fld<11, 15>(state) == 0)
325  throw ExceptionPowerpc("bits 11-15 must be nonzero", state);
326  return SageBuilderAsm::buildMemoryReferenceExpression(SageBuilderAsm::buildAddExpression(RA(state), RB(state)), NULL, t);
327  }
328 
329  // There are 15 different forms of PowerPC instructions, but all are 32-bit (fixed length instruction set).
330  SgAsmPowerpcInstruction* decode_I_formInstruction(State&);
331  SgAsmPowerpcInstruction* decode_B_formInstruction(State&);
332  SgAsmPowerpcInstruction* decode_SC_formInstruction(State&);
333  SgAsmPowerpcInstruction* decode_DS_formInstruction(State&);
334  SgAsmPowerpcInstruction* decode_X_formInstruction_00(State&);
335  SgAsmPowerpcInstruction* decode_X_formInstruction_1F(State&);
336  SgAsmPowerpcInstruction* decode_X_formInstruction_3F(State&);
337  SgAsmPowerpcInstruction* decode_XL_formInstruction(State&);
338  SgAsmPowerpcInstruction* decode_XS_formInstruction(State&);
339  SgAsmPowerpcInstruction* decode_A_formInstruction_00(State&);
340  SgAsmPowerpcInstruction* decode_A_formInstruction_04(State&);
341  SgAsmPowerpcInstruction* decode_A_formInstruction_3B(State&);
342  SgAsmPowerpcInstruction* decode_A_formInstruction_3F(State&);
343  SgAsmPowerpcInstruction* decode_MD_formInstruction(State&);
344  SgAsmPowerpcInstruction* decode_MDS_formInstruction(State&);
345 
346  SgAsmIntegerValueExpression* makeBranchTarget( uint64_t targetAddr ) const;
347 
348  SgAsmPowerpcInstruction* disassemble(State&);
349 
350  // Initialize instances of this class. Called by constructor.
351  void init();
352 
353  // Resets disassembler state to beginning of an instruction.
354  void startInstruction(State &state, rose_addr_t start_va, uint32_t c) const {
355  state.ip = start_va;
356  state.insn = c;
357  }
358 };
359 
360 } // namespace
361 } // namespace
362 } // namespace
363 
364 #endif
365 #endif
Base class for references to a machine register.
Sawyer::SharedPointer< Powerpc > PowerpcPtr
Reference counted pointer for Powerpc decoder.
Base class for machine instructions.
Disassembler for the PowerPC architecture.
Main namespace for the ROSE library.
virtual SgAsmInstruction * makeUnknownInstruction(const Exception &)
Makes an unknown instruction from an exception.
PowerpcPtr Ptr
Reference counting pointer.
Reference to memory locations.
Base class for container file headers.
Base class for integer values.
Represents one PowerPC machine instruction.
virtual SgAsmInstruction * disassembleOne(const MemoryMap::Ptr &map, rose_addr_t start_va, AddressSet *successors=NULL)
This is the lowest level disassembly function and is implemented in the architecture-specific subclas...
Base class for expressions.
Binary analysis.
virtual Base::Ptr clone() const
Creates a new copy of a disassembler.
Base class for binary types.
Base class for values.
virtual bool canDisassemble(SgAsmGenericHeader *) const
Predicate determining the suitability of a disassembler for a specific file header.
static Ptr instance(PowerpcWordSize wordSize, ByteOrder::Endianness sex)
Allocating constructor for 32- or 64-bit disassembler.
Base class for all ROSE exceptions.
Definition: Rose/Exception.h:9
Virtual base class for instruction disassemblers.
virtual Unparser::BasePtr unparser() const
Unparser.