155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris/* 255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris * Copyright (C) 2017 The Android Open Source Project 355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris * 455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris * Licensed under the Apache License, Version 2.0 (the "License"); 555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris * you may not use this file except in compliance with the License. 655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris * You may obtain a copy of the License at 755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris * 855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris * http://www.apache.org/licenses/LICENSE-2.0 955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris * 1055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris * Unless required by applicable law or agreed to in writing, software 1155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris * distributed under the License is distributed on an "AS IS" BASIS, 1255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris * See the License for the specific language governing permissions and 1455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris * limitations under the License. 1555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris */ 1655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 1755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris#include <stdint.h> 1855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 1955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris#include <deque> 2055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris#include <string> 2155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris#include <vector> 2255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 2355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris#include <android-base/stringprintf.h> 2455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 25d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris#include <unwindstack/DwarfMemory.h> 26d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris#include <unwindstack/Log.h> 27d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris#include <unwindstack/Memory.h> 28d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris#include <unwindstack/Regs.h> 29d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris 3055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris#include "DwarfError.h" 3155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris#include "DwarfOp.h" 32d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris 33d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferrisnamespace unwindstack { 3455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 3555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 3655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisconstexpr typename DwarfOp<AddressType>::OpCallback DwarfOp<AddressType>::kCallbackTable[256]; 3755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 3855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 3955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::Eval(uint64_t start, uint64_t end, uint8_t dwarf_version) { 4055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint32_t iterations = 0; 4155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris is_register_ = false; 4255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.clear(); 4355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris memory_->set_cur_offset(start); 4455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris while (memory_->cur_offset() < end) { 4555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!Decode(dwarf_version)) { 4655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 4755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 4855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // To protect against a branch that creates an infinite loop, 4955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // terminate if the number of iterations gets too high. 5055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (iterations++ == 1000) { 5155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_TOO_MANY_ITERATIONS; 5255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 5355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 5455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 5555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 5655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 5755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 5855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 5955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::Decode(uint8_t dwarf_version) { 6055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_NONE; 6155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!memory_->ReadBytes(&cur_op_, 1)) { 6255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_MEMORY_INVALID; 6355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 6455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 6555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 6655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris const auto* op = &kCallbackTable[cur_op_]; 6755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris const auto handle_func = op->handle_func; 6855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (handle_func == nullptr) { 6955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_ILLEGAL_VALUE; 7055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 7155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 7255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 7355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // Check for an unsupported opcode. 7455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (dwarf_version < op->supported_version) { 7555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_ILLEGAL_VALUE; 7655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 7755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 7855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 7955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // Make sure that the required number of stack elements is available. 8055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (stack_.size() < op->num_required_stack_values) { 8155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_STACK_INDEX_NOT_VALID; 8255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 8355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 8455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 8555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris operands_.clear(); 8655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris for (size_t i = 0; i < op->num_operands; i++) { 8755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint64_t value; 8855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!memory_->ReadEncodedValue<AddressType>(op->operands[i], &value)) { 8955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_MEMORY_INVALID; 9055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 9155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 9255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris operands_.push_back(value); 9355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 9455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return (this->*handle_func)(); 9555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 9655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 9755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 9855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisvoid DwarfOp<AddressType>::GetLogInfo(uint64_t start, uint64_t end, 9955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris std::vector<std::string>* lines) { 10055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris memory_->set_cur_offset(start); 10155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris while (memory_->cur_offset() < end) { 10255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint8_t cur_op; 10355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!memory_->ReadBytes(&cur_op, 1)) { 10455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return; 10555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 10655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 10755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris std::string raw_string(android::base::StringPrintf("Raw Data: 0x%02x", cur_op)); 10855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris std::string log_string; 10955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris const auto* op = &kCallbackTable[cur_op]; 11055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (op->handle_func == nullptr) { 11155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris log_string = "Illegal"; 11255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } else { 11355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris log_string = op->name; 11455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint64_t start_offset = memory_->cur_offset(); 11555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris for (size_t i = 0; i < op->num_operands; i++) { 11655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint64_t value; 11755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!memory_->ReadEncodedValue<AddressType>(op->operands[i], &value)) { 11855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return; 11955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 12055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris log_string += ' ' + std::to_string(value); 12155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 12255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint64_t end_offset = memory_->cur_offset(); 12355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 12455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris memory_->set_cur_offset(start_offset); 12555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris for (size_t i = start_offset; i < end_offset; i++) { 12655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint8_t byte; 12755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!memory_->ReadBytes(&byte, 1)) { 12855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return; 12955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 13055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris raw_string += android::base::StringPrintf(" 0x%02x", byte); 13155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 13255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris memory_->set_cur_offset(end_offset); 13355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 13455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris lines->push_back(std::move(log_string)); 13555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris lines->push_back(std::move(raw_string)); 13655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 13755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 13855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 13955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 14055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_deref() { 14155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // Read the address and dereference it. 14255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType addr = StackPop(); 14355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType value; 14455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!regular_memory()->Read(addr, &value, sizeof(value))) { 14555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_MEMORY_INVALID; 14655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 14755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 14855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(value); 14955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 15055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 15155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 15255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 15355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_deref_size() { 15455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType bytes_to_read = OperandAt(0); 15555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (bytes_to_read > sizeof(AddressType) || bytes_to_read == 0) { 15655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_ILLEGAL_VALUE; 15755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 15855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 15955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // Read the address and dereference it. 16055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType addr = StackPop(); 16155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType value = 0; 16255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!regular_memory()->Read(addr, &value, bytes_to_read)) { 16355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_MEMORY_INVALID; 16455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 16555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 16655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(value); 16755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 16855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 16955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 17055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 17155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_push() { 17255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // Push all of the operands. 17355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris for (auto operand : operands_) { 17455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(operand); 17555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 17655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 17755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 17855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 17955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 18055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_dup() { 18155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(StackAt(0)); 18255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 18355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 18455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 18555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 18655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_drop() { 18755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris StackPop(); 18855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 18955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 19055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 19155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 19255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_over() { 19355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(StackAt(1)); 19455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 19555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 19655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 19755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 19855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_pick() { 19955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType index = OperandAt(0); 20055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (index > StackSize()) { 20155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_STACK_INDEX_NOT_VALID; 20255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 20355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 20455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(StackAt(index)); 20555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 20655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 20755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 20855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 20955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_swap() { 21055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType old_value = stack_[0]; 21155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = stack_[1]; 21255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[1] = old_value; 21355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 21455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 21555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 21655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 21755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_rot() { 21855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = stack_[0]; 21955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = stack_[1]; 22055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[1] = stack_[2]; 22155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[2] = top; 22255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 22355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 22455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 22555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 22655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_abs() { 22755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris SignedType signed_value = static_cast<SignedType>(stack_[0]); 22855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (signed_value < 0) { 22955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris signed_value = -signed_value; 23055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 23155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = static_cast<AddressType>(signed_value); 23255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 23355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 23455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 23555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 23655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_and() { 23755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 23855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] &= top; 23955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 24055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 24155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 24255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 24355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_div() { 24455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 24555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (top == 0) { 24655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_ILLEGAL_VALUE; 24755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 24855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 24955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris SignedType signed_divisor = static_cast<SignedType>(top); 25055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris SignedType signed_dividend = static_cast<SignedType>(stack_[0]); 25155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = static_cast<AddressType>(signed_dividend / signed_divisor); 25255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 25355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 25455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 25555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 25655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_minus() { 25755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 25855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] -= top; 25955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 26055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 26155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 26255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 26355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_mod() { 26455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 26555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (top == 0) { 26655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_ILLEGAL_VALUE; 26755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 26855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 26955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] %= top; 27055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 27155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 27255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 27355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 27455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_mul() { 27555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 27655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] *= top; 27755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 27855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 27955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 28055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 28155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_neg() { 28255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris SignedType signed_value = static_cast<SignedType>(stack_[0]); 28355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = static_cast<AddressType>(-signed_value); 28455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 28555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 28655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 28755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 28855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_not() { 28955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = ~stack_[0]; 29055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 29155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 29255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 29355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 29455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_or() { 29555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 29655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] |= top; 29755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 29855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 29955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 30055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 30155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_plus() { 30255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 30355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] += top; 30455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 30555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 30655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 30755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 30855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_plus_uconst() { 30955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] += OperandAt(0); 31055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 31155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 31255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 31355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 31455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_shl() { 31555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 31655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] <<= top; 31755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 31855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 31955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 32055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 32155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_shr() { 32255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 32355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] >>= top; 32455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 32555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 32655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 32755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 32855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_shra() { 32955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 33055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris SignedType signed_value = static_cast<SignedType>(stack_[0]) >> top; 33155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = static_cast<AddressType>(signed_value); 33255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 33355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 33455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 33555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 33655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_xor() { 33755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 33855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] ^= top; 33955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 34055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 34155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 34255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 34355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_bra() { 34455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // Requires one stack element. 34555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 34655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris int16_t offset = static_cast<int16_t>(OperandAt(0)); 34755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint64_t cur_offset; 34855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (top != 0) { 34955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris cur_offset = memory_->cur_offset() + offset; 35055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } else { 35155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris cur_offset = memory_->cur_offset() - offset; 35255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 35355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris memory_->set_cur_offset(cur_offset); 35455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 35555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 35655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 35755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 35855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_eq() { 35955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 36055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = bool_to_dwarf_bool(stack_[0] == top); 36155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 36255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 36355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 36455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 36555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_ge() { 36655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 36755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = bool_to_dwarf_bool(stack_[0] >= top); 36855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 36955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 37055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 37155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 37255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_gt() { 37355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 37455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = bool_to_dwarf_bool(stack_[0] > top); 37555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 37655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 37755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 37855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 37955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_le() { 38055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 38155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = bool_to_dwarf_bool(stack_[0] <= top); 38255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 38355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 38455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 38555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 38655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_lt() { 38755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 38855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = bool_to_dwarf_bool(stack_[0] < top); 38955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 39055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 39155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 39255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 39355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_ne() { 39455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 39555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = bool_to_dwarf_bool(stack_[0] != top); 39655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 39755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 39855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 39955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 40055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_skip() { 40155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris int16_t offset = static_cast<int16_t>(OperandAt(0)); 40255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint64_t cur_offset = memory_->cur_offset() + offset; 40355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris memory_->set_cur_offset(cur_offset); 40455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 40555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 40655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 40755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 40855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_lit() { 40955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(cur_op() - 0x30); 41055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 41155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 41255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 41355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 41455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_reg() { 41555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris is_register_ = true; 41655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(cur_op() - 0x50); 41755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 41855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 41955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 42055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 42155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_regx() { 42255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris is_register_ = true; 42355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(OperandAt(0)); 42455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 42555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 42655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 42755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris// It's not clear for breg/bregx, if this op should read the current 42855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris// value of the register, or where we think that register is located. 42955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris// For simplicity, the code will read the value before doing the unwind. 43055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 43155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_breg() { 43255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint16_t reg = cur_op() - 0x70; 43355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (reg >= regs_->total_regs()) { 43455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_ILLEGAL_VALUE; 43555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 43655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 43755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front((*regs_)[reg] + OperandAt(0)); 43855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 43955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 44055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 44155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 44255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_bregx() { 44355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType reg = OperandAt(0); 44455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (reg >= regs_->total_regs()) { 44555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_ILLEGAL_VALUE; 44655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 44755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 44855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front((*regs_)[reg] + OperandAt(1)); 44955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 45055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 45155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 45255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 45355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_nop() { 45455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 45555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 45655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 45755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 45855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_not_implemented() { 45955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_NOT_IMPLEMENTED; 46055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 46155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 46255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 46355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris// Explicitly instantiate DwarfOp. 46455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate class DwarfOp<uint32_t>; 46555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate class DwarfOp<uint64_t>; 466d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris 467d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris} // namespace unwindstack 468