ROSE 0.11.145.147
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#include <boost/serialization/access.hpp>
11#include <boost/serialization/base_object.hpp>
12#include <boost/serialization/export.hpp>
13#include <boost/serialization/split_member.hpp>
14
15namespace Rose {
16namespace BinaryAnalysis {
17namespace InstructionSemantics {
18
20using DispatcherAarch64Ptr = boost::shared_ptr<class DispatcherAarch64>;
21
22class DispatcherAarch64: public BaseSemantics::Dispatcher {
23public:
25 using Super = BaseSemantics::Dispatcher;
26
28 using Ptr = DispatcherAarch64Ptr;
29
30public:
37 RegisterDescriptor REG_PC, REG_SP, REG_LR;
38 RegisterDescriptor REG_CPSR_N, REG_CPSR_Z, REG_CPSR_C, REG_CPSR_V;
41#ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
42private:
43 friend class boost::serialization::access;
44
45 template<class S>
46 void save(S &s, const unsigned /*version*/) const {
47 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Super);
48 }
49
50 template<class S>
51 void load(S &s, const unsigned /*version*/) {
52 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Super);
53 initializeRegisterDescriptors();
54 initializeInsnDispatchTable();
55 initializeMemory();
56 }
57
58 BOOST_SERIALIZATION_SPLIT_MEMBER();
59#endif
60
61private:
62 DispatcherAarch64(); // used only by boost::serialization
63
64protected:
65 // prototypical constructor
66 DispatcherAarch64(const Architecture::BaseConstPtr&);
67
68 DispatcherAarch64(const Architecture::BaseConstPtr&, const BaseSemantics::RiscOperatorsPtr&);
69
70public:
71 ~DispatcherAarch64();
72
76 static DispatcherAarch64Ptr instance(const Architecture::BaseConstPtr&);
77
79 static DispatcherAarch64Ptr instance(const Architecture::BaseConstPtr&, const BaseSemantics::RiscOperatorsPtr&);
80
82 virtual BaseSemantics::DispatcherPtr create(const BaseSemantics::RiscOperatorsPtr&) const override;
83
85 static DispatcherAarch64Ptr promote(const BaseSemantics::DispatcherPtr&);
86
87protected:
89 void initializeRegisterDescriptors();
90
94 void initializeInsnDispatchTable();
95
97 void initializeMemory();
98
99public:
100 BaseSemantics::SValuePtr read(SgAsmExpression*, size_t value_nbits=0, size_t addr_nbits=0) override;
101 void write(SgAsmExpression*, const BaseSemantics::SValuePtr &value, size_t addr_nbits=0) override;
102
103 // Operations more or less defined by the A64 reference manual. Replicates the specified value according to the vector type.
105
106 struct NZCV {
111
112 NZCV() {}
113
116 : n(n), z(z), c(c), v(v) {}
117 };
118
119 // Compute the NZCV bits based on the result of an addition and the carries returned by RiscOperators::addWithCarries.
120 NZCV computeNZCV(const BaseSemantics::SValuePtr &sum, const BaseSemantics::SValuePtr &carries);
121
122 // Set the NZCV bits based on the result of an addition and the carries returned by RiscOperators::addWithCarries.
123 void updateNZCV(const BaseSemantics::SValuePtr &sum, const BaseSemantics::SValuePtr &carries);
124
125 // Return true or false depending on whether the condition holds.
126 BaseSemantics::SValuePtr conditionHolds(Aarch64InstructionCondition);
127
128 // From ARM documentation: "Decode AArch64 bitfield and logical immediate masks which use a similar encoding structure."
129 std::pair<uint64_t, uint64_t> decodeBitMasks(size_t m, bool immN, uint64_t imms, uint64_t immr, bool immediate);
130
131 // Handles the rather tricky BFM instruction, which is a general case of a few other instructions.
132 void bitfieldMove(BaseSemantics::RiscOperators *ops, SgAsmExpression *dst, SgAsmExpression *src, bool n,
133 uint64_t immR, uint64_t immS);
134
135 // Handles the rather tricky UBFM instruction, which is a general case of a few other instructions.
136 void unsignedBitfieldMove(BaseSemantics::RiscOperators *ops, SgAsmExpression *dst, SgAsmExpression *src, bool n,
137 uint64_t immR, uint64_t immS);
138
139 // Handles the rather tricky SBFM instruction, which is a general case of a few other instructions.
140 void signedBitfieldMove(BaseSemantics::RiscOperators *ops, SgAsmExpression *dst, SgAsmExpression *src, bool n,
141 uint64_t immR, uint64_t immS);
142
143protected:
144 int iprocKey(SgAsmInstruction*) const override;
145 RegisterDescriptor instructionPointerRegister() const override;
146 RegisterDescriptor stackPointerRegister() const override;
147 RegisterDescriptor stackFrameRegister() const override;
148 RegisterDescriptor callReturnRegister() const override;
149};
150
151} // namespace
152} // namespace
153} // namespace
154
155#ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
156BOOST_CLASS_EXPORT_KEY(Rose::BinaryAnalysis::InstructionSemantics::DispatcherAarch64);
157#endif
158
159#endif
160#endif
Dispatches instructions through the RISC layer.
Definition Dispatcher.h:43
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.