ROSE  0.11.145.0
DispatcherAarch64.h
1 #ifndef ROSE_BinaryAnalysis_InstructionSemantics_DispatcherAarch64_H
2 #define ROSE_BinaryAnalysis_InstructionSemantics_DispatcherAarch64_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_ASM_AARCH64
5 
6 #include <Rose/BinaryAnalysis/BasicTypes.h>
7 #include <Rose/BinaryAnalysis/InstructionSemantics/BaseSemantics.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 namespace InstructionSemantics {
17 
19 using DispatcherAarch64Ptr = boost::shared_ptr<class DispatcherAarch64>;
20 
21 class DispatcherAarch64: public BaseSemantics::Dispatcher {
22 public:
24  using Super = BaseSemantics::Dispatcher;
25 
27  using Ptr = DispatcherAarch64Ptr;
28 
29 public:
36  RegisterDescriptor REG_PC, REG_SP, REG_LR;
37  RegisterDescriptor REG_CPSR_N, REG_CPSR_Z, REG_CPSR_C, REG_CPSR_V;
40 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
41 private:
42  friend class boost::serialization::access;
43 
44  template<class S>
45  void save(S &s, const unsigned /*version*/) const {
46  s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Super);
47  }
48 
49  template<class S>
50  void load(S &s, const unsigned /*version*/) {
51  s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Super);
52  initializeRegisterDescriptors();
53  initializeInsnDispatchTable();
54  initializeMemory();
55  }
56 
57  BOOST_SERIALIZATION_SPLIT_MEMBER();
58 #endif
59 
60 protected:
61  // prototypical constructor
62  DispatcherAarch64();
63 
64  DispatcherAarch64(const BaseSemantics::RiscOperatorsPtr&, const RegisterDictionaryPtr&);
65 
66 public:
67  ~DispatcherAarch64();
68 
72  static DispatcherAarch64Ptr instance();
73 
75  static DispatcherAarch64Ptr instance(const BaseSemantics::RiscOperatorsPtr&, const RegisterDictionaryPtr&);
76 
78  virtual BaseSemantics::DispatcherPtr create(const BaseSemantics::RiscOperatorsPtr&, size_t addrWidth,
79  const RegisterDictionaryPtr&) const override;
80 
82  static DispatcherAarch64Ptr promote(const BaseSemantics::DispatcherPtr&);
83 
84 protected:
86  void initializeRegisterDescriptors();
87 
91  void initializeInsnDispatchTable();
92 
94  void initializeMemory();
95 
96 public:
97  BaseSemantics::SValuePtr read(SgAsmExpression*, size_t value_nbits=0, size_t addr_nbits=0) override;
98  void write(SgAsmExpression*, const BaseSemantics::SValuePtr &value, size_t addr_nbits=0) override;
99 
100  // Operations more or less defined by the A64 reference manual. Replicates the specified value according to the vector type.
102 
103  struct NZCV {
108 
109  NZCV() {}
110 
111  NZCV(const BaseSemantics::SValuePtr &n, const BaseSemantics::SValuePtr &z,
113  : n(n), z(z), c(c), v(v) {}
114  };
115 
116  // Compute the NZCV bits based on the result of an addition and the carries returned by RiscOperators::addWithCarries.
117  NZCV computeNZCV(const BaseSemantics::SValuePtr &sum, const BaseSemantics::SValuePtr &carries);
118 
119  // Set the NZCV bits based on the result of an addition and the carries returned by RiscOperators::addWithCarries.
120  void updateNZCV(const BaseSemantics::SValuePtr &sum, const BaseSemantics::SValuePtr &carries);
121 
122  // Return true or false depending on whether the condition holds.
123  BaseSemantics::SValuePtr conditionHolds(Aarch64InstructionCondition);
124 
125  // From ARM documentation: "Decode AArch64 bitfield and logical immediate masks which use a similar encoding structure."
126  std::pair<uint64_t, uint64_t> decodeBitMasks(size_t m, bool immN, uint64_t imms, uint64_t immr, bool immediate);
127 
128  // Handles the rather tricky BFM instruction, which is a general case of a few other instructions.
129  void bitfieldMove(BaseSemantics::RiscOperators *ops, SgAsmExpression *dst, SgAsmExpression *src, bool n,
130  uint64_t immR, uint64_t immS);
131 
132  // Handles the rather tricky UBFM instruction, which is a general case of a few other instructions.
133  void unsignedBitfieldMove(BaseSemantics::RiscOperators *ops, SgAsmExpression *dst, SgAsmExpression *src, bool n,
134  uint64_t immR, uint64_t immS);
135 
136  // Handles the rather tricky SBFM instruction, which is a general case of a few other instructions.
137  void signedBitfieldMove(BaseSemantics::RiscOperators *ops, SgAsmExpression *dst, SgAsmExpression *src, bool n,
138  uint64_t immR, uint64_t immS);
139 
140 protected:
141  int iprocKey(SgAsmInstruction*) const override;
142  RegisterDescriptor instructionPointerRegister() const override;
143  RegisterDescriptor stackPointerRegister() const override;
144  RegisterDescriptor stackFrameRegister() const override;
145  RegisterDescriptor callReturnRegister() const override;
146  void set_register_dictionary(const RegisterDictionaryPtr&) override;
147 };
148 
149 } // namespace
150 } // namespace
151 } // namespace
152 
153 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
154 BOOST_CLASS_EXPORT_KEY(Rose::BinaryAnalysis::InstructionSemantics::DispatcherAarch64);
155 #endif
156 
157 #endif
158 #endif
Sum< T >::Ptr sum()
Factory for value agumenter.
boost::shared_ptr< RiscOperators > RiscOperatorsPtr
Shared-ownership pointer to a RISC operators object.
Base class for machine instructions.
Sawyer::SharedPointer< RegisterDictionary > RegisterDictionaryPtr
Reference counting pointer.
Main namespace for the ROSE library.
boost::shared_ptr< Dispatcher > DispatcherPtr
Shared-ownership pointer to a semantics instruction dispatcher.
Dispatches instructions through the RISC layer.
Definition: Dispatcher.h:43
ROSE_DLL_API void load(SgProject *project, std::list< std::string > const &filepaths)
Load ASTs that have been saved to files.
Base class for expressions.
Base class for binary types.
Sawyer::SharedPointer< Node > Ptr
Reference counting pointer.
Base class for most instruction semantics RISC operators.
Definition: RiscOperators.h:49