ROSE  0.11.50.0
DispatcherAarch64.h
1 #ifndef ROSE_BinaryAnalysis_InstructionSemantics2_DispatcherAarch64_H
2 #define ROSE_BinaryAnalysis_InstructionSemantics2_DispatcherAarch64_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_ASM_AARCH64
5 
6 #include <Rose/BinaryAnalysis/InstructionSemantics2/BaseSemantics.h>
7 
8 #include <boost/serialization/access.hpp>
9 #include <boost/serialization/base_object.hpp>
10 #include <boost/serialization/export.hpp>
11 #include <boost/serialization/split_member.hpp>
12 
13 namespace Rose {
14 namespace BinaryAnalysis {
15 namespace InstructionSemantics2 {
16 
18 using DispatcherAarch64Ptr = boost::shared_ptr<class DispatcherAarch64>;
19 
20 class DispatcherAarch64: public BaseSemantics::Dispatcher {
21 public:
23  using Super = BaseSemantics::Dispatcher;
24 
26  using Ptr = DispatcherAarch64Ptr;
27 
28 public:
35  RegisterDescriptor REG_PC, REG_SP, REG_LR;
36  RegisterDescriptor REG_CPSR_N, REG_CPSR_Z, REG_CPSR_C, REG_CPSR_V;
39 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
40 private:
41  friend class boost::serialization::access;
42 
43  template<class S>
44  void save(S &s, const unsigned /*version*/) const {
45  s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Super);
46  }
47 
48  template<class S>
49  void load(S &s, const unsigned /*version*/) {
50  s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Super);
51  initializeRegisterDescriptors();
52  initializeInsnDispatchTable();
53  initializeMemory();
54  }
55 
56  BOOST_SERIALIZATION_SPLIT_MEMBER();
57 #endif
58 
59 protected:
60  // prototypical constructor
61  DispatcherAarch64()
62  : BaseSemantics::Dispatcher(64, RegisterDictionary::dictionary_aarch64()) {}
63 
64  DispatcherAarch64(const BaseSemantics::RiscOperatorsPtr &ops, const RegisterDictionary *regs)
65  : BaseSemantics::Dispatcher(ops, 64, regs ? regs : RegisterDictionary::dictionary_aarch64()) {
66  initializeRegisterDescriptors();
67  initializeInsnDispatchTable();
68  initializeMemory();
69  initializeState(ops->currentState());
70  }
71 
72 public:
76  static DispatcherAarch64Ptr instance() {
77  return DispatcherAarch64Ptr(new DispatcherAarch64);
78  }
79 
81  static DispatcherAarch64Ptr instance(const BaseSemantics::RiscOperatorsPtr &ops, const RegisterDictionary *regs = nullptr) {
82  return DispatcherAarch64Ptr(new DispatcherAarch64(ops, regs));
83  }
84 
86  virtual BaseSemantics::DispatcherPtr create(const BaseSemantics::RiscOperatorsPtr &ops, size_t addrWidth = 0,
87  const RegisterDictionary *regs = nullptr) const override {
88  ASSERT_require(0 == addrWidth || 64 == addrWidth);
89  return instance(ops, regs);
90  }
91 
93  static DispatcherAarch64Ptr promote(const BaseSemantics::DispatcherPtr &d) {
94  DispatcherAarch64Ptr retval = boost::dynamic_pointer_cast<DispatcherAarch64>(d);
95  ASSERT_not_null(retval);
96  return retval;
97  }
98 
99 protected:
101  void initializeRegisterDescriptors();
102 
106  void initializeInsnDispatchTable();
107 
109  void initializeMemory();
110 
111 public:
112  BaseSemantics::SValuePtr read(SgAsmExpression*, size_t value_nbits=0, size_t addr_nbits=0) override;
113  void write(SgAsmExpression*, const BaseSemantics::SValuePtr &value, size_t addr_nbits=0) override;
114 
115  // Operations more or less defined by the A64 reference manual. Replicates the specified value according to the vector type.
117 
118  struct NZCV {
123 
124  NZCV() {}
125 
126  NZCV(const BaseSemantics::SValuePtr &n, const BaseSemantics::SValuePtr &z,
128  : n(n), z(z), c(c), v(v) {}
129  };
130 
131  // Compute the NZCV bits based on the result of an addition and the carries returned by RiscOperators::addWithCarries.
132  NZCV computeNZCV(const BaseSemantics::SValuePtr &sum, const BaseSemantics::SValuePtr &carries);
133 
134  // Set the NZCV bits based on the result of an addition and the carries returned by RiscOperators::addWithCarries.
135  void updateNZCV(const BaseSemantics::SValuePtr &sum, const BaseSemantics::SValuePtr &carries);
136 
137  // Return true or false depending on whether the condition holds.
138  BaseSemantics::SValuePtr conditionHolds(Aarch64InstructionCondition);
139 
140  // From ARM documentation: "Decode AArch64 bitfield and logical immediate masks which use a similar encoding structure."
141  std::pair<uint64_t, uint64_t> decodeBitMasks(size_t m, bool immN, uint64_t imms, uint64_t immr, bool immediate);
142 
143  // Handles the rather tricky BFM instruction, which is a general case of a few other instructions.
144  void bitfieldMove(BaseSemantics::RiscOperators *ops, SgAsmExpression *dst, SgAsmExpression *src, bool n,
145  uint64_t immR, uint64_t immS);
146 
147  // Handles the rather tricky UBFM instruction, which is a general case of a few other instructions.
148  void unsignedBitfieldMove(BaseSemantics::RiscOperators *ops, SgAsmExpression *dst, SgAsmExpression *src, bool n,
149  uint64_t immR, uint64_t immS);
150 
151  // Handles the rather tricky SBFM instruction, which is a general case of a few other instructions.
152  void signedBitfieldMove(BaseSemantics::RiscOperators *ops, SgAsmExpression *dst, SgAsmExpression *src, bool n,
153  uint64_t immR, uint64_t immS);
154 
155 protected:
156  int iprocKey(SgAsmInstruction*) const override;
157  RegisterDescriptor instructionPointerRegister() const override;
158  RegisterDescriptor stackPointerRegister() const override;
159  RegisterDescriptor stackFrameRegister() const override;
160  RegisterDescriptor callReturnRegister() const override;
161  void set_register_dictionary(const RegisterDictionary*) override;
162 };
163 
164 } // namespace
165 } // namespace
166 } // namespace
167 
168 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
169 BOOST_CLASS_EXPORT_KEY(Rose::BinaryAnalysis::InstructionSemantics2::DispatcherAarch64);
170 #endif
171 
172 #endif
173 #endif
boost::shared_ptr< RiscOperators > RiscOperatorsPtr
Shared-ownership pointer to a RISC operators object.
Sawyer::SharedPointer< Node > Ptr
Shared-ownership pointer to an expression Node.
Definition: SymbolicExpr.h:156
Sum< T >::Ptr sum()
Factory for value agumenter.
Base class for machine instructions.
Main namespace for the ROSE library.
boost::shared_ptr< Dispatcher > DispatcherPtr
Shared-ownership pointer to a semantics instruction dispatcher.
Base class for expressions.
Base class for binary types.
Sawyer::SharedPointer< SValue > SValuePtr
Shared-ownership pointer to a semantic value in any domain.