1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef _LIBUNWINDSTACK_DWARF_OP_H
18 #define _LIBUNWINDSTACK_DWARF_OP_H
19 
20 #include <stdint.h>
21 
22 #include <deque>
23 #include <string>
24 #include <type_traits>
25 #include <vector>
26 
27 #include <unwindstack/DwarfError.h>
28 
29 #include "DwarfEncoding.h"
30 #include "RegsInfo.h"
31 
32 namespace unwindstack {
33 
34 // Forward declarations.
35 class DwarfMemory;
36 class Memory;
37 template <typename AddressType>
38 class RegsImpl;
39 
40 template <typename AddressType>
41 class DwarfOp {
42   // Signed version of AddressType
43   typedef typename std::make_signed<AddressType>::type SignedType;
44 
45  public:
DwarfOp(DwarfMemory * memory,Memory * regular_memory)46   DwarfOp(DwarfMemory* memory, Memory* regular_memory)
47       : memory_(memory), regular_memory_(regular_memory) {}
48   virtual ~DwarfOp() = default;
49 
50   bool Decode();
51 
52   bool Eval(uint64_t start, uint64_t end);
53 
54   void GetLogInfo(uint64_t start, uint64_t end, std::vector<std::string>* lines);
55 
StackAt(size_t index)56   AddressType StackAt(size_t index) { return stack_[index]; }
StackSize()57   size_t StackSize() { return stack_.size(); }
58 
set_regs_info(RegsInfo<AddressType> * regs_info)59   void set_regs_info(RegsInfo<AddressType>* regs_info) { regs_info_ = regs_info; }
60 
last_error()61   const DwarfErrorData& last_error() { return last_error_; }
LastErrorCode()62   DwarfErrorCode LastErrorCode() { return last_error_.code; }
LastErrorAddress()63   uint64_t LastErrorAddress() { return last_error_.address; }
64 
dex_pc_set()65   bool dex_pc_set() { return dex_pc_set_; }
66 
is_register()67   bool is_register() { return is_register_; }
68 
cur_op()69   uint8_t cur_op() { return cur_op_; }
70 
regular_memory()71   Memory* regular_memory() { return regular_memory_; }
72 
73  protected:
OperandAt(size_t index)74   AddressType OperandAt(size_t index) { return operands_[index]; }
OperandsSize()75   size_t OperandsSize() { return operands_.size(); }
76 
StackPop()77   AddressType StackPop() {
78     AddressType value = stack_.front();
79     stack_.pop_front();
80     return value;
81   }
82 
83  private:
84   DwarfMemory* memory_;
85   Memory* regular_memory_;
86 
87   RegsInfo<AddressType>* regs_info_;
88   bool dex_pc_set_ = false;
89   bool is_register_ = false;
90   DwarfErrorData last_error_{DWARF_ERROR_NONE, 0};
91   uint8_t cur_op_;
92   std::vector<AddressType> operands_;
93   std::deque<AddressType> stack_;
94 
bool_to_dwarf_bool(bool value)95   inline AddressType bool_to_dwarf_bool(bool value) { return value ? 1 : 0; }
96 
97   // Op processing functions.
98   bool op_deref();
99   bool op_deref_size();
100   bool op_push();
101   bool op_dup();
102   bool op_drop();
103   bool op_over();
104   bool op_pick();
105   bool op_swap();
106   bool op_rot();
107   bool op_abs();
108   bool op_and();
109   bool op_div();
110   bool op_minus();
111   bool op_mod();
112   bool op_mul();
113   bool op_neg();
114   bool op_not();
115   bool op_or();
116   bool op_plus();
117   bool op_plus_uconst();
118   bool op_shl();
119   bool op_shr();
120   bool op_shra();
121   bool op_xor();
122   bool op_bra();
123   bool op_eq();
124   bool op_ge();
125   bool op_gt();
126   bool op_le();
127   bool op_lt();
128   bool op_ne();
129   bool op_skip();
130   bool op_lit();
131   bool op_reg();
132   bool op_regx();
133   bool op_breg();
134   bool op_bregx();
135   bool op_nop();
136   bool op_not_implemented();
137 
138   using OpHandleFuncPtr = bool (DwarfOp::*)();
139   static const OpHandleFuncPtr kOpHandleFuncList[];
140 };
141 
142 }  // namespace unwindstack
143 
144 #endif  // _LIBUNWINDSTACK_DWARF_OP_H
145