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 #pragma once
18 
19 #include <stdint.h>
20 
21 #include <deque>
22 #include <string>
23 #include <type_traits>
24 #include <vector>
25 
26 #include <unwindstack/DwarfError.h>
27 
28 #include "DwarfEncoding.h"
29 #include "RegsInfo.h"
30 
31 namespace unwindstack {
32 
33 // Forward declarations.
34 class DwarfMemory;
35 class Memory;
36 template <typename AddressType>
37 class RegsImpl;
38 
39 template <typename AddressType>
40 class DwarfOp {
41   // Signed version of AddressType
42   typedef typename std::make_signed<AddressType>::type SignedType;
43 
44  public:
DwarfOp(DwarfMemory * memory,Memory * regular_memory)45   DwarfOp(DwarfMemory* memory, Memory* regular_memory)
46       : memory_(memory), regular_memory_(regular_memory) {}
47   virtual ~DwarfOp() = default;
48 
49   bool Decode();
50 
51   bool Eval(uint64_t start, uint64_t end);
52 
53   void GetLogInfo(uint64_t start, uint64_t end, std::vector<std::string>* lines);
54 
StackAt(size_t index)55   AddressType StackAt(size_t index) { return stack_[index]; }
StackSize()56   size_t StackSize() { return stack_.size(); }
57 
set_regs_info(RegsInfo<AddressType> * regs_info)58   void set_regs_info(RegsInfo<AddressType>* regs_info) { regs_info_ = regs_info; }
59 
last_error()60   const DwarfErrorData& last_error() { return last_error_; }
LastErrorCode()61   DwarfErrorCode LastErrorCode() { return last_error_.code; }
LastErrorAddress()62   uint64_t LastErrorAddress() { return last_error_.address; }
63 
dex_pc_set()64   bool dex_pc_set() { return dex_pc_set_; }
65 
is_register()66   bool is_register() { return is_register_; }
67 
cur_op()68   uint8_t cur_op() { return cur_op_; }
69 
regular_memory()70   Memory* regular_memory() { return regular_memory_; }
71 
72  protected:
OperandAt(size_t index)73   AddressType OperandAt(size_t index) { return operands_[index]; }
OperandsSize()74   size_t OperandsSize() { return operands_.size(); }
75 
StackPop()76   AddressType StackPop() {
77     AddressType value = stack_.front();
78     stack_.pop_front();
79     return value;
80   }
81 
82  private:
83   DwarfMemory* memory_;
84   Memory* regular_memory_;
85 
86   RegsInfo<AddressType>* regs_info_;
87   bool dex_pc_set_ = false;
88   bool is_register_ = false;
89   DwarfErrorData last_error_{DWARF_ERROR_NONE, 0};
90   uint8_t cur_op_;
91   std::vector<AddressType> operands_;
92   std::deque<AddressType> stack_;
93 
bool_to_dwarf_bool(bool value)94   inline AddressType bool_to_dwarf_bool(bool value) { return value ? 1 : 0; }
95 
96   // Op processing functions.
97   bool op_deref();
98   bool op_deref_size();
99   bool op_push();
100   bool op_dup();
101   bool op_drop();
102   bool op_over();
103   bool op_pick();
104   bool op_swap();
105   bool op_rot();
106   bool op_abs();
107   bool op_and();
108   bool op_div();
109   bool op_minus();
110   bool op_mod();
111   bool op_mul();
112   bool op_neg();
113   bool op_not();
114   bool op_or();
115   bool op_plus();
116   bool op_plus_uconst();
117   bool op_shl();
118   bool op_shr();
119   bool op_shra();
120   bool op_xor();
121   bool op_bra();
122   bool op_eq();
123   bool op_ge();
124   bool op_gt();
125   bool op_le();
126   bool op_lt();
127   bool op_ne();
128   bool op_skip();
129   bool op_lit();
130   bool op_reg();
131   bool op_regx();
132   bool op_breg();
133   bool op_bregx();
134   bool op_nop();
135   bool op_not_implemented();
136 
137   using OpHandleFuncPtr = bool (DwarfOp::*)();
138   static const OpHandleFuncPtr kOpHandleFuncList[];
139 };
140 
141 }  // namespace unwindstack
142