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