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> 39559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferrisbool DwarfOp<AddressType>::Eval(uint64_t start, uint64_t end) { 4055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris is_register_ = false; 4155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.clear(); 4255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris memory_->set_cur_offset(start); 43559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris dex_pc_set_ = false; 44559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris 45559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris // Unroll the first Decode calls to be able to check for a special 46559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris // sequence of ops and values that indicate this is the dex pc. 47559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris // The pattern is: 48559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris // OP_const4u (0x0c) 'D' 'E' 'X' '1' 49559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris // OP_drop (0x13) 50559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris if (memory_->cur_offset() < end) { 51559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris if (!Decode()) { 52559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris return false; 53559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris } 54559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris } else { 55559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris return true; 56559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris } 57559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris bool check_for_drop; 58559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris if (cur_op_ == 0x0c && operands_.back() == 0x31584544) { 59559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris check_for_drop = true; 60559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris } else { 61559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris check_for_drop = false; 62559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris } 63559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris if (memory_->cur_offset() < end) { 64559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris if (!Decode()) { 65559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris return false; 66559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris } 67559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris } else { 68559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris return true; 69559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris } 70559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris 71559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris if (check_for_drop && cur_op_ == 0x13) { 72559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris dex_pc_set_ = true; 73559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris } 74559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris 75559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris uint32_t iterations = 2; 7655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris while (memory_->cur_offset() < end) { 77559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris if (!Decode()) { 7855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 7955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 8055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // To protect against a branch that creates an infinite loop, 8155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // terminate if the number of iterations gets too high. 8255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (iterations++ == 1000) { 832fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_TOO_MANY_ITERATIONS; 8455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 8555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 8655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 8755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 8855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 8955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 9055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 91559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferrisbool DwarfOp<AddressType>::Decode() { 922fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_NONE; 9355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!memory_->ReadBytes(&cur_op_, 1)) { 942fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_MEMORY_INVALID; 952fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.address = memory_->cur_offset(); 9655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 9755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 9855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 9955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris const auto* op = &kCallbackTable[cur_op_]; 10055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris const auto handle_func = op->handle_func; 10155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (handle_func == nullptr) { 1022fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; 10355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 10455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 10555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 10655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // Make sure that the required number of stack elements is available. 10755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (stack_.size() < op->num_required_stack_values) { 1082fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_STACK_INDEX_NOT_VALID; 10955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 11055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 11155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 11255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris operands_.clear(); 11355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris for (size_t i = 0; i < op->num_operands; i++) { 11455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint64_t value; 11555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!memory_->ReadEncodedValue<AddressType>(op->operands[i], &value)) { 1162fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_MEMORY_INVALID; 1172fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.address = memory_->cur_offset(); 11855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 11955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 12055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris operands_.push_back(value); 12155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 12255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return (this->*handle_func)(); 12355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 12455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 12555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 12655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisvoid DwarfOp<AddressType>::GetLogInfo(uint64_t start, uint64_t end, 12755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris std::vector<std::string>* lines) { 12855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris memory_->set_cur_offset(start); 12955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris while (memory_->cur_offset() < end) { 13055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint8_t cur_op; 13155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!memory_->ReadBytes(&cur_op, 1)) { 13255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return; 13355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 13455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 13555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris std::string raw_string(android::base::StringPrintf("Raw Data: 0x%02x", cur_op)); 13655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris std::string log_string; 13755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris const auto* op = &kCallbackTable[cur_op]; 13855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (op->handle_func == nullptr) { 13955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris log_string = "Illegal"; 14055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } else { 14155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris log_string = op->name; 14255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint64_t start_offset = memory_->cur_offset(); 14355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris for (size_t i = 0; i < op->num_operands; i++) { 14455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint64_t value; 14555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!memory_->ReadEncodedValue<AddressType>(op->operands[i], &value)) { 14655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return; 14755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 14855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris log_string += ' ' + std::to_string(value); 14955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 15055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint64_t end_offset = memory_->cur_offset(); 15155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 15255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris memory_->set_cur_offset(start_offset); 15355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris for (size_t i = start_offset; i < end_offset; i++) { 15455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint8_t byte; 15555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (!memory_->ReadBytes(&byte, 1)) { 15655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return; 15755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 15855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris raw_string += android::base::StringPrintf(" 0x%02x", byte); 15955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 16055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris memory_->set_cur_offset(end_offset); 16155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 16255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris lines->push_back(std::move(log_string)); 16355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris lines->push_back(std::move(raw_string)); 16455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 16555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 16655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 16755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 16855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_deref() { 16955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // Read the address and dereference it. 17055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType addr = StackPop(); 17155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType value; 172ef35aa5d40b6404baf702a58527f1cd3a9f42f19Josh Gao if (!regular_memory()->ReadFully(addr, &value, sizeof(value))) { 1732fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_MEMORY_INVALID; 1742fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.address = addr; 17555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 17655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 17755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(value); 17855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 17955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 18055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 18155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 18255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_deref_size() { 18355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType bytes_to_read = OperandAt(0); 18455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (bytes_to_read > sizeof(AddressType) || bytes_to_read == 0) { 1852fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; 18655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 18755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 18855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // Read the address and dereference it. 18955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType addr = StackPop(); 19055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType value = 0; 191ef35aa5d40b6404baf702a58527f1cd3a9f42f19Josh Gao if (!regular_memory()->ReadFully(addr, &value, bytes_to_read)) { 1922fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_MEMORY_INVALID; 1932fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.address = addr; 19455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 19555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 19655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(value); 19755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 19855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 19955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 20055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 20155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_push() { 20255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // Push all of the operands. 20355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris for (auto operand : operands_) { 20455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(operand); 20555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 20655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 20755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 20855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 20955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 21055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_dup() { 21155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(StackAt(0)); 21255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 21355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 21455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 21555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 21655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_drop() { 21755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris StackPop(); 21855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 21955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 22055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 22155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 22255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_over() { 22355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(StackAt(1)); 22455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 22555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 22655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 22755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 22855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_pick() { 22955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType index = OperandAt(0); 23055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (index > StackSize()) { 2312fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_STACK_INDEX_NOT_VALID; 23255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 23355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 23455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(StackAt(index)); 23555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 23655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 23755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 23855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 23955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_swap() { 24055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType old_value = stack_[0]; 24155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = stack_[1]; 24255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[1] = old_value; 24355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 24455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 24555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 24655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 24755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_rot() { 24855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = stack_[0]; 24955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = stack_[1]; 25055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[1] = stack_[2]; 25155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[2] = top; 25255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 25355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 25455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 25555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 25655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_abs() { 25755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris SignedType signed_value = static_cast<SignedType>(stack_[0]); 25855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (signed_value < 0) { 25955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris signed_value = -signed_value; 26055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 26155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = static_cast<AddressType>(signed_value); 26255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 26355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 26455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 26555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 26655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_and() { 26755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 26855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] &= top; 26955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 27055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 27155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 27255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 27355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_div() { 27455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 27555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (top == 0) { 2762fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; 27755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 27855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 27955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris SignedType signed_divisor = static_cast<SignedType>(top); 28055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris SignedType signed_dividend = static_cast<SignedType>(stack_[0]); 28155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = static_cast<AddressType>(signed_dividend / signed_divisor); 28255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 28355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 28455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 28555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 28655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_minus() { 28755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 28855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] -= top; 28955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 29055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 29155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 29255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 29355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_mod() { 29455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 29555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (top == 0) { 2962fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; 29755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 29855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 29955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] %= top; 30055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 30155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 30255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 30355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 30455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_mul() { 30555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 30655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] *= top; 30755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 30855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 30955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 31055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 31155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_neg() { 31255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris SignedType signed_value = static_cast<SignedType>(stack_[0]); 31355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = static_cast<AddressType>(-signed_value); 31455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 31555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 31655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 31755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 31855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_not() { 31955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = ~stack_[0]; 32055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 32155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 32255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 32355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 32455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_or() { 32555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 32655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] |= top; 32755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 32855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 32955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 33055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 33155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_plus() { 33255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 33355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] += top; 33455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 33555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 33655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 33755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 33855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_plus_uconst() { 33955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] += OperandAt(0); 34055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 34155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 34255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 34355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 34455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_shl() { 34555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 34655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] <<= top; 34755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 34855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 34955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 35055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 35155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_shr() { 35255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 35355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] >>= top; 35455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 35555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 35655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 35755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 35855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_shra() { 35955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 36055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris SignedType signed_value = static_cast<SignedType>(stack_[0]) >> top; 36155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = static_cast<AddressType>(signed_value); 36255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 36355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 36455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 36555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 36655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_xor() { 36755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 36855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] ^= top; 36955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 37055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 37155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 37255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 37355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_bra() { 37455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris // Requires one stack element. 37555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 37655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris int16_t offset = static_cast<int16_t>(OperandAt(0)); 37755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint64_t cur_offset; 37855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris if (top != 0) { 37955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris cur_offset = memory_->cur_offset() + offset; 38055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } else { 38155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris cur_offset = memory_->cur_offset() - offset; 38255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 38355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris memory_->set_cur_offset(cur_offset); 38455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 38555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 38655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 38755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 38855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_eq() { 38955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 39055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = bool_to_dwarf_bool(stack_[0] == top); 39155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 39255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 39355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 39455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 39555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_ge() { 39655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 39755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = bool_to_dwarf_bool(stack_[0] >= top); 39855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 39955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 40055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 40155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 40255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_gt() { 40355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 40455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = bool_to_dwarf_bool(stack_[0] > top); 40555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 40655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 40755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 40855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 40955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_le() { 41055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 41155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = bool_to_dwarf_bool(stack_[0] <= top); 41255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 41355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 41455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 41555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 41655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_lt() { 41755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 41855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = bool_to_dwarf_bool(stack_[0] < top); 41955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 42055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 42155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 42255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 42355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_ne() { 42455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType top = StackPop(); 42555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_[0] = bool_to_dwarf_bool(stack_[0] != top); 42655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 42755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 42855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 42955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 43055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_skip() { 43155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris int16_t offset = static_cast<int16_t>(OperandAt(0)); 43255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint64_t cur_offset = memory_->cur_offset() + offset; 43355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris memory_->set_cur_offset(cur_offset); 43455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 43555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 43655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 43755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 43855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_lit() { 43955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(cur_op() - 0x30); 44055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 44155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 44255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 44355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 44455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_reg() { 44555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris is_register_ = true; 44655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(cur_op() - 0x50); 44755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 44855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 44955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 45055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 45155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_regx() { 45255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris is_register_ = true; 45355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris stack_.push_front(OperandAt(0)); 45455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 45555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 45655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 45755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris// It's not clear for breg/bregx, if this op should read the current 45855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris// value of the register, or where we think that register is located. 45955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris// For simplicity, the code will read the value before doing the unwind. 46055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 46155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_breg() { 46255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris uint16_t reg = cur_op() - 0x70; 463559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris if (reg >= regs_info_->Total()) { 4642fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; 46555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 46655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 467559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris stack_.push_front(regs_info_->Get(reg) + OperandAt(0)); 46855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 46955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 47055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 47155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 47255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_bregx() { 47355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris AddressType reg = OperandAt(0); 474559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris if (reg >= regs_info_->Total()) { 4752fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_ILLEGAL_VALUE; 47655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 47755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris } 478559c7f209295a7070515bba9fa3985edf53d13a0Christopher Ferris stack_.push_front(regs_info_->Get(reg) + OperandAt(1)); 47955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 48055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 48155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 48255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 48355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_nop() { 48455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return true; 48555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 48655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 48755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename AddressType> 48855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisbool DwarfOp<AddressType>::op_not_implemented() { 4892fcf4cf13e9aefa8c312084af12ca2d712a6ead3Christopher Ferris last_error_.code = DWARF_ERROR_NOT_IMPLEMENTED; 49055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris return false; 49155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris} 49255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris 49355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris// Explicitly instantiate DwarfOp. 49455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate class DwarfOp<uint32_t>; 49555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate class DwarfOp<uint64_t>; 496d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris 497d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris} // namespace unwindstack 498