DwarfOp.cpp revision 2fcf4cf13e9aefa8c312084af12ca2d712a6ead3
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 252fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris#include <unwindstack/DwarfError.h> 26d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris#include <unwindstack/DwarfMemory.h> 27d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris#include <unwindstack/Log.h> 28d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris#include <unwindstack/Memory.h> 29d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris#include <unwindstack/Regs.h> 30d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris 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) { 512fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = 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) { 602fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_NONE; 6155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!memory_->ReadBytes(&cur_op_, 1)) { 622fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_MEMORY_INVALID; 632fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.address = memory_->cur_offset(); 6455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 6555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 6655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 6755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris const auto* op = &kCallbackTable[cur_op_]; 6855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris const auto handle_func = op->handle_func; 6955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (handle_func == nullptr) { 702fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; 7155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 7255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 7355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 7455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // Check for an unsupported opcode. 7555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (dwarf_version < op->supported_version) { 762fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; 7755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 7855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 7955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 8055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // Make sure that the required number of stack elements is available. 8155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (stack_.size() < op->num_required_stack_values) { 822fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_STACK_INDEX_NOT_VALID; 8355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 8455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 8555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 8655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris operands_.clear(); 8755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris for (size_t i = 0; i < op->num_operands; i++) { 8855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint64_t value; 8955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!memory_->ReadEncodedValue<AddressType>(op->operands[i], &value)) { 902fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_MEMORY_INVALID; 912fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.address = memory_->cur_offset(); 9255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 9355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 9455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris operands_.push_back(value); 9555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 9655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return (this->*handle_func)(); 9755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 9855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 9955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 10055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisvoid DwarfOp<AddressType>::GetLogInfo(uint64_t start, uint64_t end, 10155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris std::vector<std::string>* lines) { 10255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris memory_->set_cur_offset(start); 10355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris while (memory_->cur_offset() < end) { 10455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint8_t cur_op; 10555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!memory_->ReadBytes(&cur_op, 1)) { 10655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return; 10755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 10855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 10955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris std::string raw_string(android::base::StringPrintf("Raw Data: 0x%02x", cur_op)); 11055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris std::string log_string; 11155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris const auto* op = &kCallbackTable[cur_op]; 11255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (op->handle_func == nullptr) { 11355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris log_string = "Illegal"; 11455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } else { 11555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris log_string = op->name; 11655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint64_t start_offset = memory_->cur_offset(); 11755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris for (size_t i = 0; i < op->num_operands; i++) { 11855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint64_t value; 11955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!memory_->ReadEncodedValue<AddressType>(op->operands[i], &value)) { 12055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return; 12155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 12255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris log_string += ' ' + std::to_string(value); 12355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 12455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint64_t end_offset = memory_->cur_offset(); 12555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 12655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris memory_->set_cur_offset(start_offset); 12755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris for (size_t i = start_offset; i < end_offset; i++) { 12855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint8_t byte; 12955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!memory_->ReadBytes(&byte, 1)) { 13055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return; 13155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 13255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris raw_string += android::base::StringPrintf(" 0x%02x", byte); 13355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 13455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris memory_->set_cur_offset(end_offset); 13555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 13655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris lines->push_back(std::move(log_string)); 13755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris lines->push_back(std::move(raw_string)); 13855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 13955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 14055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 14155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 14255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_deref() { 14355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // Read the address and dereference it. 14455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType addr = StackPop(); 14555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType value; 146ef35aa5d40b6404baf702a58527f1cd3a9f42f19Josh Gao if (!regular_memory()->ReadFully(addr, &value, sizeof(value))) { 1472fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_MEMORY_INVALID; 1482fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.address = addr; 14955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 15055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 15155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(value); 15255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 15355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 15455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 15555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 15655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_deref_size() { 15755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType bytes_to_read = OperandAt(0); 15855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (bytes_to_read > sizeof(AddressType) || bytes_to_read == 0) { 1592fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; 16055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 16155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 16255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // Read the address and dereference it. 16355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType addr = StackPop(); 16455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType value = 0; 165ef35aa5d40b6404baf702a58527f1cd3a9f42f19Josh Gao if (!regular_memory()->ReadFully(addr, &value, bytes_to_read)) { 1662fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_MEMORY_INVALID; 1672fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.address = addr; 16855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 16955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 17055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(value); 17155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 17255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 17355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 17455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 17555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_push() { 17655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // Push all of the operands. 17755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris for (auto operand : operands_) { 17855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(operand); 17955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 18055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 18155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 18255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 18355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 18455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_dup() { 18555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(StackAt(0)); 18655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 18755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 18855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 18955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 19055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_drop() { 19155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris StackPop(); 19255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 19355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 19455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 19555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 19655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_over() { 19755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(StackAt(1)); 19855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 19955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 20055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 20155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 20255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_pick() { 20355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType index = OperandAt(0); 20455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (index > StackSize()) { 2052fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_STACK_INDEX_NOT_VALID; 20655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 20755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 20855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(StackAt(index)); 20955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 21055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 21155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 21255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 21355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_swap() { 21455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType old_value = stack_[0]; 21555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = stack_[1]; 21655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[1] = old_value; 21755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 21855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 21955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 22055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 22155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_rot() { 22255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = stack_[0]; 22355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = stack_[1]; 22455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[1] = stack_[2]; 22555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[2] = top; 22655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 22755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 22855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 22955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 23055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_abs() { 23155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris SignedType signed_value = static_cast<SignedType>(stack_[0]); 23255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (signed_value < 0) { 23355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris signed_value = -signed_value; 23455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 23555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = static_cast<AddressType>(signed_value); 23655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 23755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 23855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 23955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 24055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_and() { 24155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 24255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] &= top; 24355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 24455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 24555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 24655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 24755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_div() { 24855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 24955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (top == 0) { 2502fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; 25155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 25255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 25355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris SignedType signed_divisor = static_cast<SignedType>(top); 25455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris SignedType signed_dividend = static_cast<SignedType>(stack_[0]); 25555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = static_cast<AddressType>(signed_dividend / signed_divisor); 25655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 25755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 25855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 25955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 26055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_minus() { 26155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 26255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] -= top; 26355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 26455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 26555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 26655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 26755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_mod() { 26855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 26955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (top == 0) { 2702fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; 27155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 27255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 27355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] %= top; 27455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 27555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 27655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 27755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 27855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_mul() { 27955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 28055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] *= top; 28155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 28255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 28355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 28455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 28555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_neg() { 28655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris SignedType signed_value = static_cast<SignedType>(stack_[0]); 28755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = static_cast<AddressType>(-signed_value); 28855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 28955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 29055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 29155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 29255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_not() { 29355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = ~stack_[0]; 29455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 29555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 29655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 29755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 29855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_or() { 29955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 30055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] |= top; 30155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 30255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 30355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 30455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 30555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_plus() { 30655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 30755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] += top; 30855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 30955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 31055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 31155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 31255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_plus_uconst() { 31355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] += OperandAt(0); 31455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 31555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 31655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 31755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 31855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_shl() { 31955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 32055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] <<= top; 32155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 32255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 32355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 32455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 32555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_shr() { 32655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 32755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] >>= top; 32855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 32955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 33055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 33155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 33255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_shra() { 33355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 33455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris SignedType signed_value = static_cast<SignedType>(stack_[0]) >> top; 33555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = static_cast<AddressType>(signed_value); 33655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 33755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 33855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 33955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 34055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_xor() { 34155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 34255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] ^= top; 34355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 34455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 34555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 34655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 34755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_bra() { 34855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // Requires one stack element. 34955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 35055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris int16_t offset = static_cast<int16_t>(OperandAt(0)); 35155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint64_t cur_offset; 35255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (top != 0) { 35355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris cur_offset = memory_->cur_offset() + offset; 35455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } else { 35555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris cur_offset = memory_->cur_offset() - offset; 35655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 35755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris memory_->set_cur_offset(cur_offset); 35855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 35955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 36055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 36155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 36255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_eq() { 36355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 36455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = bool_to_dwarf_bool(stack_[0] == top); 36555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 36655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 36755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 36855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 36955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_ge() { 37055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 37155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = bool_to_dwarf_bool(stack_[0] >= top); 37255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 37355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 37455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 37555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 37655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_gt() { 37755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 37855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = bool_to_dwarf_bool(stack_[0] > top); 37955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 38055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 38155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 38255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 38355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_le() { 38455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 38555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = bool_to_dwarf_bool(stack_[0] <= top); 38655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 38755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 38855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 38955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 39055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_lt() { 39155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 39255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = bool_to_dwarf_bool(stack_[0] < top); 39355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 39455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 39555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 39655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 39755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_ne() { 39855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 39955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = bool_to_dwarf_bool(stack_[0] != top); 40055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 40155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 40255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 40355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 40455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_skip() { 40555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris int16_t offset = static_cast<int16_t>(OperandAt(0)); 40655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint64_t cur_offset = memory_->cur_offset() + offset; 40755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris memory_->set_cur_offset(cur_offset); 40855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 40955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 41055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 41155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 41255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_lit() { 41355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(cur_op() - 0x30); 41455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 41555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 41655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 41755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 41855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_reg() { 41955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris is_register_ = true; 42055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(cur_op() - 0x50); 42155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 42255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 42355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 42455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 42555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_regx() { 42655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris is_register_ = true; 42755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(OperandAt(0)); 42855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 42955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 43055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 43155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris// It's not clear for breg/bregx, if this op should read the current 43255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris// value of the register, or where we think that register is located. 43355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris// For simplicity, the code will read the value before doing the unwind. 43455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 43555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_breg() { 43655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint16_t reg = cur_op() - 0x70; 43755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (reg >= regs_->total_regs()) { 4382fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; 43955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 44055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 44155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front((*regs_)[reg] + OperandAt(0)); 44255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 44355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 44455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 44555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 44655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_bregx() { 44755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType reg = OperandAt(0); 44855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (reg >= regs_->total_regs()) { 4492fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; 45055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 45155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 45255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front((*regs_)[reg] + OperandAt(1)); 45355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 45455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 45555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 45655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 45755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_nop() { 45855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 45955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 46055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 46155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 46255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_not_implemented() { 4632fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_NOT_IMPLEMENTED; 46455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 46555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 46655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 46755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris// Explicitly instantiate DwarfOp. 46855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate class DwarfOp<uint32_t>; 46955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate class DwarfOp<uint64_t>; 470d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris 471d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris} // namespace unwindstack 472