ROSE  0.11.98.0
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/Base.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:
24 
25  // State mutated during the call to disassembleOne. Used internally.
26  struct State: boost::noncopyable { // noncopyable is so we don't accidentally pass it by value
28  rose_addr_t insn_va;
29  uint16_t iwords[11];
30  size_t niwords;
31  size_t niwords_used;
33  State()
34  : insn_va(0), niwords(0), niwords_used(0) {}
35  };
36 
37 public:
46  class Cil {
47  public:
48  Cil(const std::string &name, unsigned family, const BitPattern<uint16_t> &pattern)
49  : name(name), family(family), pattern(pattern) {}
50  virtual ~Cil() {}
51  std::string name; // for debugging; same as class name but without the "Cil_" prefix
52  unsigned family; // bitmask of CilFamily bits
53  BitPattern<uint16_t> pattern; // bits that match
54  typedef DisassemblerCil D;
55  virtual SgAsmCilInstruction *operator()(State&, const D *d, unsigned w0) = 0;
56  };
57 
58 private:
59  CilFamily family;
61  // The instruction disassembly table is an array indexed by the high-order nybble of the first 16-bit word of the
62  // instruction's pattern, the so-called "operator" bits. Since most instruction disassembler have invariant operator
63  // bits, we can divide the table into 16 entries for these invariant bits, and another entry (index 16) for the cases
64  // with a variable operator byte. Each of these 17 buckets is an unordered list of instruction disassemblers whose
65  // patterns we attempt to match one at a time (the insertion function checks that there are no ambiguities).
66  typedef std::list<Cil*> IdisList;
67  typedef std::vector<IdisList> IdisTable;
68  IdisTable idis_table;
69 
70 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
71 private:
72  friend class boost::serialization::access;
73 
74  template<class S>
75  void serialize_common(S &s, const unsigned /*version*/) {
76  s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Disassembler::Base);
77  s & BOOST_SERIALIZATION_NVP(family);
78  //s & idis_table; -- not saved
79  }
80 
81  template<class S>
82  void save(S &s, const unsigned version) const {
83  serialize_common(s, version);
84  }
85 
86  template<class S>
87  void load(S &s, const unsigned version) {
88  serialize_common(s, version);
89  init();
90  }
91 
92  BOOST_SERIALIZATION_SPLIT_MEMBER();
93 #endif
94 
95 protected:
96  // undocumented constructor for serialization. The init() will be called by the serialization.
97  DisassemblerCil()
98  : family(Cil_family) {}
99 
100 #if 0
101 
109  explicit DisassemblerCil(CilFamily family)
110  : family(family) {
111  init();
112  }
113 #endif
114 
115 public:
117  static Ptr instance();
118 
119  virtual Disassembler::BasePtr clone() const override;
120  virtual bool canDisassemble(SgAsmGenericHeader*) const override;
121  virtual SgAsmInstruction *disassembleOne(const MemoryMap::Ptr&, rose_addr_t start_va,
122  AddressSet *successors=NULL) override;
123  virtual SgAsmInstruction *makeUnknownInstruction(const Disassembler::Exception&) override;
124 
125  // DQ (11/3/2021): Simpler way to build unknown instructions.
126  virtual SgAsmCilInstruction* makeUnknownInstruction(rose_addr_t address, uint8_t opt_code);
127 
128  virtual Unparser::BasePtr unparser() const override;
129 
130  typedef std::pair<SgAsmExpression*, SgAsmExpression*> ExpressionPair;
131 
135  Cil *find_idis(uint16_t *insn_bytes, size_t nbytes) const;
136 
139  void insert_idis(Cil*);
140 
142  void start_instruction(State &state, const MemoryMap::Ptr &map, rose_addr_t start_va) const{
143  state.map = map;
144  state.insn_va = start_va;
145  state.niwords = 0;
146  memset(state.iwords, 0, sizeof state.iwords);
147  state.niwords_used = 0;
148  }
149 
151  uint16_t instructionWord(State&, size_t n) const;
152 
154  size_t extensionWordsUsed(State&) const;
155 
157  SgAsmType *makeType(State&, CilDataFormat) const;
158 
160  SgAsmRegisterReferenceExpression *makeDataRegister(State&, unsigned regnum, CilDataFormat, size_t bit_offset=0) const;
161 
163  SgAsmRegisterReferenceExpression *makeAddressRegister(State&, unsigned regnum, CilDataFormat, size_t bit_offset=0) const;
164 
167  SgAsmMemoryReferenceExpression *makeAddressRegisterPreDecrement(State&, unsigned regnum, CilDataFormat fmt) const;
168 
171  SgAsmMemoryReferenceExpression *makeAddressRegisterPostIncrement(State&, unsigned regnum, CilDataFormat fmt) const;
172 
175  SgAsmRegisterReferenceExpression *makeDataAddressRegister(State&, unsigned regnum, CilDataFormat fmt,
176  size_t bit_offset=0) const;
177 
183  SgAsmRegisterNames *makeRegistersFromMask(State&, unsigned mask, CilDataFormat fmt, bool reverse=false) const;
184 
190  SgAsmRegisterNames *makeFPRegistersFromMask(State&, unsigned mask, CilDataFormat fmt, bool reverse=false) const;
191 
194 
197 
199  SgAsmRegisterReferenceExpression* makeColdFireControlRegister(State&, unsigned regnum) const;
200 
203 
205  SgAsmRegisterReferenceExpression *makeMacRegister(State&, CilMacRegister) const;
206 
208  SgAsmRegisterReferenceExpression *makeMacAccumulatorRegister(State&, unsigned accumIndex) const;
209 
213  SgAsmRegisterReferenceExpression *makeFPRegister(State&, unsigned regnum) const;
214 
217 
219  SgAsmIntegerValueExpression *makeImmediateValue(State&, CilDataFormat fmt, unsigned value) const;
220 
222  SgAsmIntegerValueExpression *makeImmediateExtension(State&, CilDataFormat fmt, size_t ext_word_idx) const;
223 
230  SgAsmExpression *makeEffectiveAddress(State&, unsigned modreg, CilDataFormat fmt, size_t ext_offset) const;
231  SgAsmExpression *makeEffectiveAddress(State&, unsigned mode, unsigned reg, CilDataFormat fmt, size_t ext_offset) const;
237  SgAsmExpression *makeAddress(State&, SgAsmExpression *expr) const;
238 
241  ExpressionPair makeOffsetWidthPair(State&, unsigned extension_word) const;
242 
244  // DQ (10/20/2021): We don't need the State &state function parameter for .Cil
245  // SgAsmCilInstruction *makeInstruction(State&, CilInstructionKind, const std::string &mnemonic,
246  // SgAsmExpression *arg0=NULL, SgAsmExpression *arg1=NULL, SgAsmExpression *arg2=NULL,
247  // SgAsmExpression *arg3=NULL, SgAsmExpression *arg4=NULL, SgAsmExpression *arg5=NULL,
248  // SgAsmExpression *arg6=NULL) const;
249  SgAsmCilInstruction *makeInstruction(rose_addr_t start_va, CilInstructionKind, const std::string &mnemonic,
250  SgAsmExpression *arg0=NULL, SgAsmExpression *arg1=NULL, SgAsmExpression *arg2=NULL,
251  SgAsmExpression *arg3=NULL, SgAsmExpression *arg4=NULL, SgAsmExpression *arg5=NULL,
252  SgAsmExpression *arg6=NULL, SgAsmExpression *arg7=NULL) const;
253 
255  CilFamily get_family() const { return family; }
256 
257 private:
258  void init();
259 };
260 
261 } // namespace
262 } // namespace
263 
264 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
265 BOOST_CLASS_EXPORT_KEY(Rose::BinaryAnalysis::DisassemblerCil);
266 #endif
267 
268 #endif
269 #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.
SgAsmType * makeType(State &, CilDataFormat) const
Create a ROSE data type for Cil data format.
Base class for machine instructions.
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.
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.
Reference-counting intrusive smart pointer.
Definition: SharedPointer.h:68
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.
MemoryMapPtr Ptr
Reference counting pointer.
Definition: MemoryMap.h:115
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.
Sawyer::SharedPointer< DisassemblerCil > Ptr
Reference counting pointer.
Base class for container file headers.
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.
Binary analysis.
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...
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.
static Ptr instance()
Allocating constructor.
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.
virtual Disassembler::BasePtr clone() const override
Creates a new copy of a disassembler.
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.
Sawyer::SharedPointer< Base > BasePtr
Reference counted pointer for disassemblers.
Virtual base class for instruction disassemblers.
SgAsmMemoryReferenceExpression * makeAddressRegisterPreDecrement(State &, unsigned regnum, CilDataFormat fmt) const
Make a memory reference expression using an address register in pre-decrement mode.