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