ROSE  0.9.10.91
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,
46  SgAsmType *type = NULL) const;
47 
48  static SgAsmPowerpcInstruction *makeInstructionWithoutOperands(uint64_t address, const std::string& mnemonic,
49  PowerpcInstructionKind kind, uint32_t insn);
50 
52  template <size_t First, size_t Last> uint32_t fld() const;
53 
54  /* Decoded fields from section 1.7.16 of the v2.01 UISA */
55  bool AA() const {
56  return fld<30, 30>();
57  }
59  return makeRegister(powerpc_regclass_cr, fld<11, 15>(), powerpc_condreggranularity_bit);
60  }
62  return makeRegister(powerpc_regclass_cr, fld<16, 20>(), powerpc_condreggranularity_bit);
63  }
64  uint64_t BD() const {
65  return IntegerOps::signExtend<16, 64>((uint64_t)insn & 0xfffc);
66  }
67  SgAsmRegisterReferenceExpression* BF_cr() const {
68  return makeRegister(powerpc_regclass_cr, fld<6, 8>(), powerpc_condreggranularity_field);
69  }
70  SgAsmRegisterReferenceExpression* BF_fpscr() const {
71  return makeRegister(powerpc_regclass_fpscr, fld<6, 8>(), powerpc_condreggranularity_field);
72  }
73  SgAsmRegisterReferenceExpression* BFA_cr() const {
74  return makeRegister(powerpc_regclass_cr, fld<11, 13>(), powerpc_condreggranularity_field);
75  }
76  SgAsmRegisterReferenceExpression* BFA_fpscr() const {
77  return makeRegister(powerpc_regclass_fpscr, fld<11, 13>(), powerpc_condreggranularity_field);
78  }
79  SgAsmValueExpression* BH() const {
80  return SageBuilderAsm::buildValueU8(fld<19, 20>());
81  }
83  return BA();
84  }
85  SgAsmValueExpression* BO() const {
86  return SageBuilderAsm::buildValueU8(fld<6, 10>());
87  }
89  return makeRegister(powerpc_regclass_cr, fld<6, 10>(), powerpc_condreggranularity_bit);
90  }
91  SgAsmValueExpression* D() const {
92  return SageBuilderAsm::buildValueU64(IntegerOps::signExtend<16, 64>((uint64_t)fld<16, 31>()));
93  }
94  SgAsmValueExpression* DS() const {
95  return SageBuilderAsm::buildValueU64(IntegerOps::signExtend<16, 64>((uint64_t)fld<16, 31>() & 0xfffc));
96  }
97  SgAsmValueExpression* FLM() const {
98  return SageBuilderAsm::buildValueU8(fld<7, 14>());
99  }
100  SgAsmRegisterReferenceExpression* FRA() const {
101  return makeRegister(powerpc_regclass_fpr, fld<11, 15>());
102  }
103  SgAsmRegisterReferenceExpression* FRB() const {
104  return makeRegister(powerpc_regclass_fpr, fld<16, 20>());
105  }
106  SgAsmRegisterReferenceExpression* FRC() const {
107  return makeRegister(powerpc_regclass_fpr, fld<21, 25>());
108  }
109  SgAsmRegisterReferenceExpression* FRS() const {
110  return makeRegister(powerpc_regclass_fpr, fld<6, 10>());
111  }
112  SgAsmRegisterReferenceExpression* FRT() const {
113  return FRS();
114  }
115  SgAsmValueExpression* FXM() const {
116  return SageBuilderAsm::buildValueU8(fld<12, 19>());
117  }
118 
119  SgAsmValueExpression* L_10() const {
120  return SageBuilderAsm::buildValueU8(fld<10, 10>());
121  }
122  SgAsmValueExpression* L_15() const {
123  return SageBuilderAsm::buildValueU8(fld<15, 15>());
124  }
125  uint8_t L_sync() const {
126  return fld<9, 10>();
127  }
128  SgAsmValueExpression* LEV() const {
129  return SageBuilderAsm::buildValueU8(fld<20, 26>());
130  }
131  uint64_t LI() const {
132  return IntegerOps::signExtend<26, 64>(uint64_t(fld<6, 29>() * 4));
133  }
134  bool LK() const {
135  return fld<31, 31>();
136  }
137  SgAsmValueExpression* MB_32bit() const {
138  return SageBuilderAsm::buildValueU8(fld<21, 25>());
139  }
140  SgAsmValueExpression* ME_32bit() const {
141  return SageBuilderAsm::buildValueU8(fld<26, 30>());
142  }
143  SgAsmValueExpression* MB_64bit() const {
144  return SageBuilderAsm::buildValueU8(fld<21, 26>()); // FIXME check for splitting
145  }
146  SgAsmValueExpression* ME_64bit() const {
147  return SageBuilderAsm::buildValueU8(fld<21, 26>()); // FIXME check for splitting
148  }
149  SgAsmValueExpression* NB() const {
150  return SageBuilderAsm::buildValueU8(fld<16, 20>() == 0 ? 32 : fld<16, 20>());
151  }
152  bool OE() const {
153  return fld<21, 21>();
154  }
156  return makeRegister(powerpc_regclass_gpr, fld<11, 15>());
157  }
158  SgAsmExpression* RA_or_zero() const {
159  return fld<11, 15>() == 0 ? (SgAsmExpression*)SageBuilderAsm::buildValueU8(0) : RA();
160  }
162  return makeRegister(powerpc_regclass_gpr, fld<16, 20>());
163  }
164  bool Rc() const {
165  return fld<31, 31>();
166  }
168  return makeRegister(powerpc_regclass_gpr, fld<6, 10>());
169  }
171  return RS();
172  }
173  SgAsmValueExpression* SH_32bit() const {
174  return SageBuilderAsm::buildValueU8(fld<16, 20>());
175  }
176  SgAsmValueExpression* SH_64bit() const {
177  return SageBuilderAsm::buildValueU8(fld<16, 20>() + fld<30, 30>() * 32); // FIXME check
178  }
179  SgAsmValueExpression* SI() const {
180  return D();
181  }
182  SgAsmRegisterReferenceExpression* SPR() const {
183  return makeRegister(powerpc_regclass_spr, fld<16, 20>() * 32 + fld<11, 15>());
184  }
186  return makeRegister(powerpc_regclass_sr, fld<12, 15>());
187  }
188  SgAsmRegisterReferenceExpression* TBR() const {
189  return makeRegister(powerpc_regclass_tbr, fld<16, 20>() * 32 + fld<11, 15>());
190  }
191  SgAsmValueExpression* TH() const {
192  return SageBuilderAsm::buildValueU8(fld<9, 10>());
193  }
194  SgAsmValueExpression* TO() const {
195  return SageBuilderAsm::buildValueU8(fld<6, 10>());
196  }
197  SgAsmValueExpression* U() const {
198  return SageBuilderAsm::buildValueU8(fld<16, 19>());
199  }
200  SgAsmValueExpression* UI() const {
201  return SageBuilderAsm::buildValueU64(fld<16, 31>());
202  }
203 
204  SgAsmMemoryReferenceExpression* memref(SgAsmType* t) const {
205  return SageBuilderAsm::buildMemoryReferenceExpression(SageBuilderAsm::buildAddExpression(RA_or_zero(), D()), NULL, t);
206  }
207  SgAsmMemoryReferenceExpression* memrefx(SgAsmType* t) const {
208  return SageBuilderAsm::buildMemoryReferenceExpression(SageBuilderAsm::buildAddExpression(RA_or_zero(), RB()),
209  NULL, t);
210  }
211  SgAsmMemoryReferenceExpression* memrefu(SgAsmType* t) const {
212  if (fld<11, 15>() == 0)
213  throw ExceptionPowerpc("bits 11-15 must be nonzero", this);
214  return SageBuilderAsm::buildMemoryReferenceExpression(SageBuilderAsm::buildAddExpression(RA(), D()), NULL, t);
215  }
216  SgAsmMemoryReferenceExpression* memrefux(SgAsmType* t) const {
217  if (fld<11, 15>() == 0)
218  throw ExceptionPowerpc("bits 11-15 must be nonzero", this);
219  return SageBuilderAsm::buildMemoryReferenceExpression(SageBuilderAsm::buildAddExpression(RA(), RB()), NULL, t);
220  }
221 
222  /* There are 15 different forms of PowerPC instructions, but all are 32-bit (fixed length instruction set). */
223  SgAsmPowerpcInstruction* decode_I_formInstruction();
224  SgAsmPowerpcInstruction* decode_B_formInstruction();
225  SgAsmPowerpcInstruction* decode_SC_formInstruction();
226  SgAsmPowerpcInstruction* decode_DS_formInstruction();
227  SgAsmPowerpcInstruction* decode_X_formInstruction_00();
228  SgAsmPowerpcInstruction* decode_X_formInstruction_1F();
229  SgAsmPowerpcInstruction* decode_X_formInstruction_3F();
230  SgAsmPowerpcInstruction* decode_XL_formInstruction();
231  SgAsmPowerpcInstruction* decode_XS_formInstruction();
232  SgAsmPowerpcInstruction* decode_A_formInstruction_00();
233  SgAsmPowerpcInstruction* decode_A_formInstruction_04();
234  SgAsmPowerpcInstruction* decode_A_formInstruction_3B();
235  SgAsmPowerpcInstruction* decode_A_formInstruction_3F();
236  SgAsmPowerpcInstruction* decode_MD_formInstruction();
237  SgAsmPowerpcInstruction* decode_MDS_formInstruction();
238 
239  SgAsmIntegerValueExpression* makeBranchTarget( uint64_t targetAddr ) const;
240 
241  SgAsmPowerpcInstruction* disassemble();
242 
244  void init();
245 
247  void startInstruction(rose_addr_t start_va, uint32_t c) {
248  ip = start_va;
249  insn = c;
250  }
251 
252  /* Per-instruction data members (mostly set by startInstruction()) */
253  uint64_t ip;
254  uint32_t insn;
255 };
256 
257 } // namespace
258 } // namespace
259 
260 #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:42
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:83
virtual SgAsmInstruction * makeUnknownInstruction(const Exception &)
Makes an unknown instruction from an exception.