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