155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris/*
255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris * Copyright (C) 2016 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 <ios>
2055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris#include <vector>
2155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
2255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris#include <gtest/gtest.h>
2355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
24d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris#include <unwindstack/DwarfMemory.h>
25d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris#include <unwindstack/Log.h>
26d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris
2755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris#include "DwarfError.h"
2855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris#include "DwarfOp.h"
2955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
3055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris#include "MemoryFake.h"
3153a3c9b4ab57f04b46bc3abf42e36bdfa821f7f3Christopher Ferris#include "RegsFake.h"
3255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
33d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferrisnamespace unwindstack {
34d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris
3555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristemplate <typename TypeParam>
3655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferrisclass DwarfOpTest : public ::testing::Test {
3755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris protected:
3855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  void SetUp() override {
3955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    op_memory_.Clear();
4055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    regular_memory_.Clear();
4155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    mem_.reset(new DwarfMemory(&op_memory_));
4255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    op_.reset(new DwarfOp<TypeParam>(mem_.get(), &regular_memory_));
4355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
4455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
4555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  MemoryFake op_memory_;
4655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  MemoryFake regular_memory_;
4755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
4855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::unique_ptr<DwarfMemory> mem_;
4955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::unique_ptr<DwarfOp<TypeParam>> op_;
5055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris};
5155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_CASE_P(DwarfOpTest);
5255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
5355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, decode) {
5455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Memory error.
5555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
5655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_MEMORY_INVALID, this->op_->last_error());
5755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
5855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // No error.
5955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x96});
6055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->mem_->set_cur_offset(0);
6155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
6255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_NONE, this->op_->last_error());
6355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x96U, this->op_->cur_op());
6455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->mem_->cur_offset());
6555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
6655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
6755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, eval) {
6855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Memory error.
6955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Eval(0, 2, DWARF_VERSION_MAX));
7055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_MEMORY_INVALID, this->op_->last_error());
7155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
7255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Register set.
7355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Do this first, to verify that subsequent calls reset the value.
7455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x50});
7555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Eval(0, 1, DWARF_VERSION_MAX));
7655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->is_register());
7755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->mem_->cur_offset());
7855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
7955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
8055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Multi operation opcodes.
8155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
8255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x04, 0x08, 0x03, 0x08, 0x02, 0x08, 0x01,
8355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
8455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
8555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
8655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Eval(0, 8, DWARF_VERSION_MAX));
8755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_NONE, this->op_->last_error());
8855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->is_register());
8955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(8U, this->mem_->cur_offset());
9055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(4U, this->op_->StackSize());
9155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackAt(0));
9255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackAt(1));
9355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(3U, this->op_->StackAt(2));
9455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(4U, this->op_->StackAt(3));
9555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
9655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Infinite loop.
9755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x2f, 0xfd, 0xff});
9855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Eval(0, 4, DWARF_VERSION_MAX));
9955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_TOO_MANY_ITERATIONS, this->op_->last_error());
10055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->is_register());
10155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0U, this->op_->StackSize());
10255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
10355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
10455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, illegal_opcode) {
10555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Fill the buffer with all of the illegal opcodes.
10655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {0x00, 0x01, 0x02, 0x04, 0x05, 0x07};
10755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  for (size_t opcode = 0xa0; opcode < 256; opcode++) {
10855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(opcode);
10955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
11055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
11155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
11255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  for (size_t i = 0; i < opcode_buffer.size(); i++) {
11355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
11455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->last_error());
11555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(opcode_buffer[i], this->op_->cur_op());
11655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
11755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
11855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
11955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, illegal_in_version3) {
12055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d};
12155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
12255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
12355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  for (size_t i = 0; i < opcode_buffer.size(); i++) {
12455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_FALSE(this->op_->Decode(2));
12555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->last_error());
12655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(opcode_buffer[i], this->op_->cur_op());
12755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
12855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
12955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
13055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, illegal_in_version4) {
13155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {0x9e, 0x9f};
13255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
13355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
13455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  for (size_t i = 0; i < opcode_buffer.size(); i++) {
13555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_FALSE(this->op_->Decode(3));
13655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->last_error());
13755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(opcode_buffer[i], this->op_->cur_op());
13855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
13955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
14055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
14155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, not_implemented) {
14255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
14355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push values so that any not implemented ops will return the right error.
14455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x03, 0x08, 0x02, 0x08, 0x01,
14555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // xderef
14655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x18,
14755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // fbreg
14855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x91, 0x01,
14955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // piece
15055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x93, 0x01,
15155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // xderef_size
15255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x95, 0x01,
15355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // push_object_address
15455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x97,
15555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // call2
15655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x98, 0x01, 0x02,
15755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // call4
15855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x99, 0x01, 0x02, 0x03, 0x04,
15955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // call_ref
16055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x9a,
16155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // form_tls_address
16255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x9b,
16355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // call_frame_cfa
16455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x9c,
16555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // bit_piece
16655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x9d, 0x01, 0x01,
16755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // implicit_value
16855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x9e, 0x01,
16955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // stack_value
17055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x9f,
17155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
17255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
17355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
17455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Push the stack values.
17555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
17655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
17755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
17855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
17955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  while (this->mem_->cur_offset() < opcode_buffer.size()) {
18055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
18155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(DWARF_ERROR_NOT_IMPLEMENTED, this->op_->last_error());
18255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
18355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
18455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
18555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_addr) {
18655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {0x03, 0x12, 0x23, 0x34, 0x45};
18755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  if (sizeof(TypeParam) == 8) {
18855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(0x56);
18955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(0x67);
19055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(0x78);
19155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(0x89);
19255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
19355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
19455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
19555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
19655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x03, this->op_->cur_op());
19755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
19855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  if (sizeof(TypeParam) == 4) {
19955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(0x45342312U, this->op_->StackAt(0));
20055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  } else {
20155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(0x8978675645342312UL, this->op_->StackAt(0));
20255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
20355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
20455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
20555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_deref) {
20655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
20755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Try a dereference with nothing on the stack.
20855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x06,
20955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Add an address, then dereference.
21055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x0a, 0x10, 0x20, 0x06,
21155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Now do another dereference that should fail in memory.
21255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x06,
21355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
21455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
21555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  TypeParam value = 0x12345678;
21655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->regular_memory_.SetMemory(0x2010, &value, sizeof(value));
21755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
21855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
21955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
22055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
22155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
22255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
22355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
22455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x06, this->op_->cur_op());
22555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
22655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(value, this->op_->StackAt(0));
22755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
22855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
22955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_MEMORY_INVALID, this->op_->last_error());
23055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
23155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
23255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_deref_size) {
23355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x94});
23455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  TypeParam value = 0x12345678;
23555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->regular_memory_.SetMemory(0x2010, &value, sizeof(value));
23655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
23755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
23855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
23955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
24055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Read all byte sizes up to the sizeof the type.
24155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  for (size_t i = 1; i < sizeof(TypeParam); i++) {
24255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    this->op_memory_.SetMemory(
24355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris        0, std::vector<uint8_t>{0x0a, 0x10, 0x20, 0x94, static_cast<uint8_t>(i)});
24455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_TRUE(this->op_->Eval(0, 5, DWARF_VERSION_MAX)) << "Failed at size " << i;
24555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(1U, this->op_->StackSize()) << "Failed at size " << i;
24655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(0x94, this->op_->cur_op()) << "Failed at size " << i;
24755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    TypeParam expected_value = 0;
24855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    memcpy(&expected_value, &value, i);
24955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(expected_value, this->op_->StackAt(0)) << "Failed at size " << i;
25055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
25155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
25255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Zero byte read.
25355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x0a, 0x10, 0x20, 0x94, 0x00});
25455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Eval(0, 5, DWARF_VERSION_MAX));
25555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->last_error());
25655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
25755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Read too many bytes.
25855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x0a, 0x10, 0x20, 0x94, sizeof(TypeParam) + 1});
25955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Eval(0, 5, DWARF_VERSION_MAX));
26055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->last_error());
26155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
26255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Force bad memory read.
26355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x0a, 0x10, 0x40, 0x94, 0x01});
26455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Eval(0, 5, DWARF_VERSION_MAX));
26555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_MEMORY_INVALID, this->op_->last_error());
26655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
26755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
26855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, const_unsigned) {
26955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
27055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // const1u
27155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x12, 0x08, 0xff,
27255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // const2u
27355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x0a, 0x45, 0x12, 0x0a, 0x00, 0xff,
27455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // const4u
27555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x0c, 0x12, 0x23, 0x34, 0x45, 0x0c, 0x03, 0x02, 0x01, 0xff,
27655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // const8u
27755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x0e, 0x87, 0x98, 0xa9, 0xba, 0xcb,
27855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0xdc, 0xed, 0xfe,
27955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
28055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
28155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
28255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // const1u
28355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
28455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x08, this->op_->cur_op());
28555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
28655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x12U, this->op_->StackAt(0));
28755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
28855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
28955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x08, this->op_->cur_op());
29055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
29155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0xffU, this->op_->StackAt(0));
29255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
29355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // const2u
29455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
29555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x0a, this->op_->cur_op());
29655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(3U, this->op_->StackSize());
29755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x1245U, this->op_->StackAt(0));
29855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
29955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
30055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x0a, this->op_->cur_op());
30155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(4U, this->op_->StackSize());
30255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0xff00U, this->op_->StackAt(0));
30355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
30455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // const4u
30555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
30655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x0c, this->op_->cur_op());
30755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(5U, this->op_->StackSize());
30855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x45342312U, this->op_->StackAt(0));
30955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
31055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
31155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x0c, this->op_->cur_op());
31255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(6U, this->op_->StackSize());
31355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0xff010203U, this->op_->StackAt(0));
31455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
31555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // const8u
31655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
31755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x0e, this->op_->cur_op());
31855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(7U, this->op_->StackSize());
31955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  if (sizeof(TypeParam) == 4) {
32055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(0x05060708U, this->op_->StackAt(0));
32155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  } else {
32255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(0x0102030405060708ULL, this->op_->StackAt(0));
32355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
32455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
32555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
32655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x0e, this->op_->cur_op());
32755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(8U, this->op_->StackSize());
32855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  if (sizeof(TypeParam) == 4) {
32955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(0xbaa99887UL, this->op_->StackAt(0));
33055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  } else {
33155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(0xfeeddccbbaa99887ULL, this->op_->StackAt(0));
33255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
33355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
33455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
33555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, const_signed) {
33655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
33755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // const1s
33855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x09, 0x12, 0x09, 0xff,
33955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // const2s
34055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x0b, 0x21, 0x32, 0x0b, 0x08, 0xff,
34155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // const4s
34255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x0d, 0x45, 0x34, 0x23, 0x12, 0x0d, 0x01, 0x02, 0x03, 0xff,
34355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // const8s
34455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x0f, 0x89, 0x78, 0x67, 0x56, 0x45, 0x34, 0x23, 0x12, 0x0f, 0x04, 0x03, 0x02, 0x01, 0xef,
34555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0xef, 0xef, 0xff,
34655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
34755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
34855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
34955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // const1s
35055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
35155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x09, this->op_->cur_op());
35255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
35355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x12U, this->op_->StackAt(0));
35455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
35555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
35655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x09, this->op_->cur_op());
35755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
35855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(static_cast<TypeParam>(-1), this->op_->StackAt(0));
35955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
36055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // const2s
36155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
36255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x0b, this->op_->cur_op());
36355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(3U, this->op_->StackSize());
36455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x3221U, this->op_->StackAt(0));
36555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
36655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
36755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x0b, this->op_->cur_op());
36855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(4U, this->op_->StackSize());
36955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(static_cast<TypeParam>(-248), this->op_->StackAt(0));
37055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
37155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // const4s
37255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
37355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x0d, this->op_->cur_op());
37455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(5U, this->op_->StackSize());
37555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x12233445U, this->op_->StackAt(0));
37655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
37755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
37855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x0d, this->op_->cur_op());
37955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(6U, this->op_->StackSize());
38055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(static_cast<TypeParam>(-16580095), this->op_->StackAt(0));
38155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
38255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // const8s
38355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
38455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x0f, this->op_->cur_op());
38555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(7U, this->op_->StackSize());
38655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  if (sizeof(TypeParam) == 4) {
38755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(0x56677889ULL, this->op_->StackAt(0));
38855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  } else {
38955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(0x1223344556677889ULL, this->op_->StackAt(0));
39055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
39155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
39255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
39355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x0f, this->op_->cur_op());
39455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(8U, this->op_->StackSize());
39555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  if (sizeof(TypeParam) == 4) {
39655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(0x01020304U, this->op_->StackAt(0));
39755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  } else {
39855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(static_cast<TypeParam>(-4521264810949884LL), this->op_->StackAt(0));
39955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
40055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
40155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
40255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, const_uleb) {
40355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
40455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Single byte ULEB128
40555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x10, 0x22, 0x10, 0x7f,
40655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Multi byte ULEB128
40755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x10, 0xa2, 0x22, 0x10, 0xa2, 0x74, 0x10, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
40855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x09, 0x10, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x79,
40955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
41055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
41155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
41255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Single byte ULEB128
41355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
41455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x10, this->op_->cur_op());
41555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
41655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x22U, this->op_->StackAt(0));
41755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
41855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
41955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x10, this->op_->cur_op());
42055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
42155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x7fU, this->op_->StackAt(0));
42255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
42355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Multi byte ULEB128
42455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
42555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x10, this->op_->cur_op());
42655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(3U, this->op_->StackSize());
42755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x1122U, this->op_->StackAt(0));
42855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
42955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
43055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x10, this->op_->cur_op());
43155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(4U, this->op_->StackSize());
43255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x3a22U, this->op_->StackAt(0));
43355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
43455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
43555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x10, this->op_->cur_op());
43655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(5U, this->op_->StackSize());
43755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  if (sizeof(TypeParam) == 4) {
43855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(0x5080c101U, this->op_->StackAt(0));
43955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  } else {
44055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(0x9101c305080c101ULL, this->op_->StackAt(0));
44155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
44255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
44355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
44455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x10, this->op_->cur_op());
44555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(6U, this->op_->StackSize());
44655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  if (sizeof(TypeParam) == 4) {
44755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(0x5080c101U, this->op_->StackAt(0));
44855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  } else {
44955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(0x79101c305080c101ULL, this->op_->StackAt(0));
45055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
45155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
45255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
45355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, const_sleb) {
45455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
45555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Single byte SLEB128
45655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x11, 0x22, 0x11, 0x7f,
45755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Multi byte SLEB128
45855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x11, 0xa2, 0x22, 0x11, 0xa2, 0x74, 0x11, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
45955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x09, 0x11,
46055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
46155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  if (sizeof(TypeParam) == 4) {
46255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(0xb8);
46355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(0xd3);
46455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(0x63);
46555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  } else {
46655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(0x81);
46755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(0x82);
46855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(0x83);
46955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(0x84);
47055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(0x85);
47155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(0x86);
47255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(0x87);
47355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(0x88);
47455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(0x79);
47555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
47655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
47755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
47855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Single byte SLEB128
47955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
48055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x11, this->op_->cur_op());
48155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
48255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x22U, this->op_->StackAt(0));
48355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
48455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
48555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x11, this->op_->cur_op());
48655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
48755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(static_cast<TypeParam>(-1), this->op_->StackAt(0));
48855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
48955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Multi byte SLEB128
49055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
49155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x11, this->op_->cur_op());
49255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(3U, this->op_->StackSize());
49355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x1122U, this->op_->StackAt(0));
49455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
49555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
49655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x11, this->op_->cur_op());
49755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(4U, this->op_->StackSize());
49855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(static_cast<TypeParam>(-1502), this->op_->StackAt(0));
49955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
50055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
50155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x11, this->op_->cur_op());
50255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(5U, this->op_->StackSize());
50355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  if (sizeof(TypeParam) == 4) {
50455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(0x5080c101U, this->op_->StackAt(0));
50555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  } else {
50655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(0x9101c305080c101ULL, this->op_->StackAt(0));
50755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
50855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
50955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
51055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x11, this->op_->cur_op());
51155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(6U, this->op_->StackSize());
51255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  if (sizeof(TypeParam) == 4) {
51355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(static_cast<TypeParam>(-464456), this->op_->StackAt(0));
51455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  } else {
51555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(static_cast<TypeParam>(-499868564803501823LL), this->op_->StackAt(0));
51655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
51755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
51855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
51955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_dup) {
52055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
52155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Should fail since nothing is on the stack.
52255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x12,
52355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push on a value and dup.
52455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x15, 0x12,
52555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Do it again.
52655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x23, 0x12,
52755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
52855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
52955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
53055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
53155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x12, this->op_->cur_op());
53255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
53355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
53455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
53555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
53655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
53755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x12, this->op_->cur_op());
53855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
53955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x15U, this->op_->StackAt(0));
54055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x15U, this->op_->StackAt(1));
54155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
54255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
54355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(3U, this->op_->StackSize());
54455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
54555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x12, this->op_->cur_op());
54655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(4U, this->op_->StackSize());
54755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x23U, this->op_->StackAt(0));
54855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x23U, this->op_->StackAt(1));
54955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x15U, this->op_->StackAt(2));
55055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x15U, this->op_->StackAt(3));
55155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
55255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
55355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_drop) {
55455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
55555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push a couple of values.
55655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x10, 0x08, 0x20,
55755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Drop the values.
55855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x13, 0x13,
55955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Attempt to drop empty stack.
56055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x13,
56155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
56255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
56355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
56455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
56555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
56655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
56755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
56855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
56955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
57055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x13, this->op_->cur_op());
57155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
57255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x10U, this->op_->StackAt(0));
57355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
57455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
57555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x13, this->op_->cur_op());
57655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0U, this->op_->StackSize());
57755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
57855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
57955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x13, this->op_->cur_op());
58055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
58155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
58255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
58355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_over) {
58455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
58555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push a couple of values.
58655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x1a, 0x08, 0xed,
58755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Copy a value.
58855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x14,
58955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Remove all but one element.
59055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x13, 0x13,
59155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Provoke a failure with this opcode.
59255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x14,
59355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
59455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
59555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
59655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
59755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
59855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
59955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
60055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
60155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
60255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x14, this->op_->cur_op());
60355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(3U, this->op_->StackSize());
60455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x1aU, this->op_->StackAt(0));
60555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0xedU, this->op_->StackAt(1));
60655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x1aU, this->op_->StackAt(2));
60755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
60855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
60955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
61055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
61155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
61255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
61355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
61455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x14, this->op_->cur_op());
61555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
61655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
61755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
61855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_pick) {
61955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
62055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push a few values.
62155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x1a, 0x08, 0xed, 0x08, 0x34,
62255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Copy the value at offset 2.
62355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x15, 0x01,
62455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Copy the last value in the stack.
62555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x15, 0x03,
62655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Choose an invalid index.
62755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x15, 0x10,
62855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
62955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
63055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
63155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
63255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
63355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
63455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
63555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
63655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(3U, this->op_->StackSize());
63755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
63855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
63955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x15, this->op_->cur_op());
64055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(4U, this->op_->StackSize());
64155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0xedU, this->op_->StackAt(0));
64255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x34U, this->op_->StackAt(1));
64355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0xedU, this->op_->StackAt(2));
64455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x1aU, this->op_->StackAt(3));
64555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
64655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
64755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x15, this->op_->cur_op());
64855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(5U, this->op_->StackSize());
64955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x1aU, this->op_->StackAt(0));
65055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0xedU, this->op_->StackAt(1));
65155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x34U, this->op_->StackAt(2));
65255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0xedU, this->op_->StackAt(3));
65355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x1aU, this->op_->StackAt(4));
65455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
65555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
65655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x15, this->op_->cur_op());
65755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
65855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
65955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
66055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_swap) {
66155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
66255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push a couple of values.
66355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x26, 0x08, 0xab,
66455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Swap values.
66555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x16,
66655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Pop a value to cause a failure.
66755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x13, 0x16,
66855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
66955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
67055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
67155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
67255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
67355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
67455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
67555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0xabU, this->op_->StackAt(0));
67655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x26U, this->op_->StackAt(1));
67755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
67855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
67955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x16, this->op_->cur_op());
68055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
68155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x26U, this->op_->StackAt(0));
68255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0xabU, this->op_->StackAt(1));
68355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
68455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
68555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
68655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
68755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
68855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x16, this->op_->cur_op());
68955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
69055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
69155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
69255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_rot) {
69355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
69455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Rotate that should cause a failure.
69555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x17, 0x08, 0x10,
69655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Only 1 value on stack, should fail.
69755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x17, 0x08, 0x20,
69855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Only 2 values on stack, should fail.
69955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x17, 0x08, 0x30,
70055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Should rotate properly.
70155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x17,
70255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
70355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
70455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
70555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
70655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
70755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
70855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
70955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
71055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
71155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
71255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
71355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
71455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
71555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
71655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
71755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
71855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
71955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
72055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
72155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(3U, this->op_->StackSize());
72255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x30U, this->op_->StackAt(0));
72355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x20U, this->op_->StackAt(1));
72455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x10U, this->op_->StackAt(2));
72555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
72655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
72755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x17, this->op_->cur_op());
72855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(3U, this->op_->StackSize());
72955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x20U, this->op_->StackAt(0));
73055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x10U, this->op_->StackAt(1));
73155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x30U, this->op_->StackAt(2));
73255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
73355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
73455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_abs) {
73555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
73655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Abs that should fail.
73755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x19,
73855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // A value that is already positive.
73955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x10, 0x19,
74055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // A value that is negative.
74155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x11, 0x7f, 0x19,
74255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // A value that is large and negative.
74355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x11, 0x81, 0x80, 0x80, 0x80,
74455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
74555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  if (sizeof(TypeParam) == 4) {
74655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(0x08);
74755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  } else {
74855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(0x80);
74955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(0x80);
75055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(0x01);
75155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
75255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  opcode_buffer.push_back(0x19);
75355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
75455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
75555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
75655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
75755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
75855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
75955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
76055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x10U, this->op_->StackAt(0));
76155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
76255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
76355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x19, this->op_->cur_op());
76455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
76555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x10U, this->op_->StackAt(0));
76655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
76755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
76855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
76955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
77055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
77155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x19, this->op_->cur_op());
77255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
77355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x1U, this->op_->StackAt(0));
77455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
77555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
77655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(3U, this->op_->StackSize());
77755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
77855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
77955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x19, this->op_->cur_op());
78055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(3U, this->op_->StackSize());
78155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  if (sizeof(TypeParam) == 4) {
78255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(2147483647U, this->op_->StackAt(0));
78355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  } else {
78455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(4398046511105UL, this->op_->StackAt(0));
78555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
78655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
78755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
78855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_and) {
78955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
79055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // No stack, and op will fail.
79155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x1b,
79255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push a single value.
79355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x20,
79455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // One element stack, and op will fail.
79555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x1b,
79655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push another value.
79755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x02, 0x1b,
79855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push on two negative values.
79955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x11, 0x7c, 0x11, 0x7f, 0x1b,
80055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push one negative, one positive.
80155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x11, 0x10, 0x11, 0x7c, 0x1b,
80255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Divide by zero.
80355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x11, 0x10, 0x11, 0x00, 0x1b,
80455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
80555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
80655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
80755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
80855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
80955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
81055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
81155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
81255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
81355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
81455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
81555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
81655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Two positive values.
81755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
81855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
81955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
82055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
82155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x1b, this->op_->cur_op());
82255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
82355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x10U, this->op_->StackAt(0));
82455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
82555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Two negative values.
82655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
82755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
82855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
82955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
83055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(3U, this->op_->StackSize());
83155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
83255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
83355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x1b, this->op_->cur_op());
83455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
83555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x04U, this->op_->StackAt(0));
83655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
83755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // One negative value, one positive value.
83855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
83955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(3U, this->op_->StackSize());
84055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
84155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
84255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(4U, this->op_->StackSize());
84355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
84455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
84555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x1b, this->op_->cur_op());
84655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(3U, this->op_->StackSize());
84755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(static_cast<TypeParam>(-4), this->op_->StackAt(0));
84855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
84955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Divide by zero.
85055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
85155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(4U, this->op_->StackSize());
85255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
85355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
85455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(5U, this->op_->StackSize());
85555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
85655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
85755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->last_error());
85855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
85955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
86055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_div) {
86155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
86255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // No stack, and op will fail.
86355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x1a,
86455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push a single value.
86555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x48,
86655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // One element stack, and op will fail.
86755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x1a,
86855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push another value.
86955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0xf0, 0x1a,
87055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
87155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
87255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
87355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
87455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
87555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
87655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
87755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
87855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
87955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
88055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
88155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
88255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
88355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
88455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
88555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
88655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x1a, this->op_->cur_op());
88755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
88855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x40U, this->op_->StackAt(0));
88955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
89055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
89155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_minus) {
89255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
89355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // No stack, and op will fail.
89455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x1c,
89555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push a single value.
89655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x48,
89755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // One element stack, and op will fail.
89855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x1c,
89955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push another value.
90055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x04, 0x1c,
90155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
90255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
90355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
90455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
90555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
90655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
90755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
90855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
90955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
91055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
91155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
91255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
91355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
91455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
91555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
91655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
91755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x1c, this->op_->cur_op());
91855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
91955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x44U, this->op_->StackAt(0));
92055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
92155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
92255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_mod) {
92355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
92455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // No stack, and op will fail.
92555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x1d,
92655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push a single value.
92755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x47,
92855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // One element stack, and op will fail.
92955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x1d,
93055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push another value.
93155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x04, 0x1d,
93255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Try a mod of zero.
93355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x01, 0x08, 0x00, 0x1d,
93455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
93555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
93655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
93755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
93855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
93955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
94055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
94155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
94255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
94355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
94455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
94555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
94655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
94755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
94855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
94955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
95055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x1d, this->op_->cur_op());
95155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
95255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x03U, this->op_->StackAt(0));
95355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
95455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
95555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
95655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
95755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(3U, this->op_->StackSize());
95855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
95955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
96055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->last_error());
96155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
96255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
96355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_mul) {
96455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
96555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // No stack, and op will fail.
96655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x1e,
96755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push a single value.
96855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x48,
96955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // One element stack, and op will fail.
97055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x1e,
97155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push another value.
97255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x04, 0x1e,
97355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
97455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
97555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
97655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
97755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
97855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
97955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
98055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
98155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
98255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
98355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
98455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
98555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
98655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
98755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
98855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
98955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x1e, this->op_->cur_op());
99055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
99155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x120U, this->op_->StackAt(0));
99255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
99355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
99455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_neg) {
99555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
99655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // No stack, and op will fail.
99755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x1f,
99855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push a single value.
99955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x48, 0x1f,
100055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push a negative value.
100155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x11, 0x7f, 0x1f,
100255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
100355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
100455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
100555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
100655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
100755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
100855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
100955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
101055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
101155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
101255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x1f, this->op_->cur_op());
101355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
101455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(static_cast<TypeParam>(-72), this->op_->StackAt(0));
101555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
101655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
101755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
101855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
101955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
102055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x1f, this->op_->cur_op());
102155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
102255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x01U, this->op_->StackAt(0));
102355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
102455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
102555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_not) {
102655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
102755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // No stack, and op will fail.
102855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x20,
102955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push a single value.
103055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x4, 0x20,
103155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push a negative value.
103255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x11, 0x7c, 0x20,
103355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
103455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
103555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
103655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
103755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
103855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
103955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
104055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
104155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
104255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
104355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x20, this->op_->cur_op());
104455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
104555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(static_cast<TypeParam>(-5), this->op_->StackAt(0));
104655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
104755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
104855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
104955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
105055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
105155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x20, this->op_->cur_op());
105255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
105355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x03U, this->op_->StackAt(0));
105455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
105555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
105655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_or) {
105755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
105855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // No stack, and op will fail.
105955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x21,
106055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push a single value.
106155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x48,
106255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // One element stack, and op will fail.
106355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x21,
106455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push another value.
106555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0xf4, 0x21,
106655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
106755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
106855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
106955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
107055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
107155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
107255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
107355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
107455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
107555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
107655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
107755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
107855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
107955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
108055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
108155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
108255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x21, this->op_->cur_op());
108355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
108455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0xfcU, this->op_->StackAt(0));
108555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
108655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
108755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_plus) {
108855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
108955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // No stack, and op will fail.
109055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x22,
109155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push a single value.
109255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0xff,
109355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // One element stack, and op will fail.
109455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x22,
109555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push another value.
109655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0xf2, 0x22,
109755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
109855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
109955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
110055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
110155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
110255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
110355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
110455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
110555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
110655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
110755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
110855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
110955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
111055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
111155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
111255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
111355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x22, this->op_->cur_op());
111455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
111555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x1f1U, this->op_->StackAt(0));
111655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
111755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
111855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_plus_uconst) {
111955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
112055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // No stack, and op will fail.
112155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x23,
112255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push a single value.
112355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x50, 0x23, 0x80, 0x51,
112455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
112555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
112655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
112755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
112855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
112955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
113055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
113155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
113255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
113355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
113455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x23, this->op_->cur_op());
113555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
113655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x28d0U, this->op_->StackAt(0));
113755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
113855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
113955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_shl) {
114055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
114155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // No stack, and op will fail.
114255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x24,
114355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push a single value.
114455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x67,
114555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // One element stack, and op will fail.
114655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x24,
114755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push another value.
114855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x03, 0x24,
114955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
115055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
115155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
115255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
115355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
115455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
115555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
115655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
115755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
115855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
115955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
116055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
116155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
116255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
116355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
116455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
116555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x24, this->op_->cur_op());
116655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
116755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x338U, this->op_->StackAt(0));
116855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
116955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
117055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_shr) {
117155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
117255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // No stack, and op will fail.
117355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x25,
117455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push a single value.
117555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x11, 0x70,
117655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // One element stack, and op will fail.
117755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x25,
117855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push another value.
117955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x03, 0x25,
118055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
118155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
118255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
118355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
118455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
118555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
118655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
118755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
118855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
118955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
119055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
119155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
119255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
119355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
119455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
119555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
119655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x25, this->op_->cur_op());
119755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
119855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  if (sizeof(TypeParam) == 4) {
119955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(0x1ffffffeU, this->op_->StackAt(0));
120055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  } else {
120155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(0x1ffffffffffffffeULL, this->op_->StackAt(0));
120255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
120355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
120455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
120555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_shra) {
120655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
120755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // No stack, and op will fail.
120855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x26,
120955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push a single value.
121055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x11, 0x70,
121155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // One element stack, and op will fail.
121255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x26,
121355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push another value.
121455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x03, 0x26,
121555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
121655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
121755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
121855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
121955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
122055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
122155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
122255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
122355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
122455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
122555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
122655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
122755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
122855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
122955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
123055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
123155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x26, this->op_->cur_op());
123255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
123355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(static_cast<TypeParam>(-2), this->op_->StackAt(0));
123455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
123555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
123655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_xor) {
123755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
123855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // No stack, and op will fail.
123955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x27,
124055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push a single value.
124155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x11,
124255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // One element stack, and op will fail.
124355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x27,
124455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push another value.
124555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x41, 0x27,
124655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
124755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
124855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
124955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
125055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
125155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
125255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
125355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
125455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
125555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
125655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
125755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
125855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
125955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(2U, this->op_->StackSize());
126055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
126155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
126255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x27, this->op_->cur_op());
126355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
126455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x50U, this->op_->StackAt(0));
126555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
126655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
126755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_bra) {
126855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
126955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // No stack, and op will fail.
127055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x28,
127155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push on a non-zero value with a positive branch.
127255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x11, 0x28, 0x02, 0x01,
127355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push on a zero value with a positive branch.
127455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x00, 0x28, 0x05, 0x00,
127555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push on a non-zero value with a negative branch.
127655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x11, 0x28, 0xfc, 0xff,
127755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Push on a zero value with a negative branch.
127855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x00, 0x28, 0xf0, 0xff,
127955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
128055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
128155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
128255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Decode(DWARF_VERSION_MAX));
128355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
128455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
128555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Push on a non-zero value with a positive branch.
128655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
128755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
128855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
128955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  uint64_t offset = this->mem_->cur_offset() + 3;
129055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
129155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x28, this->op_->cur_op());
129255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0U, this->op_->StackSize());
129355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(offset + 0x102, this->mem_->cur_offset());
129455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
129555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Push on a zero value with a positive branch.
129655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->mem_->set_cur_offset(offset);
129755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
129855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
129955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
130055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  offset = this->mem_->cur_offset() + 3;
130155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
130255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x28, this->op_->cur_op());
130355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0U, this->op_->StackSize());
130455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(offset - 5, this->mem_->cur_offset());
130555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
130655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Push on a non-zero value with a negative branch.
130755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->mem_->set_cur_offset(offset);
130855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
130955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
131055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
131155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  offset = this->mem_->cur_offset() + 3;
131255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
131355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x28, this->op_->cur_op());
131455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0U, this->op_->StackSize());
131555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(offset - 4, this->mem_->cur_offset());
131655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
131755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Push on a zero value with a negative branch.
131855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->mem_->set_cur_offset(offset);
131955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
132055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
132155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
132255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  offset = this->mem_->cur_offset() + 3;
132355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
132455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x28, this->op_->cur_op());
132555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0U, this->op_->StackSize());
132655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(offset + 16, this->mem_->cur_offset());
132755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
132855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
132955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, compare_opcode_stack_error) {
133055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // All of the ops require two stack elements. Loop through all of these
133155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // ops with potential errors.
133255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
133355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0xff,  // Place holder for compare op.
133455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x11,
133555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0xff,  // Place holder for compare op.
133655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
133755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
133855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  for (uint8_t opcode = 0x29; opcode <= 0x2e; opcode++) {
133955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer[0] = opcode;
134055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer[3] = opcode;
134155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    this->op_memory_.SetMemory(0, opcode_buffer);
134255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
134355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_FALSE(this->op_->Eval(0, 1, DWARF_VERSION_MAX));
134455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(opcode, this->op_->cur_op());
134555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
134655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
134755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_FALSE(this->op_->Eval(1, 4, DWARF_VERSION_MAX));
134855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(opcode, this->op_->cur_op());
134955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(1U, this->op_->StackSize());
135055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->last_error());
135155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
135255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
135355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
135455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, compare_opcodes) {
135555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Have three different checks for each compare op:
135655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  //   - Both values the same.
135755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  //   - The first value larger than the second.
135855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  //   - The second value larger than the first.
135955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
136055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Values the same.
136155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x11, 0x08, 0x11,
136255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0xff,  // Placeholder.
136355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // First value larger.
136455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x12, 0x08, 0x10,
136555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0xff,  // Placeholder.
136655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Second value larger.
136755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x08, 0x10, 0x08, 0x12,
136855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0xff,  // Placeholder.
136955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
137055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
137155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Opcode followed by the expected values on the stack.
137255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> expected = {
137355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x29, 1, 0, 0,  // eq
137455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x2a, 1, 1, 0,  // ge
137555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x2b, 0, 1, 0,  // gt
137655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x2c, 1, 0, 1,  // le
137755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x2d, 0, 0, 1,  // lt
137855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x2e, 0, 1, 1,  // ne
137955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
138055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  for (size_t i = 0; i < expected.size(); i += 4) {
138155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer[4] = expected[i];
138255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer[9] = expected[i];
138355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer[14] = expected[i];
138455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    this->op_memory_.SetMemory(0, opcode_buffer);
138555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
138655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_TRUE(this->op_->Eval(0, 15, DWARF_VERSION_MAX))
138755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris        << "Op: 0x" << std::hex << static_cast<uint32_t>(expected[i]) << " failed";
138855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
138955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(3U, this->op_->StackSize());
139055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(expected[i + 1], this->op_->StackAt(2));
139155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(expected[i + 2], this->op_->StackAt(1));
139255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(expected[i + 3], this->op_->StackAt(0));
139355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
139455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
139555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
139655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_skip) {
139755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
139855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Positive value.
139955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x2f, 0x10, 0x20,
140055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      // Negative value.
140155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x2f, 0xfd, 0xff,
140255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
140355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
140455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
140555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  uint64_t offset = this->mem_->cur_offset() + 3;
140655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
140755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x2f, this->op_->cur_op());
140855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0U, this->op_->StackSize());
140955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(offset + 0x2010, this->mem_->cur_offset());
141055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
141155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->mem_->set_cur_offset(offset);
141255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  offset = this->mem_->cur_offset() + 3;
141355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
141455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x2f, this->op_->cur_op());
141555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0U, this->op_->StackSize());
141655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(offset - 3, this->mem_->cur_offset());
141755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
141855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
141955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_lit) {
142055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer;
142155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
142255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Verify every lit opcode.
142355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  for (uint8_t op = 0x30; op <= 0x4f; op++) {
142455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(op);
142555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
142655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
142755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
142855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  for (size_t i = 0; i < opcode_buffer.size(); i++) {
142955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    uint32_t op = opcode_buffer[i];
143055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_TRUE(this->op_->Eval(i, i + 1, DWARF_VERSION_MAX)) << "Failed op: 0x" << std::hex << op;
143155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(op, this->op_->cur_op());
143255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(1U, this->op_->StackSize()) << "Failed op: 0x" << std::hex << op;
143355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(op - 0x30U, this->op_->StackAt(0)) << "Failed op: 0x" << std::hex << op;
143455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
143555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
143655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
143755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_reg) {
143855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer;
143955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
144055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Verify every reg opcode.
144155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  for (uint8_t op = 0x50; op <= 0x6f; op++) {
144255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(op);
144355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
144455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
144555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
144655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  for (size_t i = 0; i < opcode_buffer.size(); i++) {
144755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    uint32_t op = opcode_buffer[i];
144855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_TRUE(this->op_->Eval(i, i + 1, DWARF_VERSION_MAX)) << "Failed op: 0x" << std::hex << op;
144955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(op, this->op_->cur_op());
145055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_TRUE(this->op_->is_register()) << "Failed op: 0x" << std::hex << op;
145155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(1U, this->op_->StackSize()) << "Failed op: 0x" << std::hex << op;
145255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(op - 0x50U, this->op_->StackAt(0)) << "Failed op: 0x" << std::hex << op;
145355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
145455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
145555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
145655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_regx) {
145755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
145855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x90, 0x02, 0x90, 0x80, 0x15,
145955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
146055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
146155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
146255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Eval(0, 2, DWARF_VERSION_MAX));
146355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x90, this->op_->cur_op());
146455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->is_register());
146555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
146655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x02U, this->op_->StackAt(0));
146755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
146855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Eval(2, 5, DWARF_VERSION_MAX));
146955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x90, this->op_->cur_op());
147055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->is_register());
147155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
147255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0xa80U, this->op_->StackAt(0));
147355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
147455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
147555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_breg) {
147655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer;
147755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
147855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Verify every reg opcode.
147955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  for (uint8_t op = 0x70; op <= 0x8f; op++) {
148055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    // Positive value added to register.
148155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(op);
148255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(0x12);
148355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    // Negative value added to register.
148455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(op);
148555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    opcode_buffer.push_back(0x7e);
148655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
148755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
148855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
148955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  RegsFake<TypeParam> regs(32, 10);
149055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  for (size_t i = 0; i < 32; i++) {
149155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    regs[i] = i + 10;
149255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
149355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_->set_regs(&regs);
149455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
149555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  uint64_t offset = 0;
149655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  for (uint32_t op = 0x70; op <= 0x8f; op++) {
149755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    // Positive value added to register.
149855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_TRUE(this->op_->Eval(offset, offset + 2, DWARF_VERSION_MAX)) << "Failed op: 0x"
149955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris                                                                        << std::hex << op;
150055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(op, this->op_->cur_op());
150155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(1U, this->op_->StackSize()) << "Failed op: 0x" << std::hex << op;
150255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(op - 0x70 + 10 + 0x12, this->op_->StackAt(0)) << "Failed op: 0x" << std::hex << op;
150355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    offset += 2;
150455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
150555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    // Negative value added to register.
150655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_TRUE(this->op_->Eval(offset, offset + 2, DWARF_VERSION_MAX)) << "Failed op: 0x"
150755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris                                                                        << std::hex << op;
150855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(op, this->op_->cur_op());
150955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(1U, this->op_->StackSize()) << "Failed op: 0x" << std::hex << op;
151055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    ASSERT_EQ(op - 0x70 + 10 - 2, this->op_->StackAt(0)) << "Failed op: 0x" << std::hex << op;
151155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    offset += 2;
151255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
151355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
151455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
151555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_breg_invalid_register) {
151655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {
151755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris      0x7f, 0x12, 0x80, 0x12,
151855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  };
151955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
152055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
152155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  RegsFake<TypeParam> regs(16, 10);
152255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  for (size_t i = 0; i < 16; i++) {
152355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris    regs[i] = i + 10;
152455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  }
152555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_->set_regs(&regs);
152655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
152755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Should pass since this references the last regsister.
152855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Eval(0, 2, DWARF_VERSION_MAX));
152955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x7fU, this->op_->cur_op());
153055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
153155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x2bU, this->op_->StackAt(0));
153255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
153355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  // Should fail since this references a non-existent register.
153455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Eval(2, 4, DWARF_VERSION_MAX));
153555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->last_error());
153655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
153755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
153855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_bregx) {
153955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  std::vector<uint8_t> opcode_buffer = {// Positive value added to register.
154055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris                                        0x92, 0x05, 0x20,
154155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris                                        // Negative value added to register.
154255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris                                        0x92, 0x06, 0x80, 0x7e,
154355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris                                        // Illegal register.
154455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris                                        0x92, 0x80, 0x15, 0x80, 0x02};
154555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, opcode_buffer);
154655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
154755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  RegsFake<TypeParam> regs(10, 10);
154855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  regs[5] = 0x45;
154955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  regs[6] = 0x190;
155055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_->set_regs(&regs);
155155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
155255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Eval(0, 3, DWARF_VERSION_MAX));
155355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x92, this->op_->cur_op());
155455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
155555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x65U, this->op_->StackAt(0));
155655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
155755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Eval(3, 7, DWARF_VERSION_MAX));
155855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x92, this->op_->cur_op());
155955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(1U, this->op_->StackSize());
156055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x90U, this->op_->StackAt(0));
156155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
156255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_FALSE(this->op_->Eval(7, 12, DWARF_VERSION_MAX));
156355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->last_error());
156455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
156555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
156655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisTYPED_TEST_P(DwarfOpTest, op_nop) {
156755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x96});
156855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
156955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_TRUE(this->op_->Decode(DWARF_VERSION_MAX));
157055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0x96, this->op_->cur_op());
157155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris  ASSERT_EQ(0U, this->op_->StackSize());
157255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris}
157355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
157455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisREGISTER_TYPED_TEST_CASE_P(DwarfOpTest, decode, eval, illegal_opcode, illegal_in_version3,
157555d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris                           illegal_in_version4, not_implemented, op_addr, op_deref, op_deref_size,
157655d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris                           const_unsigned, const_signed, const_uleb, const_sleb, op_dup, op_drop,
157755d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris                           op_over, op_pick, op_swap, op_rot, op_abs, op_and, op_div, op_minus,
157855d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris                           op_mod, op_mul, op_neg, op_not, op_or, op_plus, op_plus_uconst, op_shl,
157955d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris                           op_shr, op_shra, op_xor, op_bra, compare_opcode_stack_error,
158055d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris                           compare_opcodes, op_skip, op_lit, op_reg, op_regx, op_breg,
158155d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris                           op_breg_invalid_register, op_bregx, op_nop);
158255d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferris
158355d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher Ferristypedef ::testing::Types<uint32_t, uint64_t> DwarfOpTestTypes;
158455d22ef67c428a3f0994ee7da51b33c79ddcc552Christopher FerrisINSTANTIATE_TYPED_TEST_CASE_P(, DwarfOpTest, DwarfOpTestTypes);
1585d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris
1586d226a5140989f509a0ed3e2723f05d5fc93ce8dfChristopher Ferris}  // namespace unwindstack
1587