blob: 0898ec0efcf6b5d71d65ed934bb097460fccbc26 [file] [log] [blame]
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001/*
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 Ferris2fcf4cf2018-01-23 17:52:23 -080024#include <unwindstack/DwarfError.h>
Christopher Ferrisd226a512017-07-14 10:37:19 -070025#include <unwindstack/DwarfMemory.h>
26#include <unwindstack/Log.h>
27
Christopher Ferris55d22ef2017-04-04 10:41:31 -070028#include "DwarfOp.h"
Christopher Ferris55d22ef2017-04-04 10:41:31 -070029
30#include "MemoryFake.h"
Christopher Ferris53a3c9b2017-05-10 18:34:15 -070031#include "RegsFake.h"
Christopher Ferris55d22ef2017-04-04 10:41:31 -070032
Christopher Ferrisd226a512017-07-14 10:37:19 -070033namespace unwindstack {
34
Christopher Ferris55d22ef2017-04-04 10:41:31 -070035template <typename TypeParam>
36class 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(), &regular_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 Ferris7e21eba2019-06-20 16:16:42 -070051TYPED_TEST_SUITE_P(DwarfOpTest);
Christopher Ferris55d22ef2017-04-04 10:41:31 -070052
53TYPED_TEST_P(DwarfOpTest, decode) {
54 // Memory error.
Christopher Ferris559c7f22018-02-12 20:18:03 -080055 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -080056 ASSERT_EQ(DWARF_ERROR_MEMORY_INVALID, this->op_->LastErrorCode());
57 EXPECT_EQ(0U, this->op_->LastErrorAddress());
Christopher Ferris55d22ef2017-04-04 10:41:31 -070058
59 // No error.
60 this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x96});
61 this->mem_->set_cur_offset(0);
Christopher Ferris559c7f22018-02-12 20:18:03 -080062 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -080063 ASSERT_EQ(DWARF_ERROR_NONE, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -070064 ASSERT_EQ(0x96U, this->op_->cur_op());
65 ASSERT_EQ(1U, this->mem_->cur_offset());
66}
67
68TYPED_TEST_P(DwarfOpTest, eval) {
69 // Memory error.
Christopher Ferris559c7f22018-02-12 20:18:03 -080070 ASSERT_FALSE(this->op_->Eval(0, 2));
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -080071 ASSERT_EQ(DWARF_ERROR_MEMORY_INVALID, this->op_->LastErrorCode());
72 EXPECT_EQ(0U, this->op_->LastErrorAddress());
Christopher Ferris55d22ef2017-04-04 10:41:31 -070073
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 Ferris559c7f22018-02-12 20:18:03 -080077 ASSERT_TRUE(this->op_->Eval(0, 1));
Christopher Ferris55d22ef2017-04-04 10:41:31 -070078 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 Ferris559c7f22018-02-12 20:18:03 -080088 ASSERT_TRUE(this->op_->Eval(0, 8));
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -080089 ASSERT_EQ(DWARF_ERROR_NONE, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -070090 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 Ferris559c7f22018-02-12 20:18:03 -0800100 ASSERT_FALSE(this->op_->Eval(0, 4));
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800101 ASSERT_EQ(DWARF_ERROR_TOO_MANY_ITERATIONS, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700102 ASSERT_FALSE(this->op_->is_register());
103 ASSERT_EQ(0U, this->op_->StackSize());
104}
105
106TYPED_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 Ferris559c7f22018-02-12 20:18:03 -0800115 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800116 ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700117 ASSERT_EQ(opcode_buffer[i], this->op_->cur_op());
118 }
119}
120
121TYPED_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 Ferris559c7f22018-02-12 20:18:03 -0800155 ASSERT_TRUE(this->op_->Decode());
156 ASSERT_TRUE(this->op_->Decode());
157 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700158
159 while (this->mem_->cur_offset() < opcode_buffer.size()) {
Christopher Ferris559c7f22018-02-12 20:18:03 -0800160 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800161 ASSERT_EQ(DWARF_ERROR_NOT_IMPLEMENTED, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700162 }
163}
164
165TYPED_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 Ferris559c7f22018-02-12 20:18:03 -0800175 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700176 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
185TYPED_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 Ferris559c7f22018-02-12 20:18:03 -0800198 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800199 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700200
Christopher Ferris559c7f22018-02-12 20:18:03 -0800201 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700202 ASSERT_EQ(1U, this->op_->StackSize());
Christopher Ferris559c7f22018-02-12 20:18:03 -0800203 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700204 ASSERT_EQ(0x06, this->op_->cur_op());
205 ASSERT_EQ(1U, this->op_->StackSize());
206 ASSERT_EQ(value, this->op_->StackAt(0));
207
Christopher Ferris559c7f22018-02-12 20:18:03 -0800208 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800209 ASSERT_EQ(DWARF_ERROR_MEMORY_INVALID, this->op_->LastErrorCode());
210 ASSERT_EQ(0x12345678U, this->op_->LastErrorAddress());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700211}
212
213TYPED_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 Ferris559c7f22018-02-12 20:18:03 -0800218 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800219 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700220
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 Ferris559c7f22018-02-12 20:18:03 -0800225 ASSERT_TRUE(this->op_->Eval(0, 5)) << "Failed at size " << i;
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700226 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 Ferris559c7f22018-02-12 20:18:03 -0800235 ASSERT_FALSE(this->op_->Eval(0, 5));
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800236 ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700237
238 // Read too many bytes.
239 this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x0a, 0x10, 0x20, 0x94, sizeof(TypeParam) + 1});
Christopher Ferris559c7f22018-02-12 20:18:03 -0800240 ASSERT_FALSE(this->op_->Eval(0, 5));
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800241 ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700242
243 // Force bad memory read.
244 this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x0a, 0x10, 0x40, 0x94, 0x01});
Christopher Ferris559c7f22018-02-12 20:18:03 -0800245 ASSERT_FALSE(this->op_->Eval(0, 5));
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800246 ASSERT_EQ(DWARF_ERROR_MEMORY_INVALID, this->op_->LastErrorCode());
247 EXPECT_EQ(0x4010U, this->op_->LastErrorAddress());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700248}
249
250TYPED_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 Ferris559c7f22018-02-12 20:18:03 -0800265 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700266 ASSERT_EQ(0x08, this->op_->cur_op());
267 ASSERT_EQ(1U, this->op_->StackSize());
268 ASSERT_EQ(0x12U, this->op_->StackAt(0));
269
Christopher Ferris559c7f22018-02-12 20:18:03 -0800270 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700271 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 Ferris559c7f22018-02-12 20:18:03 -0800276 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700277 ASSERT_EQ(0x0a, this->op_->cur_op());
278 ASSERT_EQ(3U, this->op_->StackSize());
279 ASSERT_EQ(0x1245U, this->op_->StackAt(0));
280
Christopher Ferris559c7f22018-02-12 20:18:03 -0800281 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700282 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 Ferris559c7f22018-02-12 20:18:03 -0800287 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700288 ASSERT_EQ(0x0c, this->op_->cur_op());
289 ASSERT_EQ(5U, this->op_->StackSize());
290 ASSERT_EQ(0x45342312U, this->op_->StackAt(0));
291
Christopher Ferris559c7f22018-02-12 20:18:03 -0800292 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700293 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 Ferris559c7f22018-02-12 20:18:03 -0800298 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700299 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 Ferris559c7f22018-02-12 20:18:03 -0800307 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700308 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
317TYPED_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 Ferris559c7f22018-02-12 20:18:03 -0800332 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700333 ASSERT_EQ(0x09, this->op_->cur_op());
334 ASSERT_EQ(1U, this->op_->StackSize());
335 ASSERT_EQ(0x12U, this->op_->StackAt(0));
336
Christopher Ferris559c7f22018-02-12 20:18:03 -0800337 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700338 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 Ferris559c7f22018-02-12 20:18:03 -0800343 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700344 ASSERT_EQ(0x0b, this->op_->cur_op());
345 ASSERT_EQ(3U, this->op_->StackSize());
346 ASSERT_EQ(0x3221U, this->op_->StackAt(0));
347
Christopher Ferris559c7f22018-02-12 20:18:03 -0800348 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700349 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 Ferris559c7f22018-02-12 20:18:03 -0800354 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700355 ASSERT_EQ(0x0d, this->op_->cur_op());
356 ASSERT_EQ(5U, this->op_->StackSize());
357 ASSERT_EQ(0x12233445U, this->op_->StackAt(0));
358
Christopher Ferris559c7f22018-02-12 20:18:03 -0800359 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700360 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 Ferris559c7f22018-02-12 20:18:03 -0800365 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700366 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 Ferris559c7f22018-02-12 20:18:03 -0800374 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700375 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
384TYPED_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 Ferris559c7f22018-02-12 20:18:03 -0800395 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700396 ASSERT_EQ(0x10, this->op_->cur_op());
397 ASSERT_EQ(1U, this->op_->StackSize());
398 ASSERT_EQ(0x22U, this->op_->StackAt(0));
399
Christopher Ferris559c7f22018-02-12 20:18:03 -0800400 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700401 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 Ferris559c7f22018-02-12 20:18:03 -0800406 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700407 ASSERT_EQ(0x10, this->op_->cur_op());
408 ASSERT_EQ(3U, this->op_->StackSize());
409 ASSERT_EQ(0x1122U, this->op_->StackAt(0));
410
Christopher Ferris559c7f22018-02-12 20:18:03 -0800411 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700412 ASSERT_EQ(0x10, this->op_->cur_op());
413 ASSERT_EQ(4U, this->op_->StackSize());
414 ASSERT_EQ(0x3a22U, this->op_->StackAt(0));
415
Christopher Ferris559c7f22018-02-12 20:18:03 -0800416 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700417 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 Ferris559c7f22018-02-12 20:18:03 -0800425 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700426 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
435TYPED_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 Ferris559c7f22018-02-12 20:18:03 -0800461 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700462 ASSERT_EQ(0x11, this->op_->cur_op());
463 ASSERT_EQ(1U, this->op_->StackSize());
464 ASSERT_EQ(0x22U, this->op_->StackAt(0));
465
Christopher Ferris559c7f22018-02-12 20:18:03 -0800466 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700467 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 Ferris559c7f22018-02-12 20:18:03 -0800472 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700473 ASSERT_EQ(0x11, this->op_->cur_op());
474 ASSERT_EQ(3U, this->op_->StackSize());
475 ASSERT_EQ(0x1122U, this->op_->StackAt(0));
476
Christopher Ferris559c7f22018-02-12 20:18:03 -0800477 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700478 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 Ferris559c7f22018-02-12 20:18:03 -0800482 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700483 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 Ferris559c7f22018-02-12 20:18:03 -0800491 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700492 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
501TYPED_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 Ferris559c7f22018-02-12 20:18:03 -0800512 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700513 ASSERT_EQ(0x12, this->op_->cur_op());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800514 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700515
Christopher Ferris559c7f22018-02-12 20:18:03 -0800516 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700517 ASSERT_EQ(1U, this->op_->StackSize());
Christopher Ferris559c7f22018-02-12 20:18:03 -0800518 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700519 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 Ferris559c7f22018-02-12 20:18:03 -0800524 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700525 ASSERT_EQ(3U, this->op_->StackSize());
Christopher Ferris559c7f22018-02-12 20:18:03 -0800526 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700527 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
535TYPED_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 Ferris559c7f22018-02-12 20:18:03 -0800546 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700547 ASSERT_EQ(1U, this->op_->StackSize());
Christopher Ferris559c7f22018-02-12 20:18:03 -0800548 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700549 ASSERT_EQ(2U, this->op_->StackSize());
550
Christopher Ferris559c7f22018-02-12 20:18:03 -0800551 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700552 ASSERT_EQ(0x13, this->op_->cur_op());
553 ASSERT_EQ(1U, this->op_->StackSize());
554 ASSERT_EQ(0x10U, this->op_->StackAt(0));
555
Christopher Ferris559c7f22018-02-12 20:18:03 -0800556 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700557 ASSERT_EQ(0x13, this->op_->cur_op());
558 ASSERT_EQ(0U, this->op_->StackSize());
559
Christopher Ferris559c7f22018-02-12 20:18:03 -0800560 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700561 ASSERT_EQ(0x13, this->op_->cur_op());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800562 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700563}
564
565TYPED_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 Ferris559c7f22018-02-12 20:18:03 -0800578 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700579 ASSERT_EQ(1U, this->op_->StackSize());
Christopher Ferris559c7f22018-02-12 20:18:03 -0800580 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700581 ASSERT_EQ(2U, this->op_->StackSize());
582
Christopher Ferris559c7f22018-02-12 20:18:03 -0800583 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700584 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 Ferris559c7f22018-02-12 20:18:03 -0800590 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700591 ASSERT_EQ(2U, this->op_->StackSize());
Christopher Ferris559c7f22018-02-12 20:18:03 -0800592 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700593 ASSERT_EQ(1U, this->op_->StackSize());
594
Christopher Ferris559c7f22018-02-12 20:18:03 -0800595 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700596 ASSERT_EQ(0x14, this->op_->cur_op());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800597 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700598}
599
600TYPED_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 Ferris559c7f22018-02-12 20:18:03 -0800613 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700614 ASSERT_EQ(1U, this->op_->StackSize());
Christopher Ferris559c7f22018-02-12 20:18:03 -0800615 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700616 ASSERT_EQ(2U, this->op_->StackSize());
Christopher Ferris559c7f22018-02-12 20:18:03 -0800617 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700618 ASSERT_EQ(3U, this->op_->StackSize());
619
Christopher Ferris559c7f22018-02-12 20:18:03 -0800620 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700621 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 Ferris559c7f22018-02-12 20:18:03 -0800628 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700629 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 Ferris559c7f22018-02-12 20:18:03 -0800637 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700638 ASSERT_EQ(0x15, this->op_->cur_op());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800639 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700640}
641
642TYPED_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 Ferris559c7f22018-02-12 20:18:03 -0800653 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700654 ASSERT_EQ(1U, this->op_->StackSize());
Christopher Ferris559c7f22018-02-12 20:18:03 -0800655 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700656 ASSERT_EQ(2U, this->op_->StackSize());
657 ASSERT_EQ(0xabU, this->op_->StackAt(0));
658 ASSERT_EQ(0x26U, this->op_->StackAt(1));
659
Christopher Ferris559c7f22018-02-12 20:18:03 -0800660 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700661 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 Ferris559c7f22018-02-12 20:18:03 -0800666 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700667 ASSERT_EQ(1U, this->op_->StackSize());
668
Christopher Ferris559c7f22018-02-12 20:18:03 -0800669 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700670 ASSERT_EQ(0x16, this->op_->cur_op());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800671 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700672}
673
674TYPED_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 Ferris559c7f22018-02-12 20:18:03 -0800687 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800688 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700689
Christopher Ferris559c7f22018-02-12 20:18:03 -0800690 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700691 ASSERT_EQ(1U, this->op_->StackSize());
692
Christopher Ferris559c7f22018-02-12 20:18:03 -0800693 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800694 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700695
Christopher Ferris559c7f22018-02-12 20:18:03 -0800696 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700697 ASSERT_EQ(2U, this->op_->StackSize());
698
Christopher Ferris559c7f22018-02-12 20:18:03 -0800699 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800700 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700701
Christopher Ferris559c7f22018-02-12 20:18:03 -0800702 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700703 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 Ferris559c7f22018-02-12 20:18:03 -0800708 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700709 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
716TYPED_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 Ferris559c7f22018-02-12 20:18:03 -0800737 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800738 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700739
Christopher Ferris559c7f22018-02-12 20:18:03 -0800740 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700741 ASSERT_EQ(1U, this->op_->StackSize());
742 ASSERT_EQ(0x10U, this->op_->StackAt(0));
743
Christopher Ferris559c7f22018-02-12 20:18:03 -0800744 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700745 ASSERT_EQ(0x19, this->op_->cur_op());
746 ASSERT_EQ(1U, this->op_->StackSize());
747 ASSERT_EQ(0x10U, this->op_->StackAt(0));
748
Christopher Ferris559c7f22018-02-12 20:18:03 -0800749 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700750 ASSERT_EQ(2U, this->op_->StackSize());
751
Christopher Ferris559c7f22018-02-12 20:18:03 -0800752 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700753 ASSERT_EQ(0x19, this->op_->cur_op());
754 ASSERT_EQ(2U, this->op_->StackSize());
755 ASSERT_EQ(0x1U, this->op_->StackAt(0));
756
Christopher Ferris559c7f22018-02-12 20:18:03 -0800757 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700758 ASSERT_EQ(3U, this->op_->StackSize());
759
Christopher Ferris559c7f22018-02-12 20:18:03 -0800760 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700761 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
770TYPED_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 Ferris559c7f22018-02-12 20:18:03 -0800789 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800790 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700791
Christopher Ferris559c7f22018-02-12 20:18:03 -0800792 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700793 ASSERT_EQ(1U, this->op_->StackSize());
794
Christopher Ferris559c7f22018-02-12 20:18:03 -0800795 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800796 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700797
798 // Two positive values.
Christopher Ferris559c7f22018-02-12 20:18:03 -0800799 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700800 ASSERT_EQ(2U, this->op_->StackSize());
801
Christopher Ferris559c7f22018-02-12 20:18:03 -0800802 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700803 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 Ferris559c7f22018-02-12 20:18:03 -0800808 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700809 ASSERT_EQ(2U, this->op_->StackSize());
810
Christopher Ferris559c7f22018-02-12 20:18:03 -0800811 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700812 ASSERT_EQ(3U, this->op_->StackSize());
813
Christopher Ferris559c7f22018-02-12 20:18:03 -0800814 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700815 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 Ferris559c7f22018-02-12 20:18:03 -0800820 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700821 ASSERT_EQ(3U, this->op_->StackSize());
822
Christopher Ferris559c7f22018-02-12 20:18:03 -0800823 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700824 ASSERT_EQ(4U, this->op_->StackSize());
825
Christopher Ferris559c7f22018-02-12 20:18:03 -0800826 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700827 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 Ferris559c7f22018-02-12 20:18:03 -0800832 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700833 ASSERT_EQ(4U, this->op_->StackSize());
834
Christopher Ferris559c7f22018-02-12 20:18:03 -0800835 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700836 ASSERT_EQ(5U, this->op_->StackSize());
837
Christopher Ferris559c7f22018-02-12 20:18:03 -0800838 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800839 ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700840}
841
842TYPED_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 Ferris559c7f22018-02-12 20:18:03 -0800855 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800856 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700857
Christopher Ferris559c7f22018-02-12 20:18:03 -0800858 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700859 ASSERT_EQ(1U, this->op_->StackSize());
860
Christopher Ferris559c7f22018-02-12 20:18:03 -0800861 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800862 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700863
Christopher Ferris559c7f22018-02-12 20:18:03 -0800864 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700865 ASSERT_EQ(2U, this->op_->StackSize());
866
Christopher Ferris559c7f22018-02-12 20:18:03 -0800867 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700868 ASSERT_EQ(0x1a, this->op_->cur_op());
869 ASSERT_EQ(1U, this->op_->StackSize());
870 ASSERT_EQ(0x40U, this->op_->StackAt(0));
871}
872
873TYPED_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 Ferris559c7f22018-02-12 20:18:03 -0800886 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800887 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700888
Christopher Ferris559c7f22018-02-12 20:18:03 -0800889 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700890 ASSERT_EQ(1U, this->op_->StackSize());
891
Christopher Ferris559c7f22018-02-12 20:18:03 -0800892 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800893 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700894
Christopher Ferris559c7f22018-02-12 20:18:03 -0800895 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700896 ASSERT_EQ(2U, this->op_->StackSize());
897
Christopher Ferris559c7f22018-02-12 20:18:03 -0800898 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700899 ASSERT_EQ(0x1c, this->op_->cur_op());
900 ASSERT_EQ(1U, this->op_->StackSize());
901 ASSERT_EQ(0x44U, this->op_->StackAt(0));
902}
903
904TYPED_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 Ferris559c7f22018-02-12 20:18:03 -0800919 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800920 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700921
Christopher Ferris559c7f22018-02-12 20:18:03 -0800922 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700923 ASSERT_EQ(1U, this->op_->StackSize());
924
Christopher Ferris559c7f22018-02-12 20:18:03 -0800925 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800926 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700927
Christopher Ferris559c7f22018-02-12 20:18:03 -0800928 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700929 ASSERT_EQ(2U, this->op_->StackSize());
930
Christopher Ferris559c7f22018-02-12 20:18:03 -0800931 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700932 ASSERT_EQ(0x1d, this->op_->cur_op());
933 ASSERT_EQ(1U, this->op_->StackSize());
934 ASSERT_EQ(0x03U, this->op_->StackAt(0));
935
Christopher Ferris559c7f22018-02-12 20:18:03 -0800936 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700937 ASSERT_EQ(2U, this->op_->StackSize());
Christopher Ferris559c7f22018-02-12 20:18:03 -0800938 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700939 ASSERT_EQ(3U, this->op_->StackSize());
940
Christopher Ferris559c7f22018-02-12 20:18:03 -0800941 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800942 ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700943}
944
945TYPED_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 Ferris559c7f22018-02-12 20:18:03 -0800958 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800959 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700960
Christopher Ferris559c7f22018-02-12 20:18:03 -0800961 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700962 ASSERT_EQ(1U, this->op_->StackSize());
963
Christopher Ferris559c7f22018-02-12 20:18:03 -0800964 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800965 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700966
Christopher Ferris559c7f22018-02-12 20:18:03 -0800967 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700968 ASSERT_EQ(2U, this->op_->StackSize());
969
Christopher Ferris559c7f22018-02-12 20:18:03 -0800970 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700971 ASSERT_EQ(0x1e, this->op_->cur_op());
972 ASSERT_EQ(1U, this->op_->StackSize());
973 ASSERT_EQ(0x120U, this->op_->StackAt(0));
974}
975
976TYPED_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 Ferris559c7f22018-02-12 20:18:03 -0800987 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -0800988 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700989
Christopher Ferris559c7f22018-02-12 20:18:03 -0800990 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700991 ASSERT_EQ(1U, this->op_->StackSize());
992
Christopher Ferris559c7f22018-02-12 20:18:03 -0800993 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700994 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 Ferris559c7f22018-02-12 20:18:03 -0800998 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -0700999 ASSERT_EQ(2U, this->op_->StackSize());
1000
Christopher Ferris559c7f22018-02-12 20:18:03 -08001001 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001002 ASSERT_EQ(0x1f, this->op_->cur_op());
1003 ASSERT_EQ(2U, this->op_->StackSize());
1004 ASSERT_EQ(0x01U, this->op_->StackAt(0));
1005}
1006
1007TYPED_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 Ferris559c7f22018-02-12 20:18:03 -08001018 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -08001019 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001020
Christopher Ferris559c7f22018-02-12 20:18:03 -08001021 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001022 ASSERT_EQ(1U, this->op_->StackSize());
1023
Christopher Ferris559c7f22018-02-12 20:18:03 -08001024 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001025 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 Ferris559c7f22018-02-12 20:18:03 -08001029 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001030 ASSERT_EQ(2U, this->op_->StackSize());
1031
Christopher Ferris559c7f22018-02-12 20:18:03 -08001032 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001033 ASSERT_EQ(0x20, this->op_->cur_op());
1034 ASSERT_EQ(2U, this->op_->StackSize());
1035 ASSERT_EQ(0x03U, this->op_->StackAt(0));
1036}
1037
1038TYPED_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 Ferris559c7f22018-02-12 20:18:03 -08001051 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -08001052 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001053
Christopher Ferris559c7f22018-02-12 20:18:03 -08001054 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001055 ASSERT_EQ(1U, this->op_->StackSize());
1056
Christopher Ferris559c7f22018-02-12 20:18:03 -08001057 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -08001058 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001059
Christopher Ferris559c7f22018-02-12 20:18:03 -08001060 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001061 ASSERT_EQ(2U, this->op_->StackSize());
1062
Christopher Ferris559c7f22018-02-12 20:18:03 -08001063 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001064 ASSERT_EQ(0x21, this->op_->cur_op());
1065 ASSERT_EQ(1U, this->op_->StackSize());
1066 ASSERT_EQ(0xfcU, this->op_->StackAt(0));
1067}
1068
1069TYPED_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 Ferris559c7f22018-02-12 20:18:03 -08001082 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -08001083 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001084
Christopher Ferris559c7f22018-02-12 20:18:03 -08001085 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001086 ASSERT_EQ(1U, this->op_->StackSize());
1087
Christopher Ferris559c7f22018-02-12 20:18:03 -08001088 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -08001089 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001090
Christopher Ferris559c7f22018-02-12 20:18:03 -08001091 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001092 ASSERT_EQ(2U, this->op_->StackSize());
1093
Christopher Ferris559c7f22018-02-12 20:18:03 -08001094 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001095 ASSERT_EQ(0x22, this->op_->cur_op());
1096 ASSERT_EQ(1U, this->op_->StackSize());
1097 ASSERT_EQ(0x1f1U, this->op_->StackAt(0));
1098}
1099
1100TYPED_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 Ferris559c7f22018-02-12 20:18:03 -08001109 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -08001110 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001111
Christopher Ferris559c7f22018-02-12 20:18:03 -08001112 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001113 ASSERT_EQ(1U, this->op_->StackSize());
1114
Christopher Ferris559c7f22018-02-12 20:18:03 -08001115 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001116 ASSERT_EQ(0x23, this->op_->cur_op());
1117 ASSERT_EQ(1U, this->op_->StackSize());
1118 ASSERT_EQ(0x28d0U, this->op_->StackAt(0));
1119}
1120
1121TYPED_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 Ferris559c7f22018-02-12 20:18:03 -08001134 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -08001135 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001136
Christopher Ferris559c7f22018-02-12 20:18:03 -08001137 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001138 ASSERT_EQ(1U, this->op_->StackSize());
1139
Christopher Ferris559c7f22018-02-12 20:18:03 -08001140 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -08001141 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001142
Christopher Ferris559c7f22018-02-12 20:18:03 -08001143 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001144 ASSERT_EQ(2U, this->op_->StackSize());
1145
Christopher Ferris559c7f22018-02-12 20:18:03 -08001146 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001147 ASSERT_EQ(0x24, this->op_->cur_op());
1148 ASSERT_EQ(1U, this->op_->StackSize());
1149 ASSERT_EQ(0x338U, this->op_->StackAt(0));
1150}
1151
1152TYPED_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 Ferris559c7f22018-02-12 20:18:03 -08001165 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -08001166 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001167
Christopher Ferris559c7f22018-02-12 20:18:03 -08001168 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001169 ASSERT_EQ(1U, this->op_->StackSize());
1170
Christopher Ferris559c7f22018-02-12 20:18:03 -08001171 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -08001172 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001173
Christopher Ferris559c7f22018-02-12 20:18:03 -08001174 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001175 ASSERT_EQ(2U, this->op_->StackSize());
1176
Christopher Ferris559c7f22018-02-12 20:18:03 -08001177 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001178 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
1187TYPED_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 Ferris559c7f22018-02-12 20:18:03 -08001200 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -08001201 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001202
Christopher Ferris559c7f22018-02-12 20:18:03 -08001203 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001204 ASSERT_EQ(1U, this->op_->StackSize());
1205
Christopher Ferris559c7f22018-02-12 20:18:03 -08001206 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -08001207 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001208
Christopher Ferris559c7f22018-02-12 20:18:03 -08001209 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001210 ASSERT_EQ(2U, this->op_->StackSize());
1211
Christopher Ferris559c7f22018-02-12 20:18:03 -08001212 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001213 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
1218TYPED_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 Ferris559c7f22018-02-12 20:18:03 -08001231 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -08001232 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001233
Christopher Ferris559c7f22018-02-12 20:18:03 -08001234 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001235 ASSERT_EQ(1U, this->op_->StackSize());
1236
Christopher Ferris559c7f22018-02-12 20:18:03 -08001237 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -08001238 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001239
Christopher Ferris559c7f22018-02-12 20:18:03 -08001240 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001241 ASSERT_EQ(2U, this->op_->StackSize());
1242
Christopher Ferris559c7f22018-02-12 20:18:03 -08001243 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001244 ASSERT_EQ(0x27, this->op_->cur_op());
1245 ASSERT_EQ(1U, this->op_->StackSize());
1246 ASSERT_EQ(0x50U, this->op_->StackAt(0));
1247}
1248
1249TYPED_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 Ferris559c7f22018-02-12 20:18:03 -08001264 ASSERT_FALSE(this->op_->Decode());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -08001265 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001266
1267 // Push on a non-zero value with a positive branch.
Christopher Ferris559c7f22018-02-12 20:18:03 -08001268 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001269 ASSERT_EQ(1U, this->op_->StackSize());
1270
1271 uint64_t offset = this->mem_->cur_offset() + 3;
Christopher Ferris559c7f22018-02-12 20:18:03 -08001272 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001273 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 Ferris559c7f22018-02-12 20:18:03 -08001279 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001280 ASSERT_EQ(1U, this->op_->StackSize());
1281
1282 offset = this->mem_->cur_offset() + 3;
Christopher Ferris559c7f22018-02-12 20:18:03 -08001283 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001284 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 Ferris559c7f22018-02-12 20:18:03 -08001290 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001291 ASSERT_EQ(1U, this->op_->StackSize());
1292
1293 offset = this->mem_->cur_offset() + 3;
Christopher Ferris559c7f22018-02-12 20:18:03 -08001294 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001295 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 Ferris559c7f22018-02-12 20:18:03 -08001301 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001302 ASSERT_EQ(1U, this->op_->StackSize());
1303
1304 offset = this->mem_->cur_offset() + 3;
Christopher Ferris559c7f22018-02-12 20:18:03 -08001305 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001306 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
1311TYPED_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 Ferris559c7f22018-02-12 20:18:03 -08001325 ASSERT_FALSE(this->op_->Eval(0, 1));
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001326 ASSERT_EQ(opcode, this->op_->cur_op());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -08001327 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001328
Christopher Ferris559c7f22018-02-12 20:18:03 -08001329 ASSERT_FALSE(this->op_->Eval(1, 4));
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001330 ASSERT_EQ(opcode, this->op_->cur_op());
1331 ASSERT_EQ(1U, this->op_->StackSize());
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -08001332 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001333 }
1334}
1335
1336TYPED_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 Ferris559c7f22018-02-12 20:18:03 -08001368 ASSERT_TRUE(this->op_->Eval(0, 15))
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001369 << "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
1378TYPED_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 Ferris559c7f22018-02-12 20:18:03 -08001388 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001389 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 Ferris559c7f22018-02-12 20:18:03 -08001395 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001396 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
1401TYPED_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 Ferris559c7f22018-02-12 20:18:03 -08001412 ASSERT_TRUE(this->op_->Eval(i, i + 1)) << "Failed op: 0x" << std::hex << op;
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001413 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
1419TYPED_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 Ferris559c7f22018-02-12 20:18:03 -08001430 ASSERT_TRUE(this->op_->Eval(i, i + 1)) << "Failed op: 0x" << std::hex << op;
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001431 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
1438TYPED_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 Ferris559c7f22018-02-12 20:18:03 -08001444 ASSERT_TRUE(this->op_->Eval(0, 2));
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001445 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 Ferris559c7f22018-02-12 20:18:03 -08001450 ASSERT_TRUE(this->op_->Eval(2, 5));
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001451 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
1457TYPED_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 Cui11e96fe2018-03-14 18:16:22 -07001471 RegsImplFake<TypeParam> regs(32);
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001472 for (size_t i = 0; i < 32; i++) {
1473 regs[i] = i + 10;
1474 }
Christopher Ferris559c7f22018-02-12 20:18:03 -08001475 RegsInfo<TypeParam> regs_info(&regs);
1476 this->op_->set_regs_info(&regs_info);
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001477
1478 uint64_t offset = 0;
1479 for (uint32_t op = 0x70; op <= 0x8f; op++) {
1480 // Positive value added to register.
Christopher Ferris559c7f22018-02-12 20:18:03 -08001481 ASSERT_TRUE(this->op_->Eval(offset, offset + 2)) << "Failed op: 0x" << std::hex << op;
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001482 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 Ferris559c7f22018-02-12 20:18:03 -08001488 ASSERT_TRUE(this->op_->Eval(offset, offset + 2)) << "Failed op: 0x" << std::hex << op;
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001489 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
1496TYPED_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 Cui11e96fe2018-03-14 18:16:22 -07001502 RegsImplFake<TypeParam> regs(16);
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001503 for (size_t i = 0; i < 16; i++) {
1504 regs[i] = i + 10;
1505 }
Christopher Ferris559c7f22018-02-12 20:18:03 -08001506 RegsInfo<TypeParam> regs_info(&regs);
1507 this->op_->set_regs_info(&regs_info);
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001508
1509 // Should pass since this references the last regsister.
Christopher Ferris559c7f22018-02-12 20:18:03 -08001510 ASSERT_TRUE(this->op_->Eval(0, 2));
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001511 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 Ferris559c7f22018-02-12 20:18:03 -08001516 ASSERT_FALSE(this->op_->Eval(2, 4));
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -08001517 ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001518}
1519
1520TYPED_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 Cui11e96fe2018-03-14 18:16:22 -07001529 RegsImplFake<TypeParam> regs(10);
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001530 regs[5] = 0x45;
1531 regs[6] = 0x190;
Christopher Ferris559c7f22018-02-12 20:18:03 -08001532 RegsInfo<TypeParam> regs_info(&regs);
1533 this->op_->set_regs_info(&regs_info);
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001534
Christopher Ferris559c7f22018-02-12 20:18:03 -08001535 ASSERT_TRUE(this->op_->Eval(0, 3));
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001536 ASSERT_EQ(0x92, this->op_->cur_op());
1537 ASSERT_EQ(1U, this->op_->StackSize());
1538 ASSERT_EQ(0x65U, this->op_->StackAt(0));
1539
Christopher Ferris559c7f22018-02-12 20:18:03 -08001540 ASSERT_TRUE(this->op_->Eval(3, 7));
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001541 ASSERT_EQ(0x92, this->op_->cur_op());
1542 ASSERT_EQ(1U, this->op_->StackSize());
1543 ASSERT_EQ(0x90U, this->op_->StackAt(0));
1544
Christopher Ferris559c7f22018-02-12 20:18:03 -08001545 ASSERT_FALSE(this->op_->Eval(7, 12));
Christopher Ferris2fcf4cf2018-01-23 17:52:23 -08001546 ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001547}
1548
1549TYPED_TEST_P(DwarfOpTest, op_nop) {
1550 this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x96});
1551
Christopher Ferris559c7f22018-02-12 20:18:03 -08001552 ASSERT_TRUE(this->op_->Decode());
Christopher Ferris55d22ef2017-04-04 10:41:31 -07001553 ASSERT_EQ(0x96, this->op_->cur_op());
1554 ASSERT_EQ(0U, this->op_->StackSize());
1555}
1556
Christopher Ferris559c7f22018-02-12 20:18:03 -08001557TYPED_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 Ferris7e21eba2019-06-20 16:16:42 -07001574REGISTER_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 Ferris55d22ef2017-04-04 10:41:31 -07001582
1583typedef ::testing::Types<uint32_t, uint64_t> DwarfOpTestTypes;
Christopher Ferris7e21eba2019-06-20 16:16:42 -07001584INSTANTIATE_TYPED_TEST_SUITE_P(, DwarfOpTest, DwarfOpTestTypes);
Christopher Ferrisd226a512017-07-14 10:37:19 -07001585
1586} // namespace unwindstack