ROSE  0.9.9.109
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 "integerOps.h"
7 #include "sageBuilderAsm.h"
8 
9 namespace Rose {
10 namespace BinaryAnalysis {
11 
14 public:
15  DisassemblerPowerpc(): ip(0), insn(0) { init(); }
16  DisassemblerPowerpc(const DisassemblerPowerpc& other): Disassembler(other), ip(other.ip), insn(other.insn) {}
17  virtual ~DisassemblerPowerpc() {}
18  virtual DisassemblerPowerpc *clone() const { return new DisassemblerPowerpc(*this); }
19  virtual bool canDisassemble(SgAsmGenericHeader*) const;
20  virtual Unparser::BasePtr unparser() const;
21  virtual SgAsmInstruction *disassembleOne(const MemoryMap::Ptr &map, rose_addr_t start_va, AddressSet *successors=NULL);
22  virtual void assembleOne(SgAsmInstruction*, SgUnsignedCharList&) {abort();}
23  virtual SgAsmInstruction *makeUnknownInstruction(const Exception&);
24 private:
28  class ExceptionPowerpc: public Exception {
29  public:
30  ExceptionPowerpc(const std::string &mesg, const DisassemblerPowerpc *d, size_t bit=0)
31  : Exception(mesg, d->ip) {
32  /* Convert four-byte instruction to big-endian buffer. Note that PowerPC is big-endian, but PowerPC can support
33  * both big- and little-endian processor modes (with much weirdness; e.g. PDP endian like propoerties). */
34  bytes.push_back((d->insn>>24) & 0xff);
35  bytes.push_back((d->insn>>16) & 0xff);
36  bytes.push_back((d->insn>>8) & 0xff);
37  bytes.push_back(d->insn & 0xff);
38  ASSERT_require(bit<=32);
39  this->bit = 8*(4-(bit/8)) + bit%8; /*convert from native uint32_t bit position to big-endian*/
40  }
41  };
42 
44  makeRegister(PowerpcRegisterClass reg_class, int reg_number,
45  PowerpcConditionRegisterAccessGranularity reg_grainularity = powerpc_condreggranularity_whole) const;
46 
47  static SgAsmPowerpcInstruction *makeInstructionWithoutOperands(uint64_t address, const std::string& mnemonic,
48  PowerpcInstructionKind kind, uint32_t insn);
49 
51  template <size_t First, size_t Last> uint32_t fld() const;
52 
53  /* Decoded fields from section 1.7.16 of the v2.01 UISA */
54  bool AA() const {
55  return fld<30, 30>();
56  }
58  return makeRegister(powerpc_regclass_cr, fld<11, 15>(), powerpc_condreggranularity_bit);
59  }
61  return makeRegister(powerpc_regclass_cr, fld<16, 20>(), powerpc_condreggranularity_bit);
62  }
63  uint64_t BD() const {
64  return IntegerOps::signExtend<16, 64>((uint64_t)insn & 0xfffc);
65  }
66  SgAsmRegisterReferenceExpression* BF_cr() const {
67  return makeRegister(powerpc_regclass_cr, fld<6, 8>(), powerpc_condreggranularity_field);
68  }
69  SgAsmRegisterReferenceExpression* BF_fpscr() const {
70  return makeRegister(powerpc_regclass_fpscr, fld<6, 8>(), powerpc_condreggranularity_field);
71  }
72  SgAsmRegisterReferenceExpression* BFA_cr() const {
73  return makeRegister(powerpc_regclass_cr, fld<11, 13>(), powerpc_condreggranularity_field);
74  }
75  SgAsmRegisterReferenceExpression* BFA_fpscr() const {
76  return makeRegister(powerpc_regclass_fpscr, fld<11, 13>(), powerpc_condreggranularity_field);
77  }
78  SgAsmValueExpression* BH() const {
79  return SageBuilderAsm::buildValueU8(fld<19, 20>());
80  }
82  return BA();
83  }
84  SgAsmValueExpression* BO() const {
85  return SageBuilderAsm::buildValueU8(fld<6, 10>());
86  }
88  return makeRegister(powerpc_regclass_cr, fld<6, 10>(), powerpc_condreggranularity_bit);
89  }
90  SgAsmValueExpression* D() const {
91  return SageBuilderAsm::buildValueU64(IntegerOps::signExtend<16, 64>((uint64_t)fld<16, 31>()));
92  }
93  SgAsmValueExpression* DS() const {
94  return SageBuilderAsm::buildValueU64(IntegerOps::signExtend<16, 64>((uint64_t)fld<16, 31>() & 0xfffc));
95  }
96  SgAsmValueExpression* FLM() const {
97  return SageBuilderAsm::buildValueU8(fld<7, 14>());
98  }
100  return makeRegister(powerpc_regclass_fpr, fld<11, 15>());
101  }
102  SgAsmRegisterReferenceExpression* FRB() const {
103  return makeRegister(powerpc_regclass_fpr, fld<16, 20>());
104  }
105  SgAsmRegisterReferenceExpression* FRC() const {
106  return makeRegister(powerpc_regclass_fpr, fld<21, 25>());
107  }
108  SgAsmRegisterReferenceExpression* FRS() const {
109  return makeRegister(powerpc_regclass_fpr, fld<6, 10>());
110  }
111  SgAsmRegisterReferenceExpression* FRT() const {
112  return FRS();
113  }
114  SgAsmValueExpression* FXM() const {
115  return SageBuilderAsm::buildValueU8(fld<12, 19>());
116  }
117 
118  SgAsmValueExpression* L_10() const {
119  return SageBuilderAsm::buildValueU8(fld<10, 10>());
120  }
121  SgAsmValueExpression* L_15() const {
122  return SageBuilderAsm::buildValueU8(fld<15, 15>());
123  }
124  uint8_t L_sync() const {
125  return fld<9, 10>();
126  }
127  SgAsmValueExpression* LEV() const {
128  return SageBuilderAsm::buildValueU8(fld<20, 26>());
129  }
130  uint64_t LI() const {
131  return IntegerOps::signExtend<26, 64>(uint64_t(fld<6, 29>() * 4));
132  }
133  bool LK() const {
134  return fld<31, 31>();
135  }
136  SgAsmValueExpression* MB_32bit() const {
137  return SageBuilderAsm::buildValueU8(fld<21, 25>());
138  }
139  SgAsmValueExpression* ME_32bit() const {
140  return SageBuilderAsm::buildValueU8(fld<26, 30>());
141  }
142  SgAsmValueExpression* MB_64bit() const {
143  return SageBuilderAsm::buildValueU8(fld<21, 26>()); // FIXME check for splitting
144  }
145  SgAsmValueExpression* ME_64bit() const {
146  return SageBuilderAsm::buildValueU8(fld<21, 26>()); // FIXME check for splitting
147  }
148  SgAsmValueExpression* NB() const {
149  return SageBuilderAsm::buildValueU8(fld<16, 20>() == 0 ? 32 : fld<16, 20>());
150  }
151  bool OE() const {
152  return fld<21, 21>();
153  }
155  return makeRegister(powerpc_regclass_gpr, fld<11, 15>());
156  }
157  SgAsmExpression* RA_or_zero() const {
158  return fld<11, 15>() == 0 ? (SgAsmExpression*)SageBuilderAsm::buildValueU8(0) : RA();
159  }
161  return makeRegister(powerpc_regclass_gpr, fld<16, 20>());
162  }
163  bool Rc() const {
164  return fld<31, 31>();
165  }
167  return makeRegister(powerpc_regclass_gpr, fld<6, 10>());
168  }
170  return RS();
171  }
172  SgAsmValueExpression* SH_32bit() const {
173  return SageBuilderAsm::buildValueU8(fld<16, 20>());
174  }
175  SgAsmValueExpression* SH_64bit() const {
176  return SageBuilderAsm::buildValueU8(fld<16, 20>() + fld<30, 30>() * 32); // FIXME check
177  }
178  SgAsmValueExpression* SI() const {
179  return D();
180  }
181  SgAsmRegisterReferenceExpression* SPR() const {
182  return makeRegister(powerpc_regclass_spr, fld<16, 20>() * 32 + fld<11, 15>());
183  }
185  return makeRegister(powerpc_regclass_sr, fld<12, 15>());
186  }
187  SgAsmRegisterReferenceExpression* TBR() const {
188  return makeRegister(powerpc_regclass_tbr, fld<16, 20>() * 32 + fld<11, 15>());
189  }
190  SgAsmValueExpression* TH() const {
191  return SageBuilderAsm::buildValueU8(fld<9, 10>());
192  }
193  SgAsmValueExpression* TO() const {
194  return SageBuilderAsm::buildValueU8(fld<6, 10>());
195  }
196  SgAsmValueExpression* U() const {
197  return SageBuilderAsm::buildValueU8(fld<16, 19>());
198  }
199  SgAsmValueExpression* UI() const {
200  return SageBuilderAsm::buildValueU64(fld<16, 31>());
201  }
202 
203  SgAsmMemoryReferenceExpression* memref(SgAsmType* t) const {
204  return SageBuilderAsm::buildMemoryReferenceExpression(SageBuilderAsm::buildAddExpression(RA_or_zero(), D()), NULL, t);
205  }
206  SgAsmMemoryReferenceExpression* memrefx(SgAsmType* t) const {
207  return SageBuilderAsm::buildMemoryReferenceExpression(SageBuilderAsm::buildAddExpression(RA_or_zero(), RB()),
208  NULL, t);
209  }
210  SgAsmMemoryReferenceExpression* memrefu(SgAsmType* t) const {
211  if (fld<11, 15>() == 0)
212  throw ExceptionPowerpc("bits 11-15 must be nonzero", this);
213  return SageBuilderAsm::buildMemoryReferenceExpression(SageBuilderAsm::buildAddExpression(RA(), D()), NULL, t);
214  }
215  SgAsmMemoryReferenceExpression* memrefux(SgAsmType* t) const {
216  if (fld<11, 15>() == 0)
217  throw ExceptionPowerpc("bits 11-15 must be nonzero", this);
218  return SageBuilderAsm::buildMemoryReferenceExpression(SageBuilderAsm::buildAddExpression(RA(), RB()), NULL, t);
219  }
220 
221  /* There are 15 different forms of PowerPC instructions, but all are 32-bit (fixed length instruction set). */
222  SgAsmPowerpcInstruction* decode_I_formInstruction();
223  SgAsmPowerpcInstruction* decode_B_formInstruction();
224  SgAsmPowerpcInstruction* decode_SC_formInstruction();
225  SgAsmPowerpcInstruction* decode_DS_formInstruction();
226  SgAsmPowerpcInstruction* decode_X_formInstruction_00();
227  SgAsmPowerpcInstruction* decode_X_formInstruction_1F();
228  SgAsmPowerpcInstruction* decode_X_formInstruction_3F();
229  SgAsmPowerpcInstruction* decode_XL_formInstruction();
230  SgAsmPowerpcInstruction* decode_XS_formInstruction();
231  SgAsmPowerpcInstruction* decode_A_formInstruction_00();
232  SgAsmPowerpcInstruction* decode_A_formInstruction_04();
233  SgAsmPowerpcInstruction* decode_A_formInstruction_3B();
234  SgAsmPowerpcInstruction* decode_A_formInstruction_3F();
235  SgAsmPowerpcInstruction* decode_MD_formInstruction();
236  SgAsmPowerpcInstruction* decode_MDS_formInstruction();
237 
238  SgAsmIntegerValueExpression* makeBranchTarget( uint64_t targetAddr ) const;
239 
240  SgAsmPowerpcInstruction* disassemble();
241 
243  void init();
244 
246  void startInstruction(rose_addr_t start_va, uint32_t c) {
247  ip = start_va;
248  insn = c;
249  }
250 
251  /* Per-instruction data members (mostly set by startInstruction()) */
252  uint64_t ip;
253  uint32_t insn;
254 };
255 
256 } // namespace
257 } // namespace
258 
259 #endif
Base class for references to a machine register.
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.
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.
Represents one PowerPC machine instruction.
Base class for expressions.
Base class for binary types.
Base class for values.
virtual DisassemblerPowerpc * clone() const
Creates a new copy of a disassembler.
Virtual base class for instruction disassemblers.
Definition: Disassembler.h:41
Disassembler for the PowerPC architecture.
std::set< rose_addr_t > AddressSet
An AddressSet contains virtual addresses (alternatively, relative virtual addresses) for such things ...
Definition: Disassembler.h:82
virtual SgAsmInstruction * makeUnknownInstruction(const Exception &)
Makes an unknown instruction from an exception.