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