ROSE  0.9.9.109
DisassemblerM68k.h
1 /* Disassembly specific to Motorola architectures */
2 #ifndef ROSE_DisassemblerM68k_H
3 #define ROSE_DisassemblerM68k_H
4 
5 #include "Disassembler.h"
6 #include "InstructionEnumsM68k.h"
7 #include "BitPattern.h"
8 
9 #include <boost/serialization/access.hpp>
10 #include <boost/serialization/base_object.hpp>
11 #include <boost/serialization/export.hpp>
12 #include <boost/serialization/split_member.hpp>
13 
14 namespace Rose {
15 namespace BinaryAnalysis {
16 
19 public:
28  class M68k {
29  public:
30  M68k(const std::string &name, unsigned family, const BitPattern<uint16_t> &pattern)
31  : name(name), family(family), pattern(pattern) {}
32  virtual ~M68k() {}
33  std::string name; // for debugging; same as class name but without the "M68k_" prefix
34  unsigned family; // bitmask of M68kFamily bits
35  BitPattern<uint16_t> pattern; // bits that match
36  typedef DisassemblerM68k D;
37  virtual SgAsmM68kInstruction *operator()(D *d, unsigned w0) = 0;
38  };
39 
40 private:
41  M68kFamily family;
42  MemoryMap::Ptr map;
43  rose_addr_t insn_va;
44  uint16_t iwords[11];
45  size_t niwords;
46  size_t niwords_used;
48  // The instruction disassembly table is an array indexed by the high-order nybble of the first 16-bit word of the
49  // instruction's pattern, the so-called "operator" bits. Since most instruction disassembler have invariant operator
50  // bits, we can divide the table into 16 entries for these invariant bits, and another entry (index 16) for the cases
51  // with a variable operator byte. Each of these 17 buckets is an unordered list of instruction disassemblers whose
52  // patterns we attempt to match one at a time (the insertion function checks that there are no ambiguities).
53  typedef std::list<M68k*> IdisList;
54  typedef std::vector<IdisList> IdisTable;
55  IdisTable idis_table;
56 
57 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
58 private:
59  friend class boost::serialization::access;
60 
61  template<class S>
62  void serialize_common(S &s, const unsigned version) {
63  s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Disassembler);
64  s & BOOST_SERIALIZATION_NVP(family);
65  s & BOOST_SERIALIZATION_NVP(map);
66  s & BOOST_SERIALIZATION_NVP(insn_va);
67  s & BOOST_SERIALIZATION_NVP(iwords);
68  s & BOOST_SERIALIZATION_NVP(niwords);
69  s & BOOST_SERIALIZATION_NVP(niwords_used);
70  //s & idis_table; -- not saved
71  }
72 
73  template<class S>
74  void save(S &s, const unsigned version) const {
75  serialize_common(s, version);
76  }
77 
78  template<class S>
79  void load(S &s, const unsigned version) {
80  serialize_common(s, version);
81  init();
82  }
83 
84  BOOST_SERIALIZATION_SPLIT_MEMBER();
85 #endif
86 
87 protected:
88  // undocumented constructor for serialization. The init() will be called by the serialization.
89  DisassemblerM68k()
90  : family(m68k_freescale_cpu32), insn_va(0), niwords(0), niwords_used(0) {}
91 
92 public:
101  explicit DisassemblerM68k(M68kFamily family)
102  : family(family), insn_va(0), niwords(0), niwords_used(0) {
103  init();
104  }
105  virtual DisassemblerM68k *clone() const ROSE_OVERRIDE { return new DisassemblerM68k(*this); }
106  virtual bool canDisassemble(SgAsmGenericHeader*) const ROSE_OVERRIDE;
107  virtual SgAsmInstruction *disassembleOne(const MemoryMap::Ptr&, rose_addr_t start_va,
108  AddressSet *successors=NULL) ROSE_OVERRIDE;
109  virtual SgAsmInstruction *makeUnknownInstruction(const Disassembler::Exception&) ROSE_OVERRIDE;
110  virtual Unparser::BasePtr unparser() const ROSE_OVERRIDE;
111 
112  typedef std::pair<SgAsmExpression*, SgAsmExpression*> ExpressionPair;
113 
117  M68k *find_idis(uint16_t *insn_bytes, size_t nbytes) const;
118 
121  void insert_idis(M68k*);
122 
124  void start_instruction(const MemoryMap::Ptr &map, rose_addr_t start_va) {
125  this->map = map;
126  insn_va = start_va;
127  niwords = 0;
128  memset(iwords, 0, sizeof iwords);
129  niwords_used = 0;
130  }
131 
133  uint16_t instructionWord(size_t n);
134 
136  size_t extensionWordsUsed() const;
137 
139  SgAsmType *makeType(M68kDataFormat);
140 
142  SgAsmRegisterReferenceExpression *makeDataRegister(unsigned regnum, M68kDataFormat, size_t bit_offset=0);
143 
145  SgAsmRegisterReferenceExpression *makeAddressRegister(unsigned regnum, M68kDataFormat, size_t bit_offset=0);
146 
149  SgAsmMemoryReferenceExpression *makeAddressRegisterPreDecrement(unsigned regnum, M68kDataFormat fmt);
150 
153  SgAsmMemoryReferenceExpression *makeAddressRegisterPostIncrement(unsigned regnum, M68kDataFormat fmt);
154 
157  SgAsmRegisterReferenceExpression *makeDataAddressRegister(unsigned regnum, M68kDataFormat fmt, size_t bit_offset=0);
158 
164  SgAsmRegisterNames *makeRegistersFromMask(unsigned mask, M68kDataFormat fmt, bool reverse=false);
165 
171  SgAsmRegisterNames *makeFPRegistersFromMask(unsigned mask, M68kDataFormat fmt, bool reverse=false);
172 
175 
178 
181 
184 
187 
190 
195 
198 
200  SgAsmIntegerValueExpression *makeImmediateValue(M68kDataFormat fmt, unsigned value);
201 
203  SgAsmIntegerValueExpression *makeImmediateExtension(M68kDataFormat fmt, size_t ext_word_idx);
204 
211  SgAsmExpression *makeEffectiveAddress(unsigned modreg, M68kDataFormat fmt, size_t ext_offset);
212  SgAsmExpression *makeEffectiveAddress(unsigned mode, unsigned reg, M68kDataFormat fmt, size_t ext_offset);
219 
222  ExpressionPair makeOffsetWidthPair(unsigned extension_word);
223 
225  SgAsmM68kInstruction *makeInstruction(M68kInstructionKind, const std::string &mnemonic,
226  SgAsmExpression *arg0=NULL, SgAsmExpression *arg1=NULL, SgAsmExpression *arg2=NULL,
227  SgAsmExpression *arg3=NULL, SgAsmExpression *arg4=NULL, SgAsmExpression *arg5=NULL,
228  SgAsmExpression *arg6=NULL);
229 
231  rose_addr_t get_insn_va() const { return insn_va; }
232 
234  M68kFamily get_family() const { return family; }
235 
236 private:
237  void init();
238 };
239 
240 } // namespace
241 } // namespace
242 
243 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
244 BOOST_CLASS_EXPORT_KEY(Rose::BinaryAnalysis::DisassemblerM68k);
245 #endif
246 
247 #endif
virtual Unparser::BasePtr unparser() const ROSE_OVERRIDE
Unparser.
uint16_t instructionWord(size_t n)
Return the Nth instruction word.
Base class for references to a machine register.
SgAsmRegisterReferenceExpression * makeMacRegister(M68kMacRegister)
Create a MAC register reference expression.
rose_addr_t get_insn_va() const
Return the address of the instruction we are disassembling.
Base class for machine instructions.
virtual SgAsmInstruction * disassembleOne(const MemoryMap::Ptr &, rose_addr_t start_va, AddressSet *successors=NULL) ROSE_OVERRIDE
This is the lowest level disassembly function and is implemented in the architecture-specific subclas...
SgAsmRegisterReferenceExpression * makeColdFireControlRegister(unsigned regnum)
Create control register for ColdFire cpu.
STL namespace.
ExpressionPair makeOffsetWidthPair(unsigned extension_word)
Create an offset width pair from an extension word.
Main namespace for the ROSE library.
SgAsmExpression * makeAddress(SgAsmExpression *expr)
Converts a memory-reference expression to an address.
Describes (part of) a physical CPU register.
virtual bool canDisassemble(SgAsmGenericHeader *) const ROSE_OVERRIDE
Predicate determining the suitability of a disassembler for a specific file header.
SgAsmRegisterReferenceExpression * makeStatusRegister()
Create a reference to the status register.
void insert_idis(M68k *)
Insert an instruction-specific disassembler.
SgAsmRegisterReferenceExpression * makeMacAccumulatorRegister(unsigned accumIndex)
Create a MAC accumulator register.
SgAsmMemoryReferenceExpression * makeAddressRegisterPostIncrement(unsigned regnum, M68kDataFormat fmt)
Make a memory reference expression using an address register in post-increment mode.
Disassembler for Motorola M68k-based instruction set architectures.
SgAsmIntegerValueExpression * makeImmediateExtension(M68kDataFormat fmt, size_t ext_word_idx)
Create an integer expression from extension words.
Interface for disassembling a single instruction.
Reference to memory locations.
An ordered list of registers.
SgAsmMemoryReferenceExpression * makeAddressRegisterPreDecrement(unsigned regnum, M68kDataFormat fmt)
Make a memory reference expression using an address register in pre-decrement mode.
Base class for container file headers.
Base class for integer values.
SgAsmIntegerValueExpression * makeImmediateValue(M68kDataFormat fmt, unsigned value)
Create an integer expression from a specified value.
An efficient mapping from an address space to stored data.
Definition: MemoryMap.h:96
SgAsmM68kInstruction * makeInstruction(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)
Build an instruction.
SgAsmRegisterNames * makeFPRegistersFromMask(unsigned mask, M68kDataFormat fmt, bool reverse=false)
Create a list of floating-point data registers.
Base class for expressions.
SgAsmRegisterReferenceExpression * makeDataAddressRegister(unsigned regnum, M68kDataFormat fmt, size_t bit_offset=0)
Create either a data or address register reference expression.
SgAsmRegisterReferenceExpression * makeConditionCodeRegister()
Create a reference to the condition code register.
SgAsmRegisterNames * makeRegistersFromMask(unsigned mask, M68kDataFormat fmt, bool reverse=false)
Create a list of data and/or address registers.
Base class for binary types.
SgAsmRegisterReferenceExpression * makeRegister(RegisterDescriptor)
Generic ways to make a register.
SgAsmRegisterReferenceExpression * makeProgramCounter()
Create a reference to the program counter register.
DisassemblerM68k(M68kFamily family)
Constructor for a specific family.
void start_instruction(const MemoryMap::Ptr &map, rose_addr_t start_va)
Called by disassembleOne() to initialize the disassembler state for the next instruction.
M68kFamily get_family() const
Returns ISA family specified in constructor.
SgAsmRegisterReferenceExpression * makeDataRegister(unsigned regnum, M68kDataFormat, size_t bit_offset=0)
Create a data register reference expression.
virtual SgAsmInstruction * makeUnknownInstruction(const Disassembler::Exception &) ROSE_OVERRIDE
Makes an unknown instruction from an exception.
SgAsmRegisterReferenceExpression * makeAddressRegister(unsigned regnum, M68kDataFormat, size_t bit_offset=0)
Create an address register reference expression.
virtual DisassemblerM68k * clone() const ROSE_OVERRIDE
Creates a new copy of a disassembler.
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:41
SgAsmExpression * makeEffectiveAddress(unsigned modreg, M68kDataFormat fmt, size_t ext_offset)
Create an expression for m68k "x" or "y".
size_t extensionWordsUsed() const
Returns number of instruction words referenced so far in the current instruction. ...
SgAsmRegisterReferenceExpression * makeFPRegister(unsigned regnum)
Create a floating point register.
std::set< rose_addr_t > AddressSet
An AddressSet contains virtual addresses (alternatively, relative virtual addresses) for such things ...
Definition: Disassembler.h:82
SgAsmType * makeType(M68kDataFormat)
Create a ROSE data type for m68k data format.