| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright (C) 2016 The Android Open Source Project | 
 | 3 |  * | 
 | 4 |  * Licensed under the Apache License, Version 2.0 (the "License"); | 
 | 5 |  * you may not use this file except in compliance with the License. | 
 | 6 |  * You may obtain a copy of the License at | 
 | 7 |  * | 
 | 8 |  *      http://www.apache.org/licenses/LICENSE-2.0 | 
 | 9 |  * | 
 | 10 |  * Unless required by applicable law or agreed to in writing, software | 
 | 11 |  * distributed under the License is distributed on an "AS IS" BASIS, | 
 | 12 |  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 | 13 |  * See the License for the specific language governing permissions and | 
 | 14 |  * limitations under the License. | 
 | 15 |  */ | 
 | 16 |  | 
 | 17 | #include <stdint.h> | 
 | 18 |  | 
 | 19 | #include <ios> | 
 | 20 | #include <vector> | 
 | 21 |  | 
 | 22 | #include <gtest/gtest.h> | 
 | 23 |  | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 24 | #include <unwindstack/DwarfError.h> | 
| Christopher Ferris | d226a51 | 2017-07-14 10:37:19 -0700 | [diff] [blame] | 25 | #include <unwindstack/DwarfMemory.h> | 
 | 26 | #include <unwindstack/Log.h> | 
 | 27 |  | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 28 | #include "DwarfOp.h" | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 29 |  | 
 | 30 | #include "MemoryFake.h" | 
