ROSE 0.11.145.202
DispatcherAarch32.h
1#ifndef ROSE_BinaryAnalysis_InstructionSemantics_DispatcherAarch32_H
2#define ROSE_BinaryAnalysis_InstructionSemantics_DispatcherAarch32_H
3#include <featureTests.h>
4#ifdef ROSE_ENABLE_ASM_AARCH32
5
6#include <Rose/BinaryAnalysis/BasicTypes.h>
7#include <Rose/BinaryAnalysis/InstructionEnumsAarch32.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 DispatcherAarch32Ptr = boost::shared_ptr<class DispatcherAarch32>;
21
22class DispatcherAarch32: public BaseSemantics::Dispatcher {
23public:
25 using Super = BaseSemantics::Dispatcher;
26
28 using Ptr = DispatcherAarch32Ptr;
29
30public:
37 RegisterDescriptor REG_PC, REG_SP, REG_LR;
38 RegisterDescriptor REG_PSTATE_N, REG_PSTATE_Z, REG_PSTATE_C, REG_PSTATE_V, REG_PSTATE_T; // parts of CPSR
39 RegisterDescriptor REG_PSTATE_E, REG_PSTATE_Q, REG_PSTATE_GE;
40 RegisterDescriptor REG_PSTATE_NZCV; // the CPSR N, Z, C, and V bits
41 RegisterDescriptor REG_SPSR, REG_CPSR;
42 RegisterDescriptor REG_DTRTX; // debug registers
43 RegisterDescriptor REG_UNKNOWN; // special ROSE register
46#ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
47private:
48 friend class boost::serialization::access;
49
50 template<class S>
51 void save(S &s, const unsigned /*version*/) const {
52 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Super);
53 }
54
55 template<class S>
56 void load(S &s, const unsigned /*version*/) {
57 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Super);
58 initializeRegisterDescriptors();
59 initializeInsnDispatchTable();
60 initializeMemory();
61 }
62
63 BOOST_SERIALIZATION_SPLIT_MEMBER();
64#endif
65
66private:
67 DispatcherAarch32(); // used only by boost::serialization
68
69protected:
70 // prototypical constructor
71 DispatcherAarch32(const Architecture::BaseConstPtr&);
72
73 DispatcherAarch32(const Architecture::BaseConstPtr&, const BaseSemantics::RiscOperatorsPtr&);
74
75public:
76 ~DispatcherAarch32();
77
81 static DispatcherAarch32Ptr instance(const Architecture::BaseConstPtr&);
82
84 static DispatcherAarch32Ptr instance(const Architecture::BaseConstPtr&, const BaseSemantics::RiscOperatorsPtr&);
85
87 virtual BaseSemantics::DispatcherPtr create(const BaseSemantics::RiscOperatorsPtr&) const override;
88
90 static DispatcherAarch32Ptr promote(const BaseSemantics::DispatcherPtr&);
91
92protected:
94 void initializeRegisterDescriptors();
95
99 void initializeInsnDispatchTable();
100
102 void initializeMemory();
103
104protected:
105 int iprocKey(SgAsmInstruction*) const override;
106 RegisterDescriptor instructionPointerRegister() const override;
107 RegisterDescriptor stackPointerRegister() const override;
108 RegisterDescriptor callReturnRegister() const override;
109
110public:
111 BaseSemantics::SValuePtr read(SgAsmExpression*, size_t value_nbits=0, size_t addr_nbits=0) override;
112 void write(SgAsmExpression*, const BaseSemantics::SValuePtr&, size_t addr_nbits=0) override;
113
114 // Instruction condition
115 BaseSemantics::SValuePtr conditionHolds(Aarch32InstructionCondition);
116
117 // True if the expression is the program counter register
118 bool isIpRegister(SgAsmExpression*);
119
120 // Read the instruction pointer (PC) register, which is handled in a special way.
122
123 // Is the processor in T32 mode? This is based just on the instruction being executed.
124 BaseSemantics::SValuePtr isT32Mode();
125
126 // Is the processor in A32 mode? This is based just on the instruction being executed.
127 BaseSemantics::SValuePtr isA32Mode();
128
129 // Set T32 mode on or off.
130 void setThumbMode(SgAsmAarch32Instruction*); // on if instructions is 2 bytes; off otherwise
131 void setThumbMode(const BaseSemantics::SValuePtr &state);
132 void setThumbMode(const BaseSemantics::SValuePtr &enabled, const BaseSemantics::SValuePtr &state);
133
134 // Conditionally write a value to a register
135 void maybeWriteRegister(const BaseSemantics::SValuePtr &enabled, RegisterDescriptor, const BaseSemantics::SValuePtr &value);
136
137 // Conditionally write a value to memory
138 void maybeWriteMemory(const BaseSemantics::SValuePtr &enabled, const BaseSemantics::SValuePtr &address,
139 const BaseSemantics::SValuePtr &value);
140
141 // Conditionally write the the destination described the by ROSE expression, which must also be readable.
142 void maybeWrite(const BaseSemantics::SValuePtr &enabled, SgAsmExpression *destination, const BaseSemantics::SValuePtr &value);
143
144 // Returns the most significant bit.
146
147 // Return the register that's being directly read or written.
148 RegisterDescriptor accessedRegister(SgAsmExpression*);
149
150 // Returns true if the specified value is a constant true, false in all other cases
151 bool mustBeSet(const BaseSemantics::SValuePtr&);
152
153 //----------------------------------------------------------------------------------------------------------------
154 // The following functions are more or less from ARM documentation and named similarly. They are generally not
155 // further documented here or by ARM.
156 //----------------------------------------------------------------------------------------------------------------
157 using TwoValues = std::tuple<BaseSemantics::SValuePtr, BaseSemantics::SValuePtr>;
158
159 enum class SrType { LSL, LSR, ASR, ROR, RRX }; // SRType
160 enum class BranchType { // BranchType
161 DIRCALL, // direct branch with link
162 DIR, // undocumented but used by B instruction (maybe the same as DIRCALL?)
163 INDCALL, // indirect branch with link
164 ERET, // exception return (indirect)
165 DBGEXIT, // exit from debug state
166 RET, // indirect branch with function return hint
167 INDIR, // indicrect branch
168 EXCEPTION, // exception entry
169 RESET, // reset
170 UNKNOWN // other
171 };
172
173 BaseSemantics::SValuePtr part(const BaseSemantics::SValuePtr&, size_t maxBit, size_t minBit); // X<m,n>
174 BaseSemantics::SValuePtr part(const BaseSemantics::SValuePtr&, size_t bitNumber); // X<n>
176 BaseSemantics::SValuePtr zeroExtend(const BaseSemantics::SValuePtr&, size_t); // ZeroExtend
177 BaseSemantics::SValuePtr makeZeros(size_t); // Zeros
178 TwoValues a32ExpandImmC(const BaseSemantics::SValuePtr&); // A32ExpandImm_C
179 TwoValues shiftC(const BaseSemantics::SValuePtr&, SrType, int amount, const BaseSemantics::SValuePtr &carry); // Shift_C
180 TwoValues lslC(const BaseSemantics::SValuePtr&, size_t shift); // LSL_C
181 TwoValues lsrC(const BaseSemantics::SValuePtr&, size_t shift); // LSR_C
182 TwoValues asrC(const BaseSemantics::SValuePtr&, size_t shift); // ASR_C
183 TwoValues rorC(const BaseSemantics::SValuePtr&, int shift); // ROR_C
184 TwoValues rrxC(const BaseSemantics::SValuePtr&, const BaseSemantics::SValuePtr &carry); // RRX_C
185 BaseSemantics::SValuePtr lsr(const BaseSemantics::SValuePtr&, size_t shift); // LSR
186 BaseSemantics::SValuePtr lsl(const BaseSemantics::SValuePtr&, size_t shift); // LSL
188 void aluExceptionReturn(const BaseSemantics::SValuePtr &enabled,
189 const BaseSemantics::SValuePtr &address); // ALUExceptionReturn
190 void aluWritePc(const BaseSemantics::SValuePtr &enabled, const BaseSemantics::SValuePtr &address); // ALUWritePC
191 void bxWritePc(const BaseSemantics::SValuePtr &enabled, const BaseSemantics::SValuePtr &address, BranchType); // BXWritePC
192 void branchWritePc(const BaseSemantics::SValuePtr &enabled, const BaseSemantics::SValuePtr &address,
193 BranchType branchType); // BranchWritePC
194 void branchTo(const BaseSemantics::SValuePtr &enabled, const BaseSemantics::SValuePtr &alignedAddress,
195 BranchType); // BranchTo
196 BaseSemantics::SValuePtr align(const BaseSemantics::SValuePtr&, unsigned); // Align
197 BaseSemantics::SValuePtr pc(); // PC. Returns address of current instruction plus eight (not sure why).
198 BaseSemantics::SValuePtr pcStoreValue(); // PCStoreValue (which doesn't store anything at all)
199 void loadWritePc(const BaseSemantics::SValuePtr &enabled, const BaseSemantics::SValuePtr &address); // LoadWritePC
200 TwoValues addWithCarry(const BaseSemantics::SValuePtr&, const BaseSemantics::SValuePtr&,
201 const BaseSemantics::SValuePtr&); // AddWithCarry
202 BaseSemantics::SValuePtr spsr(); // SPSR
203 void aarch32ExceptionReturn(const BaseSemantics::SValuePtr &enabled, const BaseSemantics::SValuePtr &address,
204 const BaseSemantics::SValuePtr &spsr); // AArch32.ExceptionReturn
205 void dbgdtrEl0(const BaseSemantics::SValuePtr &enabled, const BaseSemantics::SValuePtr &value); // DBGDTR_EL0
206 BaseSemantics::SValuePtr dbgdtrEl0(); // DBGDTR_EL0
207 BaseSemantics::SValuePtr bigEndian(); // BigEndian
208 BaseSemantics::SValuePtr signedSat(const BaseSemantics::SValuePtr&, size_t); // SignedSat
209 TwoValues signedSatQ(const BaseSemantics::SValuePtr&, size_t); // SignedSatQ
210 BaseSemantics::SValuePtr unsignedSat(const BaseSemantics::SValuePtr&, size_t); // UnsignedSat
211 TwoValues unsignedSatQ(const BaseSemantics::SValuePtr&, size_t); // UnsignedSatQ
213 BaseSemantics::SValuePtr countLeadingZeroBits(const BaseSemantics::SValuePtr&); // CountLeadingZeroBits
214 void aarch32CallHypervisor(const BaseSemantics::SValuePtr&, const BaseSemantics::SValuePtr&); // AArch32.CallHypervisor
215};
216
217} // namespace
218} // namespace
219} // namespace
220
221#ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
222BOOST_CLASS_EXPORT_KEY(Rose::BinaryAnalysis::InstructionSemantics::DispatcherAarch32);
223#endif
224
225#endif
226#endif
Dispatches instructions through the RISC layer.
Definition Dispatcher.h:43
Base class for expressions.
Base class for machine instructions.
bool signBit(T value)
Returns true if the sign bit is set, false if clear.
Definition integerOps.h:72
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.
Unsigned signExtend(Unsigned src, size_t n)
Sign extend part of a value to the full width of the src type.
Definition BitOps.h:324
std::string join(const std::string &separator, const Container &container)
Join individual items to form a single string.
Definition SplitJoin.h:62
The ROSE library.
const char * SrType(int64_t)
Convert Rose::BinaryAnalysis::InstructionSemantics::DispatcherAarch32::SrType enum constant to a stri...
const char * BranchType(int64_t)
Convert Rose::BinaryAnalysis::InstructionSemantics::DispatcherAarch32::BranchType enum constant to a ...