ROSE  0.11.83.1
DisassemblerCil.h
1 /* Disassembly specific to Motorola architectures */
2 #ifndef ROSE_BinaryAnalysis_DisassemblerCil_H
3 #define ROSE_BinaryAnalysis_DisassemblerCil_H
4 #include <featureTests.h>
5 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
6 #include <Rose/BinaryAnalysis/Disassembler.h>
7 
8 #include <Rose/BinaryAnalysis/InstructionEnumsCil.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 Cil {
44  public:
45  Cil(const std::string &name, unsigned family, const BitPattern<uint16_t> &pattern)
46  : name(name), family(family), pattern(pattern) {}
47  virtual ~Cil() {}
48  std::string name; // for debugging; same as class name but without the "Cil_" prefix
49  unsigned family; // bitmask of CilFamily bits
50  BitPattern<uint16_t> pattern; // bits that match
51  typedef DisassemblerCil D;
52  virtual SgAsmCilInstruction *operator()(State&, const D *d, unsigned w0) = 0;
53  };
54 
55 private:
56  CilFamily 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<Cil*> 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 public:
93 // protected:
94  // undocumented constructor for serialization. The init() will be called by the serialization.
95  DisassemblerCil()
96  : family(Cil_family) {}
97 
98 public:
99 #if 0
100 
108  explicit DisassemblerCil(CilFamily family)
109  : family(family) {
110  init();
111  }
112 #endif
113 
114  virtual DisassemblerCil *clone() const override { return new DisassemblerCil(*this); }
115  virtual bool canDisassemble(SgAsmGenericHeader*) const override;
116  virtual SgAsmInstruction *disassembleOne(const MemoryMap::Ptr&, rose_addr_t start_va,
117  AddressSet *successors=NULL) override;
119 
120  // DQ (11/3/2021): Simpler way to build unknown instructions.
121  virtual SgAsmCilInstruction* makeUnknownInstruction(rose_addr_t address, uint8_t opt_code);
122 
123  virtual Unparser::BasePtr unparser() const override;
124 
125  typedef std::pair<SgAsmExpression*, SgAsmExpression*> ExpressionPair;
126 
130  Cil *find_idis(uint16_t *insn_bytes, size_t nbytes) const;
131 
134  void insert_idis(Cil*);
135 
137  void start_instruction(State &state, const MemoryMap::Ptr &map, rose_addr_t start_va) const{
138  state.map = map;
139  state.insn_va = start_va;
140  state.niwords = 0;
141  memset(state.iwords, 0, sizeof state.iwords);
142  state.niwords_used = 0;
143  }
144 
146  uint16_t instructionWord(State&, size_t n) const;
147 
149  size_t extensionWordsUsed(State&) const;
150 
152  SgAsmType *makeType(State&, CilDataFormat) const;
153 
155  SgAsmRegisterReferenceExpression *makeDataRegister(State&, unsigned regnum, CilDataFormat, size_t bit_offset=0) const;
156 
158  SgAsmRegisterReferenceExpression *makeAddressRegister(State&, unsigned regnum, CilDataFormat, size_t bit_offset=0) const;
159 
163 
167 
171  size_t bit_offset=0) const;
172 
178  SgAsmRegisterNames *makeRegistersFromMask(State&, unsigned mask, CilDataFormat fmt, bool reverse=false) const;
179 
185  SgAsmRegisterNames *makeFPRegistersFromMask(State&, unsigned mask, CilDataFormat fmt, bool reverse=false) const;
186 
189 
192 
194  SgAsmRegisterReferenceExpression* makeColdFireControlRegister(State&, unsigned regnum) const;
195 
198 
201 
203  SgAsmRegisterReferenceExpression *makeMacAccumulatorRegister(State&, unsigned accumIndex) const;
204 
208  SgAsmRegisterReferenceExpression *makeFPRegister(State&, unsigned regnum) const;
209 
212 
214  SgAsmIntegerValueExpression *makeImmediateValue(State&, CilDataFormat fmt, unsigned value) const;
215 
217  SgAsmIntegerValueExpression *makeImmediateExtension(State&, CilDataFormat fmt, size_t ext_word_idx) const;
218 
225  SgAsmExpression *makeEffectiveAddress(State&, unsigned modreg, CilDataFormat fmt, size_t ext_offset) const;
226  SgAsmExpression *makeEffectiveAddress(State&, unsigned mode, unsigned reg, CilDataFormat fmt, size_t ext_offset) const;
232  SgAsmExpression *makeAddress(State&, SgAsmExpression *expr) const;
233 
236  ExpressionPair makeOffsetWidthPair(State&, unsigned extension_word) const;
237 
239  // DQ (10/20/2021): We don't need the State &state function parameter for .Cil
240  // SgAsmCilInstruction *makeInstruction(State&, CilInstructionKind, const std::string &mnemonic,
241  // SgAsmExpression *arg0=NULL, SgAsmExpression *arg1=NULL, SgAsmExpression *arg2=NULL,
242  // SgAsmExpression *arg3=NULL, SgAsmExpression *arg4=NULL, SgAsmExpression *arg5=NULL,
243  // SgAsmExpression *arg6=NULL) const;
244  SgAsmCilInstruction *makeInstruction(rose_addr_t start_va, CilInstructionKind, const std::string &mnemonic,
245  SgAsmExpression *arg0=NULL, SgAsmExpression *arg1=NULL, SgAsmExpression *arg2=NULL,
246  SgAsmExpression *arg3=NULL, SgAsmExpression *arg4=NULL, SgAsmExpression *arg5=NULL,
247  SgAsmExpression *arg6=NULL, SgAsmExpression *arg7=NULL) const;
248 
250  CilFamily get_family() const { return family; }
251 
252 private:
253  void init();
254 };
255 
256 } // namespace
257 } // namespace
258 
259 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
260 BOOST_CLASS_EXPORT_KEY(Rose::BinaryAnalysis::DisassemblerCil);
261 #endif
262 
263 #endif
264 #endif
SgAsmRegisterReferenceExpression * makeStatusRegister(State &) const
Create a reference to the status register.
SgAsmRegisterReferenceExpression * makeConditionCodeRegister(State &) const
Create a reference to the condition code register.
SgAsmRegisterReferenceExpression * makeColdFireControlRegister(State &, unsigned regnum) const
Create control register for ColdFire cpu.
Base class for references to a machine register.
CilFamily
Members of the Motorola Coldfire family of m68k processors.
virtual DisassemblerCil * clone() const override
Creates a new copy of a disassembler.
SgAsmType * makeType(State &, CilDataFormat) const
Create a ROSE data type for Cil data format.
Base class for machine instructions.
CilMacRegister
CIL MAC registers.
SgAsmRegisterReferenceExpression * makeRegister(RegisterDescriptor) const
Generic ways to make a register.
SgAsmIntegerValueExpression * makeImmediateValue(State &, CilDataFormat fmt, unsigned value) const
Create an integer expression from a specified value.
MemoryMap::Ptr map
Map from which to read instruction words.
CilInstructionKind
CIL instruction types.
virtual bool canDisassemble(SgAsmGenericHeader *) const override
Predicate determining the suitability of a disassembler for a specific file header.
Main namespace for the ROSE library.
SgAsmMemoryReferenceExpression * makeAddressRegisterPostIncrement(State &, unsigned regnum, CilDataFormat fmt) const
Make a memory reference expression using an address register in post-increment mode.
size_t niwords_used
High water number of instruction words used by instructionWord().
SgAsmRegisterNames * makeFPRegistersFromMask(State &, unsigned mask, CilDataFormat fmt, bool reverse=false) const
Create a list of floating-point data registers.
SgAsmRegisterReferenceExpression * makeProgramCounter(State &) const
Create a reference to the program counter register.
SgAsmCilInstruction * makeInstruction(rose_addr_t start_va, CilInstructionKind, 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, SgAsmExpression *arg7=NULL) const
Build an instruction.
virtual SgAsmInstruction * makeUnknownInstruction(const Disassembler::Exception &) override
Makes an unknown instruction from an exception.
SgAsmRegisterNames * makeRegistersFromMask(State &, unsigned mask, CilDataFormat fmt, bool reverse=false) const
Create a list of data and/or address registers.
Reference to memory locations.
Cil * find_idis(uint16_t *insn_bytes, size_t nbytes) const
Find an instruction-specific disassembler.
An ordered list of registers.
Base class for container file headers.
CilDataFormat
M68k data formats for floating-point operations.
Base class for integer values.
CilFamily get_family() const
Returns ISA family specified in constructor.
uint16_t iwords[11]
Instruction words.
Describes (part of) a physical CPU register.
SgAsmRegisterReferenceExpression * makeMacAccumulatorRegister(State &, unsigned accumIndex) const
Create a MAC accumulator register.
SgAsmRegisterReferenceExpression * makeFPRegister(State &, unsigned regnum) const
Create a floating point register.
SgAsmExpression * makeEffectiveAddress(State &, unsigned modreg, CilDataFormat fmt, size_t ext_offset) const
Create an expression for Cil "x" or "y".
SgAsmRegisterReferenceExpression * makeDataRegister(State &, unsigned regnum, CilDataFormat, size_t bit_offset=0) const
Create a data register reference expression.
size_t extensionWordsUsed(State &) const
Returns number of instruction words referenced so far in the current instruction. ...
size_t niwords
Number of instruction words read.
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.
ExpressionPair makeOffsetWidthPair(State &, unsigned extension_word) const
Create an offset width pair from an extension word.
Base class for expressions.
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...
All CIL Instruction sets.
virtual Unparser::BasePtr unparser() const override
Unparser.
SgAsmRegisterReferenceExpression * makeDataAddressRegister(State &, unsigned regnum, CilDataFormat fmt, size_t bit_offset=0) const
Create either a data or address register reference expression.
Disassembler for CIL instruction set architectures.
uint16_t instructionWord(State &, size_t n) const
Return the Nth instruction word.
rose_addr_t insn_va
Address of instruction.
Base class for binary types.
SgAsmRegisterReferenceExpression * makeMacRegister(State &, CilMacRegister) const
Create a MAC register reference expression.
Interface for disassembling a single instruction.
SgAsmRegisterReferenceExpression * makeAddressRegister(State &, unsigned regnum, CilDataFormat, size_t bit_offset=0) const
Create an address register reference expression.
SgAsmExpression * makeAddress(State &, SgAsmExpression *expr) const
Converts a memory-reference expression to an address.
Exception thrown by the disassemblers.
Definition: Disassembler.h:53
SgAsmIntegerValueExpression * makeImmediateExtension(State &, CilDataFormat fmt, size_t ext_word_idx) const
Create an integer expression from extension words.
void insert_idis(Cil *)
Insert an instruction-specific disassembler.
Virtual base class for instruction disassemblers.
Definition: Disassembler.h:50
SgAsmMemoryReferenceExpression * makeAddressRegisterPreDecrement(State &, unsigned regnum, CilDataFormat fmt) const
Make a memory reference expression using an address register in pre-decrement mode.