DwarfOp.cpp revision 55d22ef67c428a3f0994ee7da51b33c79ddcc552
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 2555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris#include "DwarfError.h" 2655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris#include "DwarfMemory.h" 2755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris#include "DwarfOp.h" 2855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris#include "Log.h" 2955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris#include "Memory.h" 3055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris#include "Regs.h" 3155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 3255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 3355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisconstexpr typename DwarfOp<AddressType>::OpCallback DwarfOp<AddressType>::kCallbackTable[256]; 3455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 3555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 3655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::Eval(uint64_t start, uint64_t end, uint8_t dwarf_version) { 3755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint32_t iterations = 0; 3855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris is_register_ = false; 3955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.clear(); 4055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris memory_->set_cur_offset(start); 4155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris while (memory_->cur_offset() < end) { 4255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!Decode(dwarf_version)) { 4355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 4455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 4555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // To protect against a branch that creates an infinite loop, 4655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // terminate if the number of iterations gets too high. 4755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (iterations++ == 1000) { 4855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_TOO_MANY_ITERATIONS; 4955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 5055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 5155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 5255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 5355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 5455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 5555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 5655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::Decode(uint8_t dwarf_version) { 5755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_NONE; 5855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!memory_->ReadBytes(&cur_op_, 1)) { 5955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_MEMORY_INVALID; 6055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 6155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 6255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 6355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris const auto* op = &kCallbackTable[cur_op_]; 6455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris const auto handle_func = op->handle_func; 6555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (handle_func == nullptr) { 6655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_ILLEGAL_VALUE; 6755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 6855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 6955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 7055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // Check for an unsupported opcode. 7155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (dwarf_version < op->supported_version) { 7255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_ILLEGAL_VALUE; 7355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 7455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 7555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 7655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // Make sure that the required number of stack elements is available. 7755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (stack_.size() < op->num_required_stack_values) { 7855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_STACK_INDEX_NOT_VALID; 7955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 8055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 8155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 8255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris operands_.clear(); 8355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris for (size_t i = 0; i < op->num_operands; i++) { 8455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint64_t value; 8555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!memory_->ReadEncodedValue<AddressType>(op->operands[i], &value)) { 8655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_MEMORY_INVALID; 8755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 8855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 8955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris operands_.push_back(value); 9055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 9155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return (this->*handle_func)(); 9255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 9355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 9455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 9555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisvoid DwarfOp<AddressType>::GetLogInfo(uint64_t start, uint64_t end, 9655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris std::vector<std::string>* lines) { 9755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris memory_->set_cur_offset(start); 9855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris while (memory_->cur_offset() < end) { 9955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint8_t cur_op; 10055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!memory_->ReadBytes(&cur_op, 1)) { 10155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return; 10255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 10355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 10455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris std::string raw_string(android::base::StringPrintf("Raw Data: 0x%02x", cur_op)); 10555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris std::string log_string; 10655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris const auto* op = &kCallbackTable[cur_op]; 10755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (op->handle_func == nullptr) { 10855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris log_string = "Illegal"; 10955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } else { 11055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris log_string = op->name; 11155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint64_t start_offset = memory_->cur_offset(); 11255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris for (size_t i = 0; i < op->num_operands; i++) { 11355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint64_t value; 11455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!memory_->ReadEncodedValue<AddressType>(op->operands[i], &value)) { 11555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return; 11655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 11755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris log_string += ' ' + std::to_string(value); 11855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 11955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint64_t end_offset = memory_->cur_offset(); 12055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 12155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris memory_->set_cur_offset(start_offset); 12255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris for (size_t i = start_offset; i < end_offset; i++) { 12355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint8_t byte; 12455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!memory_->ReadBytes(&byte, 1)) { 12555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return; 12655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 12755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris raw_string += android::base::StringPrintf(" 0x%02x", byte); 12855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 12955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris memory_->set_cur_offset(end_offset); 13055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 13155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris lines->push_back(std::move(log_string)); 13255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris lines->push_back(std::move(raw_string)); 13355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 13455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 13555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 13655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 13755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_deref() { 13855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // Read the address and dereference it. 13955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType addr = StackPop(); 14055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType value; 14155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!regular_memory()->Read(addr, &value, sizeof(value))) { 14255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_MEMORY_INVALID; 14355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 14455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 14555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(value); 14655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 14755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 14855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 14955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 15055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_deref_size() { 15155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType bytes_to_read = OperandAt(0); 15255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (bytes_to_read > sizeof(AddressType) || bytes_to_read == 0) { 15355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_ILLEGAL_VALUE; 15455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 15555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 15655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // Read the address and dereference it. 15755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType addr = StackPop(); 15855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType value = 0; 15955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!regular_memory()->Read(addr, &value, bytes_to_read)) { 16055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_MEMORY_INVALID; 16155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 16255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 16355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(value); 16455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 16555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 16655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 16755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 16855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_push() { 16955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // Push all of the operands. 17055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris for (auto operand : operands_) { 17155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(operand); 17255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 17355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 17455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 17555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 17655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 17755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_dup() { 17855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(StackAt(0)); 17955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 18055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 18155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 18255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 18355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_drop() { 18455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris StackPop(); 18555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 18655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 18755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 18855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 18955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_over() { 19055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(StackAt(1)); 19155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 19255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 19355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 19455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 19555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_pick() { 19655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType index = OperandAt(0); 19755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (index > StackSize()) { 19855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_STACK_INDEX_NOT_VALID; 19955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 20055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 20155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(StackAt(index)); 20255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 20355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 20455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 20555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 20655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_swap() { 20755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType old_value = stack_[0]; 20855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = stack_[1]; 20955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[1] = old_value; 21055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 21155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 21255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 21355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 21455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_rot() { 21555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = stack_[0]; 21655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = stack_[1]; 21755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[1] = stack_[2]; 21855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[2] = top; 21955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 22055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 22155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 22255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 22355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_abs() { 22455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris SignedType signed_value = static_cast<SignedType>(stack_[0]); 22555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (signed_value < 0) { 22655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris signed_value = -signed_value; 22755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 22855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = static_cast<AddressType>(signed_value); 22955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 23055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 23155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 23255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 23355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_and() { 23455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 23555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] &= top; 23655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 23755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 23855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 23955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 24055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_div() { 24155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 24255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (top == 0) { 24355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_ILLEGAL_VALUE; 24455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 24555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 24655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris SignedType signed_divisor = static_cast<SignedType>(top); 24755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris SignedType signed_dividend = static_cast<SignedType>(stack_[0]); 24855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = static_cast<AddressType>(signed_dividend / signed_divisor); 24955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 25055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 25155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 25255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 25355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_minus() { 25455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 25555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] -= top; 25655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 25755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 25855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 25955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 26055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_mod() { 26155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 26255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (top == 0) { 26355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_ILLEGAL_VALUE; 26455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 26555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 26655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] %= top; 26755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 26855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 26955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 27055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 27155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_mul() { 27255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 27355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] *= top; 27455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 27555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 27655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 27755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 27855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_neg() { 27955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris SignedType signed_value = static_cast<SignedType>(stack_[0]); 28055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = static_cast<AddressType>(-signed_value); 28155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 28255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 28355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 28455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 28555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_not() { 28655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = ~stack_[0]; 28755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 28855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 28955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 29055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 29155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_or() { 29255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 29355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] |= top; 29455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 29555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 29655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 29755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 29855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_plus() { 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_uconst() { 30655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] += OperandAt(0); 30755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 30855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 30955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 31055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 31155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_shl() { 31255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 31355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] <<= top; 31455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 31555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 31655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 31755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 31855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_shr() { 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_shra() { 32655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 32755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris SignedType signed_value = static_cast<SignedType>(stack_[0]) >> top; 32855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = static_cast<AddressType>(signed_value); 32955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 33055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 33155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 33255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 33355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_xor() { 33455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 33555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] ^= top; 33655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 33755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 33855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 33955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 34055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_bra() { 34155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // Requires one stack element. 34255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 34355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris int16_t offset = static_cast<int16_t>(OperandAt(0)); 34455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint64_t cur_offset; 34555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (top != 0) { 34655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris cur_offset = memory_->cur_offset() + offset; 34755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } else { 34855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris cur_offset = memory_->cur_offset() - offset; 34955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 35055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris memory_->set_cur_offset(cur_offset); 35155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 35255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 35355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 35455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 35555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_eq() { 35655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 35755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = bool_to_dwarf_bool(stack_[0] == top); 35855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 35955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 36055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 36155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 36255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_ge() { 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_gt() { 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_le() { 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_lt() { 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_ne() { 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_skip() { 39855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris int16_t offset = static_cast<int16_t>(OperandAt(0)); 39955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint64_t cur_offset = memory_->cur_offset() + offset; 40055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris memory_->set_cur_offset(cur_offset); 40155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 40255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 40355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 40455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 40555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_lit() { 40655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(cur_op() - 0x30); 40755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 40855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 40955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 41055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 41155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_reg() { 41255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris is_register_ = true; 41355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(cur_op() - 0x50); 41455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 41555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 41655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 41755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 41855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_regx() { 41955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris is_register_ = true; 42055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(OperandAt(0)); 42155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 42255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 42355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 42455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris// It's not clear for breg/bregx, if this op should read the current 42555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris// value of the register, or where we think that register is located. 42655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris// For simplicity, the code will read the value before doing the unwind. 42755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 42855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_breg() { 42955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint16_t reg = cur_op() - 0x70; 43055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (reg >= regs_->total_regs()) { 43155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_ILLEGAL_VALUE; 43255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 43355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 43455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front((*regs_)[reg] + OperandAt(0)); 43555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 43655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 43755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 43855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 43955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_bregx() { 44055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType reg = OperandAt(0); 44155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (reg >= regs_->total_regs()) { 44255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_ILLEGAL_VALUE; 44355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 44455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 44555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front((*regs_)[reg] + OperandAt(1)); 44655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 44755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 44855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 44955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 45055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_nop() { 45155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 45255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 45355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 45455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 45555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_not_implemented() { 45655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris last_error_ = DWARF_ERROR_NOT_IMPLEMENTED; 45755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 45855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 45955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 46055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris// Explicitly instantiate DwarfOp. 46155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate class DwarfOp<uint32_t>; 46255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate class DwarfOp<uint64_t>; 463