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