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