/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _LIBUNWINDSTACK_DWARF_OP_H
#define _LIBUNWINDSTACK_DWARF_OP_H
#include <stdint.h>
#include <deque>
#include <string>
#include <type_traits>
#include <vector>
#include <unwindstack/DwarfError.h>
#include "DwarfEncoding.h"
#include "RegsInfo.h"
namespace unwindstack {
// Forward declarations.
class DwarfMemory;
class Memory;
template <typename AddressType>
class RegsImpl;
template <typename AddressType>
class DwarfOp {
// Signed version of AddressType
typedef typename std::make_signed<AddressType>::type SignedType;
public:
DwarfOp(DwarfMemory* memory, Memory* regular_memory)
: memory_(memory), regular_memory_(regular_memory) {}
virtual ~DwarfOp() = default;
bool Decode();
bool Eval(uint64_t start, uint64_t end);
void GetLogInfo(uint64_t start, uint64_t end, std::vector<std::string>* lines);
AddressType StackAt(size_t index) { return stack_[index]; }
size_t StackSize() { return stack_.size(); }
void set_regs_info(RegsInfo<AddressType>* regs_info) { regs_info_ = regs_info; }
const DwarfErrorData& last_error() { return last_error_; }
DwarfErrorCode LastErrorCode() { return last_error_.code; }
uint64_t LastErrorAddress() { return last_error_.address; }
bool dex_pc_set() { return dex_pc_set_; }
bool is_register() { return is_register_; }
uint8_t cur_op() { return cur_op_; }
Memory* regular_memory() { return regular_memory_; }
protected:
AddressType OperandAt(size_t index) { return operands_[index]; }
size_t OperandsSize() { return operands_.size(); }
AddressType StackPop() {
AddressType value = stack_.front();
stack_.pop_front();
return value;
}
private:
DwarfMemory* memory_;
Memory* regular_memory_;
RegsInfo<AddressType>* regs_info_;
bool dex_pc_set_ = false;
bool is_register_ = false;
DwarfErrorData last_error_{DWARF_ERROR_NONE, 0};
uint8_t cur_op_;
std::vector<AddressType> operands_;
std::deque<AddressType> stack_;
inline AddressType bool_to_dwarf_bool(bool value) { return value ? 1 : 0; }
// Op processing functions.
bool op_deref();
bool op_deref_size();
bool op_push();
bool op_dup();
bool op_drop();
bool op_over();
bool op_pick();
bool op_swap();
bool op_rot();
bool op_abs();
bool op_and();
bool op_div();
bool op_minus();
bool op_mod();
bool op_mul();
bool op_neg();
bool op_not();
bool op_or();
bool op_plus();
bool op_plus_uconst();
bool op_shl();
bool op_shr();
bool op_shra();
bool op_xor();
bool op_bra();
bool op_eq();
bool op_ge();
bool op_gt();
bool op_le();
bool op_lt();
bool op_ne();
bool op_skip();
bool op_lit();
bool op_reg();
bool op_regx();
bool op_breg();
bool op_bregx();
bool op_nop();
bool op_not_implemented();
using OpHandleFuncPtr = bool (DwarfOp::*)();
static const OpHandleFuncPtr kOpHandleFuncList[];
};
} // namespace unwindstack
#endif // _LIBUNWINDSTACK_DWARF_OP_H