ROSE  0.11.96.0
DisassemblerM68k.h
1 /* Disassembly specific to Motorola architectures */
2 #ifndef ROSE_BinaryAnalysis_DisassemblerM68k_H
3 #define ROSE_BinaryAnalysis_DisassemblerM68k_H
4 #include <featureTests.h>
5 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
6 #include <Rose/BinaryAnalysis/Disassembler.h>
7 
8 #include <Rose/BinaryAnalysis/InstructionEnumsM68k.h>
9 #include "BitPattern.h"
10 
11 #include <boost/serialization/access.hpp>
12 #include <boost/serialization/base_object.hpp>
13 #include <boost/serialization/export.hpp>
14 #include <boost/serialization/split_member.hpp>
15 
16 namespace Rose {
17 namespace BinaryAnalysis {
18 
21 public:
22  // State mutated during the call to disassembleOne. Used internally.
23  struct State: boost::noncopyable { // noncopyable is so we don't accidentally pass it by value
25  rose_addr_t insn_va;
26  uint16_t iwords[11];
27  size_t niwords;
28  size_t niwords_used;
30  State()
31  : insn_va(0), niwords(0), niwords_used(0) {}
32  };
33 
34 public:
43  class M68k {
44  public:
45  M68k(const std::string &name, unsigned family, const BitPattern<uint16_t> &pattern)
46  : name(name), family(family), pattern(pattern) {}
47  virtual ~M68k() {}
48  std::string name; // for debugging; same as class name but without the "M68k_" prefix
49  unsigned family; // bitmask of M68kFamily bits
50  BitPattern<uint16_t> pattern; // bits that match
51  typedef DisassemblerM68k D;
52  virtual SgAsmM68kInstruction *operator()(State&, const D *d, unsigned w0) = 0;
53  };
54 
55 private:
56  M68kFamily family;
58  // The instruction disassembly table is an array indexed by the high-order nybble of the first 16-bit word of the
59  // instruction's pattern, the so-called "operator" bits. Since most instruction disassembler have invariant operator
60  // bits, we can divide the table into 16 entries for these invariant bits, and another entry (index 16) for the cases
61  // with a variable operator byte. Each of these 17 buckets is an unordered list of instruction disassemblers whose
62  // patterns we attempt to match one at a time (the insertion function checks that there are no ambiguities).
63  typedef std::list<M68k*> IdisList;
64  typedef std::vector<IdisList> IdisTable;
65  IdisTable idis_table;
66 
67 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
68 private:
69  friend class boost::serialization::access;
70 
71  template<class S>
72  void serialize_common(S &s, const unsigned /*version*/) {
73  s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Disassembler);
74  s & BOOST_SERIALIZATION_NVP(family);
75  //s & idis_table; -- not saved
76  }
77 
78  template<class S>
79  void save(S &s, const unsigned version) const {
80  serialize_common(s, version);
81  }
82 
83  template<class S>
84  void load(S &s, const unsigned version) {
85  serialize_common(s, version);
86  init();
87  }
88 
89  BOOST_SERIALIZATION_SPLIT_MEMBER();
90 #endif
91 
92 protected:
93  // undocumented constructor for serialization. The init() will be called by the serialization.
94  DisassemblerM68k()
95  : family(m68k_freescale_cpu32) {}
96 
97 public:
106  explicit DisassemblerM68k(M68kFamily family)
107  : family(family) {
108  init();
109  }
110  virtual DisassemblerM68k *clone() const override { return new DisassemblerM68k(*this); }
111  virtual bool canDisassemble(SgAsmGenericHeader*) const override;
112  virtual SgAsmInstruction *disassembleOne(const MemoryMap::Ptr&, rose_addr_t start_va,
113  AddressSet *successors=NULL) override;
115  virtual Unparser::BasePtr unparser() const override;
116 
117  typedef std::pair<SgAsmExpression*, SgAsmExpression*> ExpressionPair;
118 
122  M68k *find_idis(uint16_t *insn_bytes, size_t nbytes) const;
123 
126  void insert_idis(M68k*);
127 
129  void start_instruction(State &state, const MemoryMap::Ptr &map, rose_addr_t start_va) const{
130  state.map = map;
131  state.insn_va = start_va;
132  state.niwords = 0;
133  memset(state.iwords, 0, sizeof state.iwords);
134  state.niwords_used = 0;
135  }
136 
138  uint16_t instructionWord(State&, size_t n) const;
139 
141  size_t extensionWordsUsed(State&) const;
142 
144  SgAsmType *makeType(State&, M68kDataFormat) const;
145 
147  SgAsmRegisterReferenceExpression *makeDataRegister(State&, unsigned regnum, M68kDataFormat, size_t bit_offset=0) const;
148 
150  SgAsmRegisterReferenceExpression *makeAddressRegister(State&, unsigned regnum, M68kDataFormat, size_t bit_offset=0) const;
151 
155 
159 
163  size_t bit_offset=0) const;
164 
170  SgAsmRegisterNames *makeRegistersFromMask(State&, unsigned mask, M68kDataFormat fmt, bool reverse=false) const;
171 
177  SgAsmRegisterNames *makeFPRegistersFromMask(State&, unsigned mask, M68kDataFormat fmt, bool reverse=false) const;
178 
181 
184 
186  SgAsmRegisterReferenceExpression* makeColdFireControlRegister(State&, unsigned regnum) const;
187 
190 
193 
195  SgAsmRegisterReferenceExpression *makeMacAccumulatorRegister(State&, unsigned accumIndex) const;
196 
200  SgAsmRegisterReferenceExpression *makeFPRegister(State&, unsigned regnum) const;
201 
204 
206  SgAsmIntegerValueExpression *makeImmediateValue(State&, M68kDataFormat fmt, unsigned value) const;
207 
209  SgAsmIntegerValueExpression *makeImmediateExtension(State&, M68kDataFormat fmt, size_t ext_word_idx) const;
210 
217  SgAsmExpression *makeEffectiveAddress(State&, unsigned modreg, M68kDataFormat fmt, size_t ext_offset) const;
218  SgAsmExpression *makeEffectiveAddress(State&, unsigned mode, unsigned reg, M68kDataFormat fmt, size_t ext_offset) const;
224  SgAsmExpression *makeAddress(State&, SgAsmExpression *expr) const;
225 
228  ExpressionPair makeOffsetWidthPair(State&, unsigned extension_word) const;
229 
231  SgAsmM68kInstruction *makeInstruction(State&, M68kInstructionKind, const std::string &mnemonic,
232  SgAsmExpression *arg0=NULL, SgAsmExpression *arg1=NULL, SgAsmExpression *arg2=NULL,
233  SgAsmExpression *arg3=NULL, SgAsmExpression *arg4=NULL, SgAsmExpression *arg5=NULL,
234  SgAsmExpression *arg6=NULL) const;
235 
237  M68kFamily get_family() const { return family; }
238 
239 private:
240  void init();
241 };
242 
243 } // namespace
244 } // namespace
245 
246 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
247 BOOST_CLASS_EXPORT_KEY(Rose::BinaryAnalysis::DisassemblerM68k);
248 #endif
249 
250 #endif
251 #endif
Freescale CPU32 (similar to MC68020 w/out bitfield insns.
rose_addr_t insn_va
Address of instruction.
size_t niwords_used
High water number of instruction words used by instructionWord().
Base class for references to a machine register.
SgAsmRegisterReferenceExpression * makeRegister(RegisterDescriptor) const
Generic ways to make a register.
M68kInstructionKind
M68k instruction types.
virtual Unparser::BasePtr unparser() const override
Unparser.
SgAsmRegisterNames * makeRegistersFromMask(State &, unsigned mask, M68kDataFormat fmt, bool reverse=false) const
Create a list of data and/or address registers.
Base class for machine instructions.
SgAsmRegisterNames * makeFPRegistersFromMask(State &, unsigned mask, M68kDataFormat fmt, bool reverse=false) const
Create a list of floating-point data registers.
virtual DisassemblerM68k * clone() const override
Creates a new copy of a disassembler.
void start_instruction(State &state, const MemoryMap::Ptr &map, rose_addr_t start_va) const
Called by disassembleOne() to initialize the disassembler state for the next instruction.
Main namespace for the ROSE library.
virtual SgAsmInstruction * disassembleOne(const MemoryMap::Ptr &, rose_addr_t start_va, AddressSet *successors=NULL) override
This is the lowest level disassembly function and is implemented in the architecture-specific subclas...
SgAsmRegisterReferenceExpression * makeFPRegister(State &, unsigned regnum) const
Create a floating point register.
SgAsmMemoryReferenceExpression * makeAddressRegisterPostIncrement(State &, unsigned regnum, M68kDataFormat fmt) const
Make a memory reference expression using an address register in post-increment mode.
SgAsmRegisterReferenceExpression * makeStatusRegister(State &) const
Create a reference to the status register.
M68kDataFormat
M68k data formats for floating-point operations.
SgAsmRegisterReferenceExpression * makeConditionCodeRegister(State &) const
Create a reference to the condition code register.
void insert_idis(M68k *)
Insert an instruction-specific disassembler.
SgAsmRegisterReferenceExpression * makeColdFireControlRegister(State &, unsigned regnum) const
Create control register for ColdFire cpu.
SgAsmRegisterReferenceExpression * makeProgramCounter(State &) const
Create a reference to the program counter register.
Disassembler for Motorola M68k-based instruction set architectures.
SgAsmRegisterReferenceExpression * makeMacRegister(State &, M68kMacRegister) const
Create a MAC register reference expression.
SgAsmIntegerValueExpression * makeImmediateValue(State &, M68kDataFormat fmt, unsigned value) const
Create an integer expression from a specified value.
Interface for disassembling a single instruction.
Reference to memory locations.
M68kFamily
Members of the Motorola Coldfire family of m68k processors.
SgAsmExpression * makeAddress(State &, SgAsmExpression *expr) const
Converts a memory-reference expression to an address.
An ordered list of registers.
Base class for container file headers.
SgAsmType * makeType(State &, M68kDataFormat) const
Create a ROSE data type for m68k data format.
Base class for integer values.
Describes (part of) a physical CPU register.
size_t extensionWordsUsed(State &) const
Returns number of instruction words referenced so far in the current instruction. ...
SgAsmExpression * makeEffectiveAddress(State &, unsigned modreg, M68kDataFormat fmt, size_t ext_offset) const
Create an expression for m68k "x" or "y".
ExpressionPair makeOffsetWidthPair(State &, unsigned extension_word) const
Create an offset width pair from an extension word.
M68kMacRegister
M68k MAC registers.
MemoryMap::Ptr map
Map from which to read instruction words.
SgAsmMemoryReferenceExpression * makeAddressRegisterPreDecrement(State &, unsigned regnum, M68kDataFormat fmt) const
Make a memory reference expression using an address register in pre-decrement mode.
size_t niwords
Number of instruction words read.
Base class for expressions.
virtual SgAsmInstruction * makeUnknownInstruction(const Disassembler::Exception &) override
Makes an unknown instruction from an exception.
SgAsmRegisterReferenceExpression * makeDataAddressRegister(State &, unsigned regnum, M68kDataFormat fmt, size_t bit_offset=0) const
Create either a data or address register reference expression.
Base class for binary types.
SgAsmRegisterReferenceExpression * makeMacAccumulatorRegister(State &, unsigned accumIndex) const
Create a MAC accumulator register.
SgAsmRegisterReferenceExpression * makeAddressRegister(State &, unsigned regnum, M68kDataFormat, size_t bit_offset=0) const
Create an address register reference expression.
DisassemblerM68k(M68kFamily family)
Constructor for a specific family.
SgAsmM68kInstruction * makeInstruction(State &, M68kInstructionKind, const std::string &mnemonic, SgAsmExpression *arg0=NULL, SgAsmExpression *arg1=NULL, SgAsmExpression *arg2=NULL, SgAsmExpression *arg3=NULL, SgAsmExpression *arg4=NULL, SgAsmExpression *arg5=NULL, SgAsmExpression *arg6=NULL) const
Build an instruction.
uint16_t instructionWord(State &, size_t n) const
Return the Nth instruction word.
M68kFamily get_family() const
Returns ISA family specified in constructor.
virtual bool canDisassemble(SgAsmGenericHeader *) const override
Predicate determining the suitability of a disassembler for a specific file header.
Exception thrown by the disassemblers.
Definition: Disassembler.h:53
SgAsmRegisterReferenceExpression * makeDataRegister(State &, unsigned regnum, M68kDataFormat, size_t bit_offset=0) const
Create a data register reference expression.
M68k * find_idis(uint16_t *insn_bytes, size_t nbytes) const
Find an instruction-specific disassembler.
Virtual base class for instruction disassemblers.
Definition: Disassembler.h:50
SgAsmIntegerValueExpression * makeImmediateExtension(State &, M68kDataFormat fmt, size_t ext_word_idx) const
Create an integer expression from extension words.
uint16_t iwords[11]
Instruction words.