| Christopher Ferris | 53a3c9b | 2017-05-10 18:34:15 -0700 | [diff] [blame] | 31 | #include "RegsFake.h" | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 32 |  | 
| Christopher Ferris | d226a51 | 2017-07-14 10:37:19 -0700 | [diff] [blame] | 33 | namespace unwindstack { | 
 | 34 |  | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 35 | template <typename TypeParam> | 
 | 36 | class DwarfOpTest : public ::testing::Test { | 
 | 37 |  protected: | 
 | 38 |   void SetUp() override { | 
 | 39 |     op_memory_.Clear(); | 
 | 40 |     regular_memory_.Clear(); | 
 | 41 |     mem_.reset(new DwarfMemory(&op_memory_)); | 
 | 42 |     op_.reset(new DwarfOp<TypeParam>(mem_.get(), ®ular_memory_)); | 
 | 43 |   } | 
 | 44 |  | 
 | 45 |   MemoryFake op_memory_; | 
 | 46 |   MemoryFake regular_memory_; | 
 | 47 |  | 
 | 48 |   std::unique_ptr<DwarfMemory> mem_; | 
 | 49 |   std::unique_ptr<DwarfOp<TypeParam>> op_; | 
 | 50 | }; | 
| Christopher Ferris | 7e21eba | 2019-06-20 16:16:42 -0700 | [diff] [blame] | 51 | TYPED_TEST_SUITE_P(DwarfOpTest); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 52 |  | 
 | 53 | TYPED_TEST_P(DwarfOpTest, decode) { | 
 | 54 |   // Memory error. | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 55 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 56 |   ASSERT_EQ(DWARF_ERROR_MEMORY_INVALID, this->op_->LastErrorCode()); | 
 | 57 |   EXPECT_EQ(0U, this->op_->LastErrorAddress()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 58 |  | 
 | 59 |   // No error. | 
 | 60 |   this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x96}); | 
 | 61 |   this->mem_->set_cur_offset(0); | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 62 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 63 |   ASSERT_EQ(DWARF_ERROR_NONE, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 64 |   ASSERT_EQ(0x96U, this->op_->cur_op()); | 
 | 65 |   ASSERT_EQ(1U, this->mem_->cur_offset()); | 
 | 66 | } | 
 | 67 |  | 
 | 68 | TYPED_TEST_P(DwarfOpTest, eval) { | 
 | 69 |   // Memory error. | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 70 |   ASSERT_FALSE(this->op_->Eval(0, 2)); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 71 |   ASSERT_EQ(DWARF_ERROR_MEMORY_INVALID, this->op_->LastErrorCode()); | 
 | 72 |   EXPECT_EQ(0U, this->op_->LastErrorAddress()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 73 |  | 
 | 74 |   // Register set. | 
 | 75 |   // Do this first, to verify that subsequent calls reset the value. | 
 | 76 |   this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x50}); | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 77 |   ASSERT_TRUE(this->op_->Eval(0, 1)); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 78 |   ASSERT_TRUE(this->op_->is_register()); | 
 | 79 |   ASSERT_EQ(1U, this->mem_->cur_offset()); | 
 | 80 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 81 |  | 
 | 82 |   // Multi operation opcodes. | 
 | 83 |   std::vector<uint8_t> opcode_buffer = { | 
 | 84 |       0x08, 0x04, 0x08, 0x03, 0x08, 0x02, 0x08, 0x01, | 
 | 85 |   }; | 
 | 86 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 87 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 88 |   ASSERT_TRUE(this->op_->Eval(0, 8)); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 89 |   ASSERT_EQ(DWARF_ERROR_NONE, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 90 |   ASSERT_FALSE(this->op_->is_register()); | 
 | 91 |   ASSERT_EQ(8U, this->mem_->cur_offset()); | 
 | 92 |   ASSERT_EQ(4U, this->op_->StackSize()); | 
 | 93 |   ASSERT_EQ(1U, this->op_->StackAt(0)); | 
 | 94 |   ASSERT_EQ(2U, this->op_->StackAt(1)); | 
 | 95 |   ASSERT_EQ(3U, this->op_->StackAt(2)); | 
 | 96 |   ASSERT_EQ(4U, this->op_->StackAt(3)); | 
 | 97 |  | 
 | 98 |   // Infinite loop. | 
 | 99 |   this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x2f, 0xfd, 0xff}); | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 100 |   ASSERT_FALSE(this->op_->Eval(0, 4)); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 101 |   ASSERT_EQ(DWARF_ERROR_TOO_MANY_ITERATIONS, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 102 |   ASSERT_FALSE(this->op_->is_register()); | 
 | 103 |   ASSERT_EQ(0U, this->op_->StackSize()); | 
 | 104 | } | 
 | 105 |  | 
 | 106 | TYPED_TEST_P(DwarfOpTest, illegal_opcode) { | 
 | 107 |   // Fill the buffer with all of the illegal opcodes. | 
 | 108 |   std::vector<uint8_t> opcode_buffer = {0x00, 0x01, 0x02, 0x04, 0x05, 0x07}; | 
 | 109 |   for (size_t opcode = 0xa0; opcode < 256; opcode++) { | 
 | 110 |     opcode_buffer.push_back(opcode); | 
 | 111 |   } | 
 | 112 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 113 |  | 
 | 114 |   for (size_t i = 0; i < opcode_buffer.size(); i++) { | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 115 |     ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 116 |     ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 117 |     ASSERT_EQ(opcode_buffer[i], this->op_->cur_op()); | 
 | 118 |   } | 
 | 119 | } | 
 | 120 |  | 
 | 121 | TYPED_TEST_P(DwarfOpTest, not_implemented) { | 
 | 122 |   std::vector<uint8_t> opcode_buffer = { | 
 | 123 |       // Push values so that any not implemented ops will return the right error. | 
 | 124 |       0x08, 0x03, 0x08, 0x02, 0x08, 0x01, | 
 | 125 |       // xderef | 
 | 126 |       0x18, | 
 | 127 |       // fbreg | 
 | 128 |       0x91, 0x01, | 
 | 129 |       // piece | 
 | 130 |       0x93, 0x01, | 
 | 131 |       // xderef_size | 
 | 132 |       0x95, 0x01, | 
 | 133 |       // push_object_address | 
 | 134 |       0x97, | 
 | 135 |       // call2 | 
 | 136 |       0x98, 0x01, 0x02, | 
 | 137 |       // call4 | 
 | 138 |       0x99, 0x01, 0x02, 0x03, 0x04, | 
 | 139 |       // call_ref | 
 | 140 |       0x9a, | 
 | 141 |       // form_tls_address | 
 | 142 |       0x9b, | 
 | 143 |       // call_frame_cfa | 
 | 144 |       0x9c, | 
 | 145 |       // bit_piece | 
 | 146 |       0x9d, 0x01, 0x01, | 
 | 147 |       // implicit_value | 
 | 148 |       0x9e, 0x01, | 
 | 149 |       // stack_value | 
 | 150 |       0x9f, | 
 | 151 |   }; | 
 | 152 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 153 |  | 
 | 154 |   // Push the stack values. | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 155 |   ASSERT_TRUE(this->op_->Decode()); | 
 | 156 |   ASSERT_TRUE(this->op_->Decode()); | 
 | 157 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 158 |  | 
 | 159 |   while (this->mem_->cur_offset() < opcode_buffer.size()) { | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 160 |     ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 161 |     ASSERT_EQ(DWARF_ERROR_NOT_IMPLEMENTED, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 162 |   } | 
 | 163 | } | 
 | 164 |  | 
 | 165 | TYPED_TEST_P(DwarfOpTest, op_addr) { | 
 | 166 |   std::vector<uint8_t> opcode_buffer = {0x03, 0x12, 0x23, 0x34, 0x45}; | 
 | 167 |   if (sizeof(TypeParam) == 8) { | 
 | 168 |     opcode_buffer.push_back(0x56); | 
 | 169 |     opcode_buffer.push_back(0x67); | 
 | 170 |     opcode_buffer.push_back(0x78); | 
 | 171 |     opcode_buffer.push_back(0x89); | 
 | 172 |   } | 
 | 173 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 174 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 175 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 176 |   ASSERT_EQ(0x03, this->op_->cur_op()); | 
 | 177 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 178 |   if (sizeof(TypeParam) == 4) { | 
 | 179 |     ASSERT_EQ(0x45342312U, this->op_->StackAt(0)); | 
 | 180 |   } else { | 
 | 181 |     ASSERT_EQ(0x8978675645342312UL, this->op_->StackAt(0)); | 
 | 182 |   } | 
 | 183 | } | 
 | 184 |  | 
 | 185 | TYPED_TEST_P(DwarfOpTest, op_deref) { | 
 | 186 |   std::vector<uint8_t> opcode_buffer = { | 
 | 187 |       // Try a dereference with nothing on the stack. | 
 | 188 |       0x06, | 
 | 189 |       // Add an address, then dereference. | 
 | 190 |       0x0a, 0x10, 0x20, 0x06, | 
 | 191 |       // Now do another dereference that should fail in memory. | 
 | 192 |       0x06, | 
 | 193 |   }; | 
 | 194 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 195 |   TypeParam value = 0x12345678; | 
 | 196 |   this->regular_memory_.SetMemory(0x2010, &value, sizeof(value)); | 
 | 197 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 198 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 199 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 200 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 201 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 202 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 203 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 204 |   ASSERT_EQ(0x06, this->op_->cur_op()); | 
 | 205 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 206 |   ASSERT_EQ(value, this->op_->StackAt(0)); | 
 | 207 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 208 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 209 |   ASSERT_EQ(DWARF_ERROR_MEMORY_INVALID, this->op_->LastErrorCode()); | 
 | 210 |   ASSERT_EQ(0x12345678U, this->op_->LastErrorAddress()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 211 | } | 
 | 212 |  | 
 | 213 | TYPED_TEST_P(DwarfOpTest, op_deref_size) { | 
 | 214 |   this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x94}); | 
 | 215 |   TypeParam value = 0x12345678; | 
 | 216 |   this->regular_memory_.SetMemory(0x2010, &value, sizeof(value)); | 
 | 217 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 218 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 219 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 220 |  | 
 | 221 |   // Read all byte sizes up to the sizeof the type. | 
 | 222 |   for (size_t i = 1; i < sizeof(TypeParam); i++) { | 
 | 223 |     this->op_memory_.SetMemory( | 
 | 224 |         0, std::vector<uint8_t>{0x0a, 0x10, 0x20, 0x94, static_cast<uint8_t>(i)}); | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 225 |     ASSERT_TRUE(this->op_->Eval(0, 5)) << "Failed at size " << i; | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 226 |     ASSERT_EQ(1U, this->op_->StackSize()) << "Failed at size " << i; | 
 | 227 |     ASSERT_EQ(0x94, this->op_->cur_op()) << "Failed at size " << i; | 
 | 228 |     TypeParam expected_value = 0; | 
 | 229 |     memcpy(&expected_value, &value, i); | 
 | 230 |     ASSERT_EQ(expected_value, this->op_->StackAt(0)) << "Failed at size " << i; | 
 | 231 |   } | 
 | 232 |  | 
 | 233 |   // Zero byte read. | 
 | 234 |   this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x0a, 0x10, 0x20, 0x94, 0x00}); | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 235 |   ASSERT_FALSE(this->op_->Eval(0, 5)); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 236 |   ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 237 |  | 
 | 238 |   // Read too many bytes. | 
 | 239 |   this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x0a, 0x10, 0x20, 0x94, sizeof(TypeParam) + 1}); | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 240 |   ASSERT_FALSE(this->op_->Eval(0, 5)); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 241 |   ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 242 |  | 
 | 243 |   // Force bad memory read. | 
 | 244 |   this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x0a, 0x10, 0x40, 0x94, 0x01}); | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 245 |   ASSERT_FALSE(this->op_->Eval(0, 5)); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 246 |   ASSERT_EQ(DWARF_ERROR_MEMORY_INVALID, this->op_->LastErrorCode()); | 
 | 247 |   EXPECT_EQ(0x4010U, this->op_->LastErrorAddress()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 248 | } | 
 | 249 |  | 
 | 250 | TYPED_TEST_P(DwarfOpTest, const_unsigned) { | 
 | 251 |   std::vector<uint8_t> opcode_buffer = { | 
 | 252 |       // const1u | 
 | 253 |       0x08, 0x12, 0x08, 0xff, | 
 | 254 |       // const2u | 
 | 255 |       0x0a, 0x45, 0x12, 0x0a, 0x00, 0xff, | 
 | 256 |       // const4u | 
 | 257 |       0x0c, 0x12, 0x23, 0x34, 0x45, 0x0c, 0x03, 0x02, 0x01, 0xff, | 
 | 258 |       // const8u | 
 | 259 |       0x0e, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x0e, 0x87, 0x98, 0xa9, 0xba, 0xcb, | 
 | 260 |       0xdc, 0xed, 0xfe, | 
 | 261 |   }; | 
 | 262 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 263 |  | 
 | 264 |   // const1u | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 265 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 266 |   ASSERT_EQ(0x08, this->op_->cur_op()); | 
 | 267 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 268 |   ASSERT_EQ(0x12U, this->op_->StackAt(0)); | 
 | 269 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 270 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 271 |   ASSERT_EQ(0x08, this->op_->cur_op()); | 
 | 272 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 273 |   ASSERT_EQ(0xffU, this->op_->StackAt(0)); | 
 | 274 |  | 
 | 275 |   // const2u | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 276 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 277 |   ASSERT_EQ(0x0a, this->op_->cur_op()); | 
 | 278 |   ASSERT_EQ(3U, this->op_->StackSize()); | 
 | 279 |   ASSERT_EQ(0x1245U, this->op_->StackAt(0)); | 
 | 280 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 281 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 282 |   ASSERT_EQ(0x0a, this->op_->cur_op()); | 
 | 283 |   ASSERT_EQ(4U, this->op_->StackSize()); | 
 | 284 |   ASSERT_EQ(0xff00U, this->op_->StackAt(0)); | 
 | 285 |  | 
 | 286 |   // const4u | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 287 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 288 |   ASSERT_EQ(0x0c, this->op_->cur_op()); | 
 | 289 |   ASSERT_EQ(5U, this->op_->StackSize()); | 
 | 290 |   ASSERT_EQ(0x45342312U, this->op_->StackAt(0)); | 
 | 291 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 292 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 293 |   ASSERT_EQ(0x0c, this->op_->cur_op()); | 
 | 294 |   ASSERT_EQ(6U, this->op_->StackSize()); | 
 | 295 |   ASSERT_EQ(0xff010203U, this->op_->StackAt(0)); | 
 | 296 |  | 
 | 297 |   // const8u | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 298 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 299 |   ASSERT_EQ(0x0e, this->op_->cur_op()); | 
 | 300 |   ASSERT_EQ(7U, this->op_->StackSize()); | 
 | 301 |   if (sizeof(TypeParam) == 4) { | 
 | 302 |     ASSERT_EQ(0x05060708U, this->op_->StackAt(0)); | 
 | 303 |   } else { | 
 | 304 |     ASSERT_EQ(0x0102030405060708ULL, this->op_->StackAt(0)); | 
 | 305 |   } | 
 | 306 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 307 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 308 |   ASSERT_EQ(0x0e, this->op_->cur_op()); | 
 | 309 |   ASSERT_EQ(8U, this->op_->StackSize()); | 
 | 310 |   if (sizeof(TypeParam) == 4) { | 
 | 311 |     ASSERT_EQ(0xbaa99887UL, this->op_->StackAt(0)); | 
 | 312 |   } else { | 
 | 313 |     ASSERT_EQ(0xfeeddccbbaa99887ULL, this->op_->StackAt(0)); | 
 | 314 |   } | 
 | 315 | } | 
 | 316 |  | 
 | 317 | TYPED_TEST_P(DwarfOpTest, const_signed) { | 
 | 318 |   std::vector<uint8_t> opcode_buffer = { | 
 | 319 |       // const1s | 
 | 320 |       0x09, 0x12, 0x09, 0xff, | 
 | 321 |       // const2s | 
 | 322 |       0x0b, 0x21, 0x32, 0x0b, 0x08, 0xff, | 
 | 323 |       // const4s | 
 | 324 |       0x0d, 0x45, 0x34, 0x23, 0x12, 0x0d, 0x01, 0x02, 0x03, 0xff, | 
 | 325 |       // const8s | 
 | 326 |       0x0f, 0x89, 0x78, 0x67, 0x56, 0x45, 0x34, 0x23, 0x12, 0x0f, 0x04, 0x03, 0x02, 0x01, 0xef, | 
 | 327 |       0xef, 0xef, 0xff, | 
 | 328 |   }; | 
 | 329 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 330 |  | 
 | 331 |   // const1s | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 332 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 333 |   ASSERT_EQ(0x09, this->op_->cur_op()); | 
 | 334 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 335 |   ASSERT_EQ(0x12U, this->op_->StackAt(0)); | 
 | 336 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 337 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 338 |   ASSERT_EQ(0x09, this->op_->cur_op()); | 
 | 339 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 340 |   ASSERT_EQ(static_cast<TypeParam>(-1), this->op_->StackAt(0)); | 
 | 341 |  | 
 | 342 |   // const2s | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 343 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 344 |   ASSERT_EQ(0x0b, this->op_->cur_op()); | 
 | 345 |   ASSERT_EQ(3U, this->op_->StackSize()); | 
 | 346 |   ASSERT_EQ(0x3221U, this->op_->StackAt(0)); | 
 | 347 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 348 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 349 |   ASSERT_EQ(0x0b, this->op_->cur_op()); | 
 | 350 |   ASSERT_EQ(4U, this->op_->StackSize()); | 
 | 351 |   ASSERT_EQ(static_cast<TypeParam>(-248), this->op_->StackAt(0)); | 
 | 352 |  | 
 | 353 |   // const4s | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 354 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 355 |   ASSERT_EQ(0x0d, this->op_->cur_op()); | 
 | 356 |   ASSERT_EQ(5U, this->op_->StackSize()); | 
 | 357 |   ASSERT_EQ(0x12233445U, this->op_->StackAt(0)); | 
 | 358 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 359 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 360 |   ASSERT_EQ(0x0d, this->op_->cur_op()); | 
 | 361 |   ASSERT_EQ(6U, this->op_->StackSize()); | 
 | 362 |   ASSERT_EQ(static_cast<TypeParam>(-16580095), this->op_->StackAt(0)); | 
 | 363 |  | 
 | 364 |   // const8s | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 365 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 366 |   ASSERT_EQ(0x0f, this->op_->cur_op()); | 
 | 367 |   ASSERT_EQ(7U, this->op_->StackSize()); | 
 | 368 |   if (sizeof(TypeParam) == 4) { | 
 | 369 |     ASSERT_EQ(0x56677889ULL, this->op_->StackAt(0)); | 
 | 370 |   } else { | 
 | 371 |     ASSERT_EQ(0x1223344556677889ULL, this->op_->StackAt(0)); | 
 | 372 |   } | 
 | 373 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 374 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 375 |   ASSERT_EQ(0x0f, this->op_->cur_op()); | 
 | 376 |   ASSERT_EQ(8U, this->op_->StackSize()); | 
 | 377 |   if (sizeof(TypeParam) == 4) { | 
 | 378 |     ASSERT_EQ(0x01020304U, this->op_->StackAt(0)); | 
 | 379 |   } else { | 
 | 380 |     ASSERT_EQ(static_cast<TypeParam>(-4521264810949884LL), this->op_->StackAt(0)); | 
 | 381 |   } | 
 | 382 | } | 
 | 383 |  | 
 | 384 | TYPED_TEST_P(DwarfOpTest, const_uleb) { | 
 | 385 |   std::vector<uint8_t> opcode_buffer = { | 
 | 386 |       // Single byte ULEB128 | 
 | 387 |       0x10, 0x22, 0x10, 0x7f, | 
 | 388 |       // Multi byte ULEB128 | 
 | 389 |       0x10, 0xa2, 0x22, 0x10, 0xa2, 0x74, 0x10, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, | 
 | 390 |       0x09, 0x10, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x79, | 
 | 391 |   }; | 
 | 392 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 393 |  | 
 | 394 |   // Single byte ULEB128 | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 395 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 396 |   ASSERT_EQ(0x10, this->op_->cur_op()); | 
 | 397 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 398 |   ASSERT_EQ(0x22U, this->op_->StackAt(0)); | 
 | 399 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 400 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 401 |   ASSERT_EQ(0x10, this->op_->cur_op()); | 
 | 402 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 403 |   ASSERT_EQ(0x7fU, this->op_->StackAt(0)); | 
 | 404 |  | 
 | 405 |   // Multi byte ULEB128 | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 406 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 407 |   ASSERT_EQ(0x10, this->op_->cur_op()); | 
 | 408 |   ASSERT_EQ(3U, this->op_->StackSize()); | 
 | 409 |   ASSERT_EQ(0x1122U, this->op_->StackAt(0)); | 
 | 410 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 411 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 412 |   ASSERT_EQ(0x10, this->op_->cur_op()); | 
 | 413 |   ASSERT_EQ(4U, this->op_->StackSize()); | 
 | 414 |   ASSERT_EQ(0x3a22U, this->op_->StackAt(0)); | 
 | 415 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 416 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 417 |   ASSERT_EQ(0x10, this->op_->cur_op()); | 
 | 418 |   ASSERT_EQ(5U, this->op_->StackSize()); | 
 | 419 |   if (sizeof(TypeParam) == 4) { | 
 | 420 |     ASSERT_EQ(0x5080c101U, this->op_->StackAt(0)); | 
 | 421 |   } else { | 
 | 422 |     ASSERT_EQ(0x9101c305080c101ULL, this->op_->StackAt(0)); | 
 | 423 |   } | 
 | 424 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 425 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 426 |   ASSERT_EQ(0x10, this->op_->cur_op()); | 
 | 427 |   ASSERT_EQ(6U, this->op_->StackSize()); | 
 | 428 |   if (sizeof(TypeParam) == 4) { | 
 | 429 |     ASSERT_EQ(0x5080c101U, this->op_->StackAt(0)); | 
 | 430 |   } else { | 
 | 431 |     ASSERT_EQ(0x79101c305080c101ULL, this->op_->StackAt(0)); | 
 | 432 |   } | 
 | 433 | } | 
 | 434 |  | 
 | 435 | TYPED_TEST_P(DwarfOpTest, const_sleb) { | 
 | 436 |   std::vector<uint8_t> opcode_buffer = { | 
 | 437 |       // Single byte SLEB128 | 
 | 438 |       0x11, 0x22, 0x11, 0x7f, | 
 | 439 |       // Multi byte SLEB128 | 
 | 440 |       0x11, 0xa2, 0x22, 0x11, 0xa2, 0x74, 0x11, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, | 
 | 441 |       0x09, 0x11, | 
 | 442 |   }; | 
 | 443 |   if (sizeof(TypeParam) == 4) { | 
 | 444 |     opcode_buffer.push_back(0xb8); | 
 | 445 |     opcode_buffer.push_back(0xd3); | 
 | 446 |     opcode_buffer.push_back(0x63); | 
 | 447 |   } else { | 
 | 448 |     opcode_buffer.push_back(0x81); | 
 | 449 |     opcode_buffer.push_back(0x82); | 
 | 450 |     opcode_buffer.push_back(0x83); | 
 | 451 |     opcode_buffer.push_back(0x84); | 
 | 452 |     opcode_buffer.push_back(0x85); | 
 | 453 |     opcode_buffer.push_back(0x86); | 
 | 454 |     opcode_buffer.push_back(0x87); | 
 | 455 |     opcode_buffer.push_back(0x88); | 
 | 456 |     opcode_buffer.push_back(0x79); | 
 | 457 |   } | 
 | 458 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 459 |  | 
 | 460 |   // Single byte SLEB128 | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 461 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 462 |   ASSERT_EQ(0x11, this->op_->cur_op()); | 
 | 463 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 464 |   ASSERT_EQ(0x22U, this->op_->StackAt(0)); | 
 | 465 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 466 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 467 |   ASSERT_EQ(0x11, this->op_->cur_op()); | 
 | 468 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 469 |   ASSERT_EQ(static_cast<TypeParam>(-1), this->op_->StackAt(0)); | 
 | 470 |  | 
 | 471 |   // Multi byte SLEB128 | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 472 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 473 |   ASSERT_EQ(0x11, this->op_->cur_op()); | 
 | 474 |   ASSERT_EQ(3U, this->op_->StackSize()); | 
 | 475 |   ASSERT_EQ(0x1122U, this->op_->StackAt(0)); | 
 | 476 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 477 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 478 |   ASSERT_EQ(0x11, this->op_->cur_op()); | 
 | 479 |   ASSERT_EQ(4U, this->op_->StackSize()); | 
 | 480 |   ASSERT_EQ(static_cast<TypeParam>(-1502), this->op_->StackAt(0)); | 
 | 481 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 482 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 483 |   ASSERT_EQ(0x11, this->op_->cur_op()); | 
 | 484 |   ASSERT_EQ(5U, this->op_->StackSize()); | 
 | 485 |   if (sizeof(TypeParam) == 4) { | 
 | 486 |     ASSERT_EQ(0x5080c101U, this->op_->StackAt(0)); | 
 | 487 |   } else { | 
 | 488 |     ASSERT_EQ(0x9101c305080c101ULL, this->op_->StackAt(0)); | 
 | 489 |   } | 
 | 490 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 491 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 492 |   ASSERT_EQ(0x11, this->op_->cur_op()); | 
 | 493 |   ASSERT_EQ(6U, this->op_->StackSize()); | 
 | 494 |   if (sizeof(TypeParam) == 4) { | 
 | 495 |     ASSERT_EQ(static_cast<TypeParam>(-464456), this->op_->StackAt(0)); | 
 | 496 |   } else { | 
 | 497 |     ASSERT_EQ(static_cast<TypeParam>(-499868564803501823LL), this->op_->StackAt(0)); | 
 | 498 |   } | 
 | 499 | } | 
 | 500 |  | 
 | 501 | TYPED_TEST_P(DwarfOpTest, op_dup) { | 
 | 502 |   std::vector<uint8_t> opcode_buffer = { | 
 | 503 |       // Should fail since nothing is on the stack. | 
 | 504 |       0x12, | 
 | 505 |       // Push on a value and dup. | 
 | 506 |       0x08, 0x15, 0x12, | 
 | 507 |       // Do it again. | 
 | 508 |       0x08, 0x23, 0x12, | 
 | 509 |   }; | 
 | 510 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 511 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 512 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 513 |   ASSERT_EQ(0x12, this->op_->cur_op()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 514 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 515 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 516 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 517 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 518 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 519 |   ASSERT_EQ(0x12, this->op_->cur_op()); | 
 | 520 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 521 |   ASSERT_EQ(0x15U, this->op_->StackAt(0)); | 
 | 522 |   ASSERT_EQ(0x15U, this->op_->StackAt(1)); | 
 | 523 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 524 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 525 |   ASSERT_EQ(3U, this->op_->StackSize()); | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 526 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 527 |   ASSERT_EQ(0x12, this->op_->cur_op()); | 
 | 528 |   ASSERT_EQ(4U, this->op_->StackSize()); | 
 | 529 |   ASSERT_EQ(0x23U, this->op_->StackAt(0)); | 
 | 530 |   ASSERT_EQ(0x23U, this->op_->StackAt(1)); | 
 | 531 |   ASSERT_EQ(0x15U, this->op_->StackAt(2)); | 
 | 532 |   ASSERT_EQ(0x15U, this->op_->StackAt(3)); | 
 | 533 | } | 
 | 534 |  | 
 | 535 | TYPED_TEST_P(DwarfOpTest, op_drop) { | 
 | 536 |   std::vector<uint8_t> opcode_buffer = { | 
 | 537 |       // Push a couple of values. | 
 | 538 |       0x08, 0x10, 0x08, 0x20, | 
 | 539 |       // Drop the values. | 
 | 540 |       0x13, 0x13, | 
 | 541 |       // Attempt to drop empty stack. | 
 | 542 |       0x13, | 
 | 543 |   }; | 
 | 544 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 545 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 546 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 547 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 548 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 549 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 550 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 551 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 552 |   ASSERT_EQ(0x13, this->op_->cur_op()); | 
 | 553 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 554 |   ASSERT_EQ(0x10U, this->op_->StackAt(0)); | 
 | 555 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 556 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 557 |   ASSERT_EQ(0x13, this->op_->cur_op()); | 
 | 558 |   ASSERT_EQ(0U, this->op_->StackSize()); | 
 | 559 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 560 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 561 |   ASSERT_EQ(0x13, this->op_->cur_op()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 562 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 563 | } | 
 | 564 |  | 
 | 565 | TYPED_TEST_P(DwarfOpTest, op_over) { | 
 | 566 |   std::vector<uint8_t> opcode_buffer = { | 
 | 567 |       // Push a couple of values. | 
 | 568 |       0x08, 0x1a, 0x08, 0xed, | 
 | 569 |       // Copy a value. | 
 | 570 |       0x14, | 
 | 571 |       // Remove all but one element. | 
 | 572 |       0x13, 0x13, | 
 | 573 |       // Provoke a failure with this opcode. | 
 | 574 |       0x14, | 
 | 575 |   }; | 
 | 576 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 577 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 578 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 579 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 580 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 581 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 582 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 583 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 584 |   ASSERT_EQ(0x14, this->op_->cur_op()); | 
 | 585 |   ASSERT_EQ(3U, this->op_->StackSize()); | 
 | 586 |   ASSERT_EQ(0x1aU, this->op_->StackAt(0)); | 
 | 587 |   ASSERT_EQ(0xedU, this->op_->StackAt(1)); | 
 | 588 |   ASSERT_EQ(0x1aU, this->op_->StackAt(2)); | 
 | 589 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 590 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 591 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 592 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 593 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 594 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 595 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 596 |   ASSERT_EQ(0x14, this->op_->cur_op()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 597 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 598 | } | 
 | 599 |  | 
 | 600 | TYPED_TEST_P(DwarfOpTest, op_pick) { | 
 | 601 |   std::vector<uint8_t> opcode_buffer = { | 
 | 602 |       // Push a few values. | 
 | 603 |       0x08, 0x1a, 0x08, 0xed, 0x08, 0x34, | 
 | 604 |       // Copy the value at offset 2. | 
 | 605 |       0x15, 0x01, | 
 | 606 |       // Copy the last value in the stack. | 
 | 607 |       0x15, 0x03, | 
 | 608 |       // Choose an invalid index. | 
 | 609 |       0x15, 0x10, | 
 | 610 |   }; | 
 | 611 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 612 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 613 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 614 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 615 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 616 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 617 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 618 |   ASSERT_EQ(3U, this->op_->StackSize()); | 
 | 619 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 620 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 621 |   ASSERT_EQ(0x15, this->op_->cur_op()); | 
 | 622 |   ASSERT_EQ(4U, this->op_->StackSize()); | 
 | 623 |   ASSERT_EQ(0xedU, this->op_->StackAt(0)); | 
 | 624 |   ASSERT_EQ(0x34U, this->op_->StackAt(1)); | 
 | 625 |   ASSERT_EQ(0xedU, this->op_->StackAt(2)); | 
 | 626 |   ASSERT_EQ(0x1aU, this->op_->StackAt(3)); | 
 | 627 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 628 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 629 |   ASSERT_EQ(0x15, this->op_->cur_op()); | 
 | 630 |   ASSERT_EQ(5U, this->op_->StackSize()); | 
 | 631 |   ASSERT_EQ(0x1aU, this->op_->StackAt(0)); | 
 | 632 |   ASSERT_EQ(0xedU, this->op_->StackAt(1)); | 
 | 633 |   ASSERT_EQ(0x34U, this->op_->StackAt(2)); | 
 | 634 |   ASSERT_EQ(0xedU, this->op_->StackAt(3)); | 
 | 635 |   ASSERT_EQ(0x1aU, this->op_->StackAt(4)); | 
 | 636 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 637 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 638 |   ASSERT_EQ(0x15, this->op_->cur_op()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 639 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 640 | } | 
 | 641 |  | 
 | 642 | TYPED_TEST_P(DwarfOpTest, op_swap) { | 
 | 643 |   std::vector<uint8_t> opcode_buffer = { | 
 | 644 |       // Push a couple of values. | 
 | 645 |       0x08, 0x26, 0x08, 0xab, | 
 | 646 |       // Swap values. | 
 | 647 |       0x16, | 
 | 648 |       // Pop a value to cause a failure. | 
 | 649 |       0x13, 0x16, | 
 | 650 |   }; | 
 | 651 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 652 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 653 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 654 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 655 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 656 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 657 |   ASSERT_EQ(0xabU, this->op_->StackAt(0)); | 
 | 658 |   ASSERT_EQ(0x26U, this->op_->StackAt(1)); | 
 | 659 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 660 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 661 |   ASSERT_EQ(0x16, this->op_->cur_op()); | 
 | 662 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 663 |   ASSERT_EQ(0x26U, this->op_->StackAt(0)); | 
 | 664 |   ASSERT_EQ(0xabU, this->op_->StackAt(1)); | 
 | 665 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 666 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 667 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 668 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 669 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 670 |   ASSERT_EQ(0x16, this->op_->cur_op()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 671 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 672 | } | 
 | 673 |  | 
 | 674 | TYPED_TEST_P(DwarfOpTest, op_rot) { | 
 | 675 |   std::vector<uint8_t> opcode_buffer = { | 
 | 676 |       // Rotate that should cause a failure. | 
 | 677 |       0x17, 0x08, 0x10, | 
 | 678 |       // Only 1 value on stack, should fail. | 
 | 679 |       0x17, 0x08, 0x20, | 
 | 680 |       // Only 2 values on stack, should fail. | 
 | 681 |       0x17, 0x08, 0x30, | 
 | 682 |       // Should rotate properly. | 
 | 683 |       0x17, | 
 | 684 |   }; | 
 | 685 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 686 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 687 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 688 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 689 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 690 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 691 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 692 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 693 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 694 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 695 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 696 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 697 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 698 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 699 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 700 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 701 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 702 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 703 |   ASSERT_EQ(3U, this->op_->StackSize()); | 
 | 704 |   ASSERT_EQ(0x30U, this->op_->StackAt(0)); | 
 | 705 |   ASSERT_EQ(0x20U, this->op_->StackAt(1)); | 
 | 706 |   ASSERT_EQ(0x10U, this->op_->StackAt(2)); | 
 | 707 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 708 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 709 |   ASSERT_EQ(0x17, this->op_->cur_op()); | 
 | 710 |   ASSERT_EQ(3U, this->op_->StackSize()); | 
 | 711 |   ASSERT_EQ(0x20U, this->op_->StackAt(0)); | 
 | 712 |   ASSERT_EQ(0x10U, this->op_->StackAt(1)); | 
 | 713 |   ASSERT_EQ(0x30U, this->op_->StackAt(2)); | 
 | 714 | } | 
 | 715 |  | 
 | 716 | TYPED_TEST_P(DwarfOpTest, op_abs) { | 
 | 717 |   std::vector<uint8_t> opcode_buffer = { | 
 | 718 |       // Abs that should fail. | 
 | 719 |       0x19, | 
 | 720 |       // A value that is already positive. | 
 | 721 |       0x08, 0x10, 0x19, | 
 | 722 |       // A value that is negative. | 
 | 723 |       0x11, 0x7f, 0x19, | 
 | 724 |       // A value that is large and negative. | 
 | 725 |       0x11, 0x81, 0x80, 0x80, 0x80, | 
 | 726 |   }; | 
 | 727 |   if (sizeof(TypeParam) == 4) { | 
 | 728 |     opcode_buffer.push_back(0x08); | 
 | 729 |   } else { | 
 | 730 |     opcode_buffer.push_back(0x80); | 
 | 731 |     opcode_buffer.push_back(0x80); | 
 | 732 |     opcode_buffer.push_back(0x01); | 
 | 733 |   } | 
 | 734 |   opcode_buffer.push_back(0x19); | 
 | 735 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 736 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 737 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 738 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 739 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 740 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 741 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 742 |   ASSERT_EQ(0x10U, this->op_->StackAt(0)); | 
 | 743 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 744 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 745 |   ASSERT_EQ(0x19, this->op_->cur_op()); | 
 | 746 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 747 |   ASSERT_EQ(0x10U, this->op_->StackAt(0)); | 
 | 748 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 749 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 750 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 751 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 752 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 753 |   ASSERT_EQ(0x19, this->op_->cur_op()); | 
 | 754 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 755 |   ASSERT_EQ(0x1U, this->op_->StackAt(0)); | 
 | 756 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 757 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 758 |   ASSERT_EQ(3U, this->op_->StackSize()); | 
 | 759 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 760 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 761 |   ASSERT_EQ(0x19, this->op_->cur_op()); | 
 | 762 |   ASSERT_EQ(3U, this->op_->StackSize()); | 
 | 763 |   if (sizeof(TypeParam) == 4) { | 
 | 764 |     ASSERT_EQ(2147483647U, this->op_->StackAt(0)); | 
 | 765 |   } else { | 
 | 766 |     ASSERT_EQ(4398046511105UL, this->op_->StackAt(0)); | 
 | 767 |   } | 
 | 768 | } | 
 | 769 |  | 
 | 770 | TYPED_TEST_P(DwarfOpTest, op_and) { | 
 | 771 |   std::vector<uint8_t> opcode_buffer = { | 
 | 772 |       // No stack, and op will fail. | 
 | 773 |       0x1b, | 
 | 774 |       // Push a single value. | 
 | 775 |       0x08, 0x20, | 
 | 776 |       // One element stack, and op will fail. | 
 | 777 |       0x1b, | 
 | 778 |       // Push another value. | 
 | 779 |       0x08, 0x02, 0x1b, | 
 | 780 |       // Push on two negative values. | 
 | 781 |       0x11, 0x7c, 0x11, 0x7f, 0x1b, | 
 | 782 |       // Push one negative, one positive. | 
 | 783 |       0x11, 0x10, 0x11, 0x7c, 0x1b, | 
 | 784 |       // Divide by zero. | 
 | 785 |       0x11, 0x10, 0x11, 0x00, 0x1b, | 
 | 786 |   }; | 
 | 787 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 788 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 789 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 790 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 791 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 792 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 793 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 794 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 795 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 796 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 797 |  | 
 | 798 |   // Two positive values. | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 799 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 800 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 801 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 802 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 803 |   ASSERT_EQ(0x1b, this->op_->cur_op()); | 
 | 804 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 805 |   ASSERT_EQ(0x10U, this->op_->StackAt(0)); | 
 | 806 |  | 
 | 807 |   // Two negative values. | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 808 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 809 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 810 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 811 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 812 |   ASSERT_EQ(3U, this->op_->StackSize()); | 
 | 813 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 814 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 815 |   ASSERT_EQ(0x1b, this->op_->cur_op()); | 
 | 816 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 817 |   ASSERT_EQ(0x04U, this->op_->StackAt(0)); | 
 | 818 |  | 
 | 819 |   // One negative value, one positive value. | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 820 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 821 |   ASSERT_EQ(3U, this->op_->StackSize()); | 
 | 822 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 823 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 824 |   ASSERT_EQ(4U, this->op_->StackSize()); | 
 | 825 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 826 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 827 |   ASSERT_EQ(0x1b, this->op_->cur_op()); | 
 | 828 |   ASSERT_EQ(3U, this->op_->StackSize()); | 
 | 829 |   ASSERT_EQ(static_cast<TypeParam>(-4), this->op_->StackAt(0)); | 
 | 830 |  | 
 | 831 |   // Divide by zero. | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 832 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 833 |   ASSERT_EQ(4U, this->op_->StackSize()); | 
 | 834 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 835 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 836 |   ASSERT_EQ(5U, this->op_->StackSize()); | 
 | 837 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 838 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 839 |   ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 840 | } | 
 | 841 |  | 
 | 842 | TYPED_TEST_P(DwarfOpTest, op_div) { | 
 | 843 |   std::vector<uint8_t> opcode_buffer = { | 
 | 844 |       // No stack, and op will fail. | 
 | 845 |       0x1a, | 
 | 846 |       // Push a single value. | 
 | 847 |       0x08, 0x48, | 
 | 848 |       // One element stack, and op will fail. | 
 | 849 |       0x1a, | 
 | 850 |       // Push another value. | 
 | 851 |       0x08, 0xf0, 0x1a, | 
 | 852 |   }; | 
 | 853 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 854 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 855 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 856 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 857 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 858 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 859 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 860 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 861 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 862 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 863 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 864 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 865 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 866 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 867 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 868 |   ASSERT_EQ(0x1a, this->op_->cur_op()); | 
 | 869 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 870 |   ASSERT_EQ(0x40U, this->op_->StackAt(0)); | 
 | 871 | } | 
 | 872 |  | 
 | 873 | TYPED_TEST_P(DwarfOpTest, op_minus) { | 
 | 874 |   std::vector<uint8_t> opcode_buffer = { | 
 | 875 |       // No stack, and op will fail. | 
 | 876 |       0x1c, | 
 | 877 |       // Push a single value. | 
 | 878 |       0x08, 0x48, | 
 | 879 |       // One element stack, and op will fail. | 
 | 880 |       0x1c, | 
 | 881 |       // Push another value. | 
 | 882 |       0x08, 0x04, 0x1c, | 
 | 883 |   }; | 
 | 884 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 885 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 886 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 887 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 888 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 889 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 890 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 891 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 892 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 893 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 894 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 895 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 896 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 897 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 898 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 899 |   ASSERT_EQ(0x1c, this->op_->cur_op()); | 
 | 900 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 901 |   ASSERT_EQ(0x44U, this->op_->StackAt(0)); | 
 | 902 | } | 
 | 903 |  | 
 | 904 | TYPED_TEST_P(DwarfOpTest, op_mod) { | 
 | 905 |   std::vector<uint8_t> opcode_buffer = { | 
 | 906 |       // No stack, and op will fail. | 
 | 907 |       0x1d, | 
 | 908 |       // Push a single value. | 
 | 909 |       0x08, 0x47, | 
 | 910 |       // One element stack, and op will fail. | 
 | 911 |       0x1d, | 
 | 912 |       // Push another value. | 
 | 913 |       0x08, 0x04, 0x1d, | 
 | 914 |       // Try a mod of zero. | 
 | 915 |       0x08, 0x01, 0x08, 0x00, 0x1d, | 
 | 916 |   }; | 
 | 917 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 918 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 919 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 920 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 921 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 922 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 923 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 924 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 925 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 926 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 927 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 928 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 929 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 930 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 931 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 932 |   ASSERT_EQ(0x1d, this->op_->cur_op()); | 
 | 933 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 934 |   ASSERT_EQ(0x03U, this->op_->StackAt(0)); | 
 | 935 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 936 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 937 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 938 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 939 |   ASSERT_EQ(3U, this->op_->StackSize()); | 
 | 940 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 941 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 942 |   ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 943 | } | 
 | 944 |  | 
 | 945 | TYPED_TEST_P(DwarfOpTest, op_mul) { | 
 | 946 |   std::vector<uint8_t> opcode_buffer = { | 
 | 947 |       // No stack, and op will fail. | 
 | 948 |       0x1e, | 
 | 949 |       // Push a single value. | 
 | 950 |       0x08, 0x48, | 
 | 951 |       // One element stack, and op will fail. | 
 | 952 |       0x1e, | 
 | 953 |       // Push another value. | 
 | 954 |       0x08, 0x04, 0x1e, | 
 | 955 |   }; | 
 | 956 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 957 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 958 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 959 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 960 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 961 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 962 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 963 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 964 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 965 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 966 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 967 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 968 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 969 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 970 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 971 |   ASSERT_EQ(0x1e, this->op_->cur_op()); | 
 | 972 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 973 |   ASSERT_EQ(0x120U, this->op_->StackAt(0)); | 
 | 974 | } | 
 | 975 |  | 
 | 976 | TYPED_TEST_P(DwarfOpTest, op_neg) { | 
 | 977 |   std::vector<uint8_t> opcode_buffer = { | 
 | 978 |       // No stack, and op will fail. | 
 | 979 |       0x1f, | 
 | 980 |       // Push a single value. | 
 | 981 |       0x08, 0x48, 0x1f, | 
 | 982 |       // Push a negative value. | 
 | 983 |       0x11, 0x7f, 0x1f, | 
 | 984 |   }; | 
 | 985 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 986 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 987 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 988 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 989 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 990 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 991 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 992 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 993 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 994 |   ASSERT_EQ(0x1f, this->op_->cur_op()); | 
 | 995 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 996 |   ASSERT_EQ(static_cast<TypeParam>(-72), this->op_->StackAt(0)); | 
 | 997 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 998 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 999 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 1000 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1001 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1002 |   ASSERT_EQ(0x1f, this->op_->cur_op()); | 
 | 1003 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 1004 |   ASSERT_EQ(0x01U, this->op_->StackAt(0)); | 
 | 1005 | } | 
 | 1006 |  | 
 | 1007 | TYPED_TEST_P(DwarfOpTest, op_not) { | 
 | 1008 |   std::vector<uint8_t> opcode_buffer = { | 
 | 1009 |       // No stack, and op will fail. | 
 | 1010 |       0x20, | 
 | 1011 |       // Push a single value. | 
 | 1012 |       0x08, 0x4, 0x20, | 
 | 1013 |       // Push a negative value. | 
 | 1014 |       0x11, 0x7c, 0x20, | 
 | 1015 |   }; | 
 | 1016 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 1017 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1018 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 1019 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1020 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1021 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1022 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 1023 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1024 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1025 |   ASSERT_EQ(0x20, this->op_->cur_op()); | 
 | 1026 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 1027 |   ASSERT_EQ(static_cast<TypeParam>(-5), this->op_->StackAt(0)); | 
 | 1028 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1029 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1030 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 1031 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1032 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1033 |   ASSERT_EQ(0x20, this->op_->cur_op()); | 
 | 1034 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 1035 |   ASSERT_EQ(0x03U, this->op_->StackAt(0)); | 
 | 1036 | } | 
 | 1037 |  | 
 | 1038 | TYPED_TEST_P(DwarfOpTest, op_or) { | 
 | 1039 |   std::vector<uint8_t> opcode_buffer = { | 
 | 1040 |       // No stack, and op will fail. | 
 | 1041 |       0x21, | 
 | 1042 |       // Push a single value. | 
 | 1043 |       0x08, 0x48, | 
 | 1044 |       // One element stack, and op will fail. | 
 | 1045 |       0x21, | 
 | 1046 |       // Push another value. | 
 | 1047 |       0x08, 0xf4, 0x21, | 
 | 1048 |   }; | 
 | 1049 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 1050 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1051 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 1052 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1053 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1054 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1055 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 1056 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1057 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 1058 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1059 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1060 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1061 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 1062 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1063 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1064 |   ASSERT_EQ(0x21, this->op_->cur_op()); | 
 | 1065 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 1066 |   ASSERT_EQ(0xfcU, this->op_->StackAt(0)); | 
 | 1067 | } | 
 | 1068 |  | 
 | 1069 | TYPED_TEST_P(DwarfOpTest, op_plus) { | 
 | 1070 |   std::vector<uint8_t> opcode_buffer = { | 
 | 1071 |       // No stack, and op will fail. | 
 | 1072 |       0x22, | 
 | 1073 |       // Push a single value. | 
 | 1074 |       0x08, 0xff, | 
 | 1075 |       // One element stack, and op will fail. | 
 | 1076 |       0x22, | 
 | 1077 |       // Push another value. | 
 | 1078 |       0x08, 0xf2, 0x22, | 
 | 1079 |   }; | 
 | 1080 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 1081 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1082 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 1083 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1084 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1085 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1086 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 1087 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1088 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 1089 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1090 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1091 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1092 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 1093 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1094 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1095 |   ASSERT_EQ(0x22, this->op_->cur_op()); | 
 | 1096 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 1097 |   ASSERT_EQ(0x1f1U, this->op_->StackAt(0)); | 
 | 1098 | } | 
 | 1099 |  | 
 | 1100 | TYPED_TEST_P(DwarfOpTest, op_plus_uconst) { | 
 | 1101 |   std::vector<uint8_t> opcode_buffer = { | 
 | 1102 |       // No stack, and op will fail. | 
 | 1103 |       0x23, | 
 | 1104 |       // Push a single value. | 
 | 1105 |       0x08, 0x50, 0x23, 0x80, 0x51, | 
 | 1106 |   }; | 
 | 1107 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 1108 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1109 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 1110 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1111 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1112 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1113 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 1114 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1115 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1116 |   ASSERT_EQ(0x23, this->op_->cur_op()); | 
 | 1117 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 1118 |   ASSERT_EQ(0x28d0U, this->op_->StackAt(0)); | 
 | 1119 | } | 
 | 1120 |  | 
 | 1121 | TYPED_TEST_P(DwarfOpTest, op_shl) { | 
 | 1122 |   std::vector<uint8_t> opcode_buffer = { | 
 | 1123 |       // No stack, and op will fail. | 
 | 1124 |       0x24, | 
 | 1125 |       // Push a single value. | 
 | 1126 |       0x08, 0x67, | 
 | 1127 |       // One element stack, and op will fail. | 
 | 1128 |       0x24, | 
 | 1129 |       // Push another value. | 
 | 1130 |       0x08, 0x03, 0x24, | 
 | 1131 |   }; | 
 | 1132 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 1133 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1134 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 1135 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1136 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1137 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1138 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 1139 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1140 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 1141 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1142 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1143 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1144 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 1145 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1146 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1147 |   ASSERT_EQ(0x24, this->op_->cur_op()); | 
 | 1148 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 1149 |   ASSERT_EQ(0x338U, this->op_->StackAt(0)); | 
 | 1150 | } | 
 | 1151 |  | 
 | 1152 | TYPED_TEST_P(DwarfOpTest, op_shr) { | 
 | 1153 |   std::vector<uint8_t> opcode_buffer = { | 
 | 1154 |       // No stack, and op will fail. | 
 | 1155 |       0x25, | 
 | 1156 |       // Push a single value. | 
 | 1157 |       0x11, 0x70, | 
 | 1158 |       // One element stack, and op will fail. | 
 | 1159 |       0x25, | 
 | 1160 |       // Push another value. | 
 | 1161 |       0x08, 0x03, 0x25, | 
 | 1162 |   }; | 
 | 1163 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 1164 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1165 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 1166 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1167 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1168 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1169 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 1170 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1171 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 1172 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1173 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1174 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1175 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 1176 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1177 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1178 |   ASSERT_EQ(0x25, this->op_->cur_op()); | 
 | 1179 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 1180 |   if (sizeof(TypeParam) == 4) { | 
 | 1181 |     ASSERT_EQ(0x1ffffffeU, this->op_->StackAt(0)); | 
 | 1182 |   } else { | 
 | 1183 |     ASSERT_EQ(0x1ffffffffffffffeULL, this->op_->StackAt(0)); | 
 | 1184 |   } | 
 | 1185 | } | 
 | 1186 |  | 
 | 1187 | TYPED_TEST_P(DwarfOpTest, op_shra) { | 
 | 1188 |   std::vector<uint8_t> opcode_buffer = { | 
 | 1189 |       // No stack, and op will fail. | 
 | 1190 |       0x26, | 
 | 1191 |       // Push a single value. | 
 | 1192 |       0x11, 0x70, | 
 | 1193 |       // One element stack, and op will fail. | 
 | 1194 |       0x26, | 
 | 1195 |       // Push another value. | 
 | 1196 |       0x08, 0x03, 0x26, | 
 | 1197 |   }; | 
 | 1198 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 1199 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1200 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 1201 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1202 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1203 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1204 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 1205 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1206 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 1207 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1208 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1209 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1210 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 1211 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1212 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1213 |   ASSERT_EQ(0x26, this->op_->cur_op()); | 
 | 1214 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 1215 |   ASSERT_EQ(static_cast<TypeParam>(-2), this->op_->StackAt(0)); | 
 | 1216 | } | 
 | 1217 |  | 
 | 1218 | TYPED_TEST_P(DwarfOpTest, op_xor) { | 
 | 1219 |   std::vector<uint8_t> opcode_buffer = { | 
 | 1220 |       // No stack, and op will fail. | 
 | 1221 |       0x27, | 
 | 1222 |       // Push a single value. | 
 | 1223 |       0x08, 0x11, | 
 | 1224 |       // One element stack, and op will fail. | 
 | 1225 |       0x27, | 
 | 1226 |       // Push another value. | 
 | 1227 |       0x08, 0x41, 0x27, | 
 | 1228 |   }; | 
 | 1229 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 1230 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1231 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 1232 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1233 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1234 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1235 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 1236 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1237 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 1238 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1239 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1240 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1241 |   ASSERT_EQ(2U, this->op_->StackSize()); | 
 | 1242 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1243 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1244 |   ASSERT_EQ(0x27, this->op_->cur_op()); | 
 | 1245 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 1246 |   ASSERT_EQ(0x50U, this->op_->StackAt(0)); | 
 | 1247 | } | 
 | 1248 |  | 
 | 1249 | TYPED_TEST_P(DwarfOpTest, op_bra) { | 
 | 1250 |   std::vector<uint8_t> opcode_buffer = { | 
 | 1251 |       // No stack, and op will fail. | 
 | 1252 |       0x28, | 
 | 1253 |       // Push on a non-zero value with a positive branch. | 
 | 1254 |       0x08, 0x11, 0x28, 0x02, 0x01, | 
 | 1255 |       // Push on a zero value with a positive branch. | 
 | 1256 |       0x08, 0x00, 0x28, 0x05, 0x00, | 
 | 1257 |       // Push on a non-zero value with a negative branch. | 
 | 1258 |       0x08, 0x11, 0x28, 0xfc, 0xff, | 
 | 1259 |       // Push on a zero value with a negative branch. | 
 | 1260 |       0x08, 0x00, 0x28, 0xf0, 0xff, | 
 | 1261 |   }; | 
 | 1262 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 1263 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1264 |   ASSERT_FALSE(this->op_->Decode()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 1265 |   ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1266 |  | 
 | 1267 |   // Push on a non-zero value with a positive branch. | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1268 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1269 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 1270 |  | 
 | 1271 |   uint64_t offset = this->mem_->cur_offset() + 3; | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1272 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1273 |   ASSERT_EQ(0x28, this->op_->cur_op()); | 
 | 1274 |   ASSERT_EQ(0U, this->op_->StackSize()); | 
 | 1275 |   ASSERT_EQ(offset + 0x102, this->mem_->cur_offset()); | 
 | 1276 |  | 
 | 1277 |   // Push on a zero value with a positive branch. | 
 | 1278 |   this->mem_->set_cur_offset(offset); | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1279 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1280 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 1281 |  | 
 | 1282 |   offset = this->mem_->cur_offset() + 3; | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1283 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1284 |   ASSERT_EQ(0x28, this->op_->cur_op()); | 
 | 1285 |   ASSERT_EQ(0U, this->op_->StackSize()); | 
 | 1286 |   ASSERT_EQ(offset - 5, this->mem_->cur_offset()); | 
 | 1287 |  | 
 | 1288 |   // Push on a non-zero value with a negative branch. | 
 | 1289 |   this->mem_->set_cur_offset(offset); | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1290 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1291 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 1292 |  | 
 | 1293 |   offset = this->mem_->cur_offset() + 3; | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1294 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1295 |   ASSERT_EQ(0x28, this->op_->cur_op()); | 
 | 1296 |   ASSERT_EQ(0U, this->op_->StackSize()); | 
 | 1297 |   ASSERT_EQ(offset - 4, this->mem_->cur_offset()); | 
 | 1298 |  | 
 | 1299 |   // Push on a zero value with a negative branch. | 
 | 1300 |   this->mem_->set_cur_offset(offset); | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1301 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1302 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 1303 |  | 
 | 1304 |   offset = this->mem_->cur_offset() + 3; | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1305 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1306 |   ASSERT_EQ(0x28, this->op_->cur_op()); | 
 | 1307 |   ASSERT_EQ(0U, this->op_->StackSize()); | 
 | 1308 |   ASSERT_EQ(offset + 16, this->mem_->cur_offset()); | 
 | 1309 | } | 
 | 1310 |  | 
 | 1311 | TYPED_TEST_P(DwarfOpTest, compare_opcode_stack_error) { | 
 | 1312 |   // All of the ops require two stack elements. Loop through all of these | 
 | 1313 |   // ops with potential errors. | 
 | 1314 |   std::vector<uint8_t> opcode_buffer = { | 
 | 1315 |       0xff,  // Place holder for compare op. | 
 | 1316 |       0x08, 0x11, | 
 | 1317 |       0xff,  // Place holder for compare op. | 
 | 1318 |   }; | 
 | 1319 |  | 
 | 1320 |   for (uint8_t opcode = 0x29; opcode <= 0x2e; opcode++) { | 
 | 1321 |     opcode_buffer[0] = opcode; | 
 | 1322 |     opcode_buffer[3] = opcode; | 
 | 1323 |     this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 1324 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1325 |     ASSERT_FALSE(this->op_->Eval(0, 1)); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1326 |     ASSERT_EQ(opcode, this->op_->cur_op()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 1327 |     ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1328 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1329 |     ASSERT_FALSE(this->op_->Eval(1, 4)); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1330 |     ASSERT_EQ(opcode, this->op_->cur_op()); | 
 | 1331 |     ASSERT_EQ(1U, this->op_->StackSize()); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 1332 |     ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1333 |   } | 
 | 1334 | } | 
 | 1335 |  | 
 | 1336 | TYPED_TEST_P(DwarfOpTest, compare_opcodes) { | 
 | 1337 |   // Have three different checks for each compare op: | 
 | 1338 |   //   - Both values the same. | 
 | 1339 |   //   - The first value larger than the second. | 
 | 1340 |   //   - The second value larger than the first. | 
 | 1341 |   std::vector<uint8_t> opcode_buffer = { | 
 | 1342 |       // Values the same. | 
 | 1343 |       0x08, 0x11, 0x08, 0x11, | 
 | 1344 |       0xff,  // Placeholder. | 
 | 1345 |       // First value larger. | 
 | 1346 |       0x08, 0x12, 0x08, 0x10, | 
 | 1347 |       0xff,  // Placeholder. | 
 | 1348 |       // Second value larger. | 
 | 1349 |       0x08, 0x10, 0x08, 0x12, | 
 | 1350 |       0xff,  // Placeholder. | 
 | 1351 |   }; | 
 | 1352 |  | 
 | 1353 |   // Opcode followed by the expected values on the stack. | 
 | 1354 |   std::vector<uint8_t> expected = { | 
 | 1355 |       0x29, 1, 0, 0,  // eq | 
 | 1356 |       0x2a, 1, 1, 0,  // ge | 
 | 1357 |       0x2b, 0, 1, 0,  // gt | 
 | 1358 |       0x2c, 1, 0, 1,  // le | 
 | 1359 |       0x2d, 0, 0, 1,  // lt | 
 | 1360 |       0x2e, 0, 1, 1,  // ne | 
 | 1361 |   }; | 
 | 1362 |   for (size_t i = 0; i < expected.size(); i += 4) { | 
 | 1363 |     opcode_buffer[4] = expected[i]; | 
 | 1364 |     opcode_buffer[9] = expected[i]; | 
 | 1365 |     opcode_buffer[14] = expected[i]; | 
 | 1366 |     this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 1367 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1368 |     ASSERT_TRUE(this->op_->Eval(0, 15)) | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1369 |         << "Op: 0x" << std::hex << static_cast<uint32_t>(expected[i]) << " failed"; | 
 | 1370 |  | 
 | 1371 |     ASSERT_EQ(3U, this->op_->StackSize()); | 
 | 1372 |     ASSERT_EQ(expected[i + 1], this->op_->StackAt(2)); | 
 | 1373 |     ASSERT_EQ(expected[i + 2], this->op_->StackAt(1)); | 
 | 1374 |     ASSERT_EQ(expected[i + 3], this->op_->StackAt(0)); | 
 | 1375 |   } | 
 | 1376 | } | 
 | 1377 |  | 
 | 1378 | TYPED_TEST_P(DwarfOpTest, op_skip) { | 
 | 1379 |   std::vector<uint8_t> opcode_buffer = { | 
 | 1380 |       // Positive value. | 
 | 1381 |       0x2f, 0x10, 0x20, | 
 | 1382 |       // Negative value. | 
 | 1383 |       0x2f, 0xfd, 0xff, | 
 | 1384 |   }; | 
 | 1385 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 1386 |  | 
 | 1387 |   uint64_t offset = this->mem_->cur_offset() + 3; | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1388 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1389 |   ASSERT_EQ(0x2f, this->op_->cur_op()); | 
 | 1390 |   ASSERT_EQ(0U, this->op_->StackSize()); | 
 | 1391 |   ASSERT_EQ(offset + 0x2010, this->mem_->cur_offset()); | 
 | 1392 |  | 
 | 1393 |   this->mem_->set_cur_offset(offset); | 
 | 1394 |   offset = this->mem_->cur_offset() + 3; | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1395 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1396 |   ASSERT_EQ(0x2f, this->op_->cur_op()); | 
 | 1397 |   ASSERT_EQ(0U, this->op_->StackSize()); | 
 | 1398 |   ASSERT_EQ(offset - 3, this->mem_->cur_offset()); | 
 | 1399 | } | 
 | 1400 |  | 
 | 1401 | TYPED_TEST_P(DwarfOpTest, op_lit) { | 
 | 1402 |   std::vector<uint8_t> opcode_buffer; | 
 | 1403 |  | 
 | 1404 |   // Verify every lit opcode. | 
 | 1405 |   for (uint8_t op = 0x30; op <= 0x4f; op++) { | 
 | 1406 |     opcode_buffer.push_back(op); | 
 | 1407 |   } | 
 | 1408 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 1409 |  | 
 | 1410 |   for (size_t i = 0; i < opcode_buffer.size(); i++) { | 
 | 1411 |     uint32_t op = opcode_buffer[i]; | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1412 |     ASSERT_TRUE(this->op_->Eval(i, i + 1)) << "Failed op: 0x" << std::hex << op; | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1413 |     ASSERT_EQ(op, this->op_->cur_op()); | 
 | 1414 |     ASSERT_EQ(1U, this->op_->StackSize()) << "Failed op: 0x" << std::hex << op; | 
 | 1415 |     ASSERT_EQ(op - 0x30U, this->op_->StackAt(0)) << "Failed op: 0x" << std::hex << op; | 
 | 1416 |   } | 
 | 1417 | } | 
 | 1418 |  | 
 | 1419 | TYPED_TEST_P(DwarfOpTest, op_reg) { | 
 | 1420 |   std::vector<uint8_t> opcode_buffer; | 
 | 1421 |  | 
 | 1422 |   // Verify every reg opcode. | 
 | 1423 |   for (uint8_t op = 0x50; op <= 0x6f; op++) { | 
 | 1424 |     opcode_buffer.push_back(op); | 
 | 1425 |   } | 
 | 1426 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 1427 |  | 
 | 1428 |   for (size_t i = 0; i < opcode_buffer.size(); i++) { | 
 | 1429 |     uint32_t op = opcode_buffer[i]; | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1430 |     ASSERT_TRUE(this->op_->Eval(i, i + 1)) << "Failed op: 0x" << std::hex << op; | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1431 |     ASSERT_EQ(op, this->op_->cur_op()); | 
 | 1432 |     ASSERT_TRUE(this->op_->is_register()) << "Failed op: 0x" << std::hex << op; | 
 | 1433 |     ASSERT_EQ(1U, this->op_->StackSize()) << "Failed op: 0x" << std::hex << op; | 
 | 1434 |     ASSERT_EQ(op - 0x50U, this->op_->StackAt(0)) << "Failed op: 0x" << std::hex << op; | 
 | 1435 |   } | 
 | 1436 | } | 
 | 1437 |  | 
 | 1438 | TYPED_TEST_P(DwarfOpTest, op_regx) { | 
 | 1439 |   std::vector<uint8_t> opcode_buffer = { | 
 | 1440 |       0x90, 0x02, 0x90, 0x80, 0x15, | 
 | 1441 |   }; | 
 | 1442 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 1443 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1444 |   ASSERT_TRUE(this->op_->Eval(0, 2)); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1445 |   ASSERT_EQ(0x90, this->op_->cur_op()); | 
 | 1446 |   ASSERT_TRUE(this->op_->is_register()); | 
 | 1447 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 1448 |   ASSERT_EQ(0x02U, this->op_->StackAt(0)); | 
 | 1449 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1450 |   ASSERT_TRUE(this->op_->Eval(2, 5)); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1451 |   ASSERT_EQ(0x90, this->op_->cur_op()); | 
 | 1452 |   ASSERT_TRUE(this->op_->is_register()); | 
 | 1453 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 1454 |   ASSERT_EQ(0xa80U, this->op_->StackAt(0)); | 
 | 1455 | } | 
 | 1456 |  | 
 | 1457 | TYPED_TEST_P(DwarfOpTest, op_breg) { | 
 | 1458 |   std::vector<uint8_t> opcode_buffer; | 
 | 1459 |  | 
 | 1460 |   // Verify every reg opcode. | 
 | 1461 |   for (uint8_t op = 0x70; op <= 0x8f; op++) { | 
 | 1462 |     // Positive value added to register. | 
 | 1463 |     opcode_buffer.push_back(op); | 
 | 1464 |     opcode_buffer.push_back(0x12); | 
 | 1465 |     // Negative value added to register. | 
 | 1466 |     opcode_buffer.push_back(op); | 
 | 1467 |     opcode_buffer.push_back(0x7e); | 
 | 1468 |   } | 
 | 1469 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 1470 |  | 
| Yabin Cui | 11e96fe | 2018-03-14 18:16:22 -0700 | [diff] [blame] | 1471 |   RegsImplFake<TypeParam> regs(32); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1472 |   for (size_t i = 0; i < 32; i++) { | 
 | 1473 |     regs[i] = i + 10; | 
 | 1474 |   } | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1475 |   RegsInfo<TypeParam> regs_info(®s); | 
 | 1476 |   this->op_->set_regs_info(®s_info); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1477 |  | 
 | 1478 |   uint64_t offset = 0; | 
 | 1479 |   for (uint32_t op = 0x70; op <= 0x8f; op++) { | 
 | 1480 |     // Positive value added to register. | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1481 |     ASSERT_TRUE(this->op_->Eval(offset, offset + 2)) << "Failed op: 0x" << std::hex << op; | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1482 |     ASSERT_EQ(op, this->op_->cur_op()); | 
 | 1483 |     ASSERT_EQ(1U, this->op_->StackSize()) << "Failed op: 0x" << std::hex << op; | 
 | 1484 |     ASSERT_EQ(op - 0x70 + 10 + 0x12, this->op_->StackAt(0)) << "Failed op: 0x" << std::hex << op; | 
 | 1485 |     offset += 2; | 
 | 1486 |  | 
 | 1487 |     // Negative value added to register. | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1488 |     ASSERT_TRUE(this->op_->Eval(offset, offset + 2)) << "Failed op: 0x" << std::hex << op; | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1489 |     ASSERT_EQ(op, this->op_->cur_op()); | 
 | 1490 |     ASSERT_EQ(1U, this->op_->StackSize()) << "Failed op: 0x" << std::hex << op; | 
 | 1491 |     ASSERT_EQ(op - 0x70 + 10 - 2, this->op_->StackAt(0)) << "Failed op: 0x" << std::hex << op; | 
 | 1492 |     offset += 2; | 
 | 1493 |   } | 
 | 1494 | } | 
 | 1495 |  | 
 | 1496 | TYPED_TEST_P(DwarfOpTest, op_breg_invalid_register) { | 
 | 1497 |   std::vector<uint8_t> opcode_buffer = { | 
 | 1498 |       0x7f, 0x12, 0x80, 0x12, | 
 | 1499 |   }; | 
 | 1500 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 1501 |  | 
| Yabin Cui | 11e96fe | 2018-03-14 18:16:22 -0700 | [diff] [blame] | 1502 |   RegsImplFake<TypeParam> regs(16); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1503 |   for (size_t i = 0; i < 16; i++) { | 
 | 1504 |     regs[i] = i + 10; | 
 | 1505 |   } | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1506 |   RegsInfo<TypeParam> regs_info(®s); | 
 | 1507 |   this->op_->set_regs_info(®s_info); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1508 |  | 
 | 1509 |   // Should pass since this references the last regsister. | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1510 |   ASSERT_TRUE(this->op_->Eval(0, 2)); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1511 |   ASSERT_EQ(0x7fU, this->op_->cur_op()); | 
 | 1512 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 1513 |   ASSERT_EQ(0x2bU, this->op_->StackAt(0)); | 
 | 1514 |  | 
 | 1515 |   // Should fail since this references a non-existent register. | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1516 |   ASSERT_FALSE(this->op_->Eval(2, 4)); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 1517 |   ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1518 | } | 
 | 1519 |  | 
 | 1520 | TYPED_TEST_P(DwarfOpTest, op_bregx) { | 
 | 1521 |   std::vector<uint8_t> opcode_buffer = {// Positive value added to register. | 
 | 1522 |                                         0x92, 0x05, 0x20, | 
 | 1523 |                                         // Negative value added to register. | 
 | 1524 |                                         0x92, 0x06, 0x80, 0x7e, | 
 | 1525 |                                         // Illegal register. | 
 | 1526 |                                         0x92, 0x80, 0x15, 0x80, 0x02}; | 
 | 1527 |   this->op_memory_.SetMemory(0, opcode_buffer); | 
 | 1528 |  | 
| Yabin Cui | 11e96fe | 2018-03-14 18:16:22 -0700 | [diff] [blame] | 1529 |   RegsImplFake<TypeParam> regs(10); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1530 |   regs[5] = 0x45; | 
 | 1531 |   regs[6] = 0x190; | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1532 |   RegsInfo<TypeParam> regs_info(®s); | 
 | 1533 |   this->op_->set_regs_info(®s_info); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1534 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1535 |   ASSERT_TRUE(this->op_->Eval(0, 3)); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1536 |   ASSERT_EQ(0x92, this->op_->cur_op()); | 
 | 1537 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 1538 |   ASSERT_EQ(0x65U, this->op_->StackAt(0)); | 
 | 1539 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1540 |   ASSERT_TRUE(this->op_->Eval(3, 7)); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1541 |   ASSERT_EQ(0x92, this->op_->cur_op()); | 
 | 1542 |   ASSERT_EQ(1U, this->op_->StackSize()); | 
 | 1543 |   ASSERT_EQ(0x90U, this->op_->StackAt(0)); | 
 | 1544 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1545 |   ASSERT_FALSE(this->op_->Eval(7, 12)); | 
| Christopher Ferris | 2fcf4cf | 2018-01-23 17:52:23 -0800 | [diff] [blame] | 1546 |   ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1547 | } | 
 | 1548 |  | 
 | 1549 | TYPED_TEST_P(DwarfOpTest, op_nop) { | 
 | 1550 |   this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x96}); | 
 | 1551 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1552 |   ASSERT_TRUE(this->op_->Decode()); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1553 |   ASSERT_EQ(0x96, this->op_->cur_op()); | 
 | 1554 |   ASSERT_EQ(0U, this->op_->StackSize()); | 
 | 1555 | } | 
 | 1556 |  | 
| Christopher Ferris | 559c7f2 | 2018-02-12 20:18:03 -0800 | [diff] [blame] | 1557 | TYPED_TEST_P(DwarfOpTest, is_dex_pc) { | 
 | 1558 |   // Special sequence that indicates this is a dex pc. | 
 | 1559 |   this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x0c, 'D', 'E', 'X', '1', 0x13}); | 
 | 1560 |  | 
 | 1561 |   ASSERT_TRUE(this->op_->Eval(0, 6)); | 
 | 1562 |   EXPECT_TRUE(this->op_->dex_pc_set()); | 
 | 1563 |  | 
 | 1564 |   // Try without the last op. | 
 | 1565 |   ASSERT_TRUE(this->op_->Eval(0, 5)); | 
 | 1566 |   EXPECT_FALSE(this->op_->dex_pc_set()); | 
 | 1567 |  | 
 | 1568 |   // Change the constant. | 
 | 1569 |   this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x0c, 'D', 'E', 'X', '2', 0x13}); | 
 | 1570 |   ASSERT_TRUE(this->op_->Eval(0, 6)); | 
 | 1571 |   EXPECT_FALSE(this->op_->dex_pc_set()); | 
 | 1572 | } | 
 | 1573 |  | 
| Christopher Ferris | 7e21eba | 2019-06-20 16:16:42 -0700 | [diff] [blame] | 1574 | REGISTER_TYPED_TEST_SUITE_P(DwarfOpTest, decode, eval, illegal_opcode, not_implemented, op_addr, | 
 | 1575 |                             op_deref, op_deref_size, const_unsigned, const_signed, const_uleb, | 
 | 1576 |                             const_sleb, op_dup, op_drop, op_over, op_pick, op_swap, op_rot, op_abs, | 
 | 1577 |                             op_and, op_div, op_minus, op_mod, op_mul, op_neg, op_not, op_or, | 
 | 1578 |                             op_plus, op_plus_uconst, op_shl, op_shr, op_shra, op_xor, op_bra, | 
 | 1579 |                             compare_opcode_stack_error, compare_opcodes, op_skip, op_lit, op_reg, | 
 | 1580 |                             op_regx, op_breg, op_breg_invalid_register, op_bregx, op_nop, | 
 | 1581 |                             is_dex_pc); | 
| Christopher Ferris | 55d22ef | 2017-04-04 10:41:31 -0700 | [diff] [blame] | 1582 |  | 
 | 1583 | typedef ::testing::Types<uint32_t, uint64_t> DwarfOpTestTypes; | 
| Haibo Huang | 0c01bb6 | 2019-12-11 12:46:20 -0800 | [diff] [blame] | 1584 | INSTANTIATE_TYPED_TEST_SUITE_P(Libunwindstack, DwarfOpTest, DwarfOpTestTypes); | 
| Christopher Ferris | d226a51 | 2017-07-14 10:37:19 -0700 | [diff] [blame] | 1585 |  | 
 | 1586 | }  // namespace unwindstack |