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
24 #include <unwindstack/DwarfError.h>
25 #include <unwindstack/DwarfMemory.h>
26 #include <unwindstack/Log.h>
27
28 #include "DwarfOp.h"
29
30 #include "MemoryFake.h"
31 #include "RegsFake.h"
32
33 namespace unwindstack {
34
35 template <typename TypeParam>
36 class DwarfOpTest : public ::testing::Test {
37 protected:
SetUp()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 };
51 TYPED_TEST_SUITE_P(DwarfOpTest);
52
TYPED_TEST_P(DwarfOpTest,decode)53 TYPED_TEST_P(DwarfOpTest, decode) {
54 // Memory error.
55 ASSERT_FALSE(this->op_->Decode());
56 ASSERT_EQ(DWARF_ERROR_MEMORY_INVALID, this->op_->LastErrorCode());
57 EXPECT_EQ(0U, this->op_->LastErrorAddress());
58
59 // No error.
60 this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x96});
61 this->mem_->set_cur_offset(0);
62 ASSERT_TRUE(this->op_->Decode());
63 ASSERT_EQ(DWARF_ERROR_NONE, this->op_->LastErrorCode());
64 ASSERT_EQ(0x96U, this->op_->cur_op());
65 ASSERT_EQ(1U, this->mem_->cur_offset());
66 }
67
TYPED_TEST_P(DwarfOpTest,eval)68 TYPED_TEST_P(DwarfOpTest, eval) {
69 // Memory error.
70 ASSERT_FALSE(this->op_->Eval(0, 2));
71 ASSERT_EQ(DWARF_ERROR_MEMORY_INVALID, this->op_->LastErrorCode());
72 EXPECT_EQ(0U, this->op_->LastErrorAddress());
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});
77 ASSERT_TRUE(this->op_->Eval(0, 1));
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
88 ASSERT_TRUE(this->op_->Eval(0, 8));
89 ASSERT_EQ(DWARF_ERROR_NONE, this->op_->LastErrorCode());
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});
100 ASSERT_FALSE(this->op_->Eval(0, 4));
101 ASSERT_EQ(DWARF_ERROR_TOO_MANY_ITERATIONS, this->op_->LastErrorCode());
102 ASSERT_FALSE(this->op_->is_register());
103 ASSERT_EQ(0U, this->op_->StackSize());
104 }
105
TYPED_TEST_P(DwarfOpTest,illegal_opcode)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++) {
115 ASSERT_FALSE(this->op_->Decode());
116 ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode());
117 ASSERT_EQ(opcode_buffer[i], this->op_->cur_op());
118 }
119 }
120
TYPED_TEST_P(DwarfOpTest,not_implemented)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.
155 ASSERT_TRUE(this->op_->Decode());
156 ASSERT_TRUE(this->op_->Decode());
157 ASSERT_TRUE(this->op_->Decode());
158
159 while (this->mem_->cur_offset() < opcode_buffer.size()) {
160 ASSERT_FALSE(this->op_->Decode());
161 ASSERT_EQ(DWARF_ERROR_NOT_IMPLEMENTED, this->op_->LastErrorCode());
162 }
163 }
164
TYPED_TEST_P(DwarfOpTest,op_addr)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
175 ASSERT_TRUE(this->op_->Decode());
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
TYPED_TEST_P(DwarfOpTest,op_deref)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
198 ASSERT_FALSE(this->op_->Decode());
199 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
200
201 ASSERT_TRUE(this->op_->Decode());
202 ASSERT_EQ(1U, this->op_->StackSize());
203 ASSERT_TRUE(this->op_->Decode());
204 ASSERT_EQ(0x06, this->op_->cur_op());
205 ASSERT_EQ(1U, this->op_->StackSize());
206 ASSERT_EQ(value, this->op_->StackAt(0));
207
208 ASSERT_FALSE(this->op_->Decode());
209 ASSERT_EQ(DWARF_ERROR_MEMORY_INVALID, this->op_->LastErrorCode());
210 ASSERT_EQ(0x12345678U, this->op_->LastErrorAddress());
211 }
212
TYPED_TEST_P(DwarfOpTest,op_deref_size)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
218 ASSERT_FALSE(this->op_->Decode());
219 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
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)});
225 ASSERT_TRUE(this->op_->Eval(0, 5)) << "Failed at size " << i;
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});
235 ASSERT_FALSE(this->op_->Eval(0, 5));
236 ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode());
237
238 // Read too many bytes.
239 this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x0a, 0x10, 0x20, 0x94, sizeof(TypeParam) + 1});
240 ASSERT_FALSE(this->op_->Eval(0, 5));
241 ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode());
242
243 // Force bad memory read.
244 this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x0a, 0x10, 0x40, 0x94, 0x01});
245 ASSERT_FALSE(this->op_->Eval(0, 5));
246 ASSERT_EQ(DWARF_ERROR_MEMORY_INVALID, this->op_->LastErrorCode());
247 EXPECT_EQ(0x4010U, this->op_->LastErrorAddress());
248 }
249
TYPED_TEST_P(DwarfOpTest,const_unsigned)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
265 ASSERT_TRUE(this->op_->Decode());
266 ASSERT_EQ(0x08, this->op_->cur_op());
267 ASSERT_EQ(1U, this->op_->StackSize());
268 ASSERT_EQ(0x12U, this->op_->StackAt(0));
269
270 ASSERT_TRUE(this->op_->Decode());
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
276 ASSERT_TRUE(this->op_->Decode());
277 ASSERT_EQ(0x0a, this->op_->cur_op());
278 ASSERT_EQ(3U, this->op_->StackSize());
279 ASSERT_EQ(0x1245U, this->op_->StackAt(0));
280
281 ASSERT_TRUE(this->op_->Decode());
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
287 ASSERT_TRUE(this->op_->Decode());
288 ASSERT_EQ(0x0c, this->op_->cur_op());
289 ASSERT_EQ(5U, this->op_->StackSize());
290 ASSERT_EQ(0x45342312U, this->op_->StackAt(0));
291
292 ASSERT_TRUE(this->op_->Decode());
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
298 ASSERT_TRUE(this->op_->Decode());
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
307 ASSERT_TRUE(this->op_->Decode());
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
TYPED_TEST_P(DwarfOpTest,const_signed)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
332 ASSERT_TRUE(this->op_->Decode());
333 ASSERT_EQ(0x09, this->op_->cur_op());
334 ASSERT_EQ(1U, this->op_->StackSize());
335 ASSERT_EQ(0x12U, this->op_->StackAt(0));
336
337 ASSERT_TRUE(this->op_->Decode());
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
343 ASSERT_TRUE(this->op_->Decode());
344 ASSERT_EQ(0x0b, this->op_->cur_op());
345 ASSERT_EQ(3U, this->op_->StackSize());
346 ASSERT_EQ(0x3221U, this->op_->StackAt(0));
347
348 ASSERT_TRUE(this->op_->Decode());
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
354 ASSERT_TRUE(this->op_->Decode());
355 ASSERT_EQ(0x0d, this->op_->cur_op());
356 ASSERT_EQ(5U, this->op_->StackSize());
357 ASSERT_EQ(0x12233445U, this->op_->StackAt(0));
358
359 ASSERT_TRUE(this->op_->Decode());
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
365 ASSERT_TRUE(this->op_->Decode());
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
374 ASSERT_TRUE(this->op_->Decode());
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
TYPED_TEST_P(DwarfOpTest,const_uleb)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
395 ASSERT_TRUE(this->op_->Decode());
396 ASSERT_EQ(0x10, this->op_->cur_op());
397 ASSERT_EQ(1U, this->op_->StackSize());
398 ASSERT_EQ(0x22U, this->op_->StackAt(0));
399
400 ASSERT_TRUE(this->op_->Decode());
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
406 ASSERT_TRUE(this->op_->Decode());
407 ASSERT_EQ(0x10, this->op_->cur_op());
408 ASSERT_EQ(3U, this->op_->StackSize());
409 ASSERT_EQ(0x1122U, this->op_->StackAt(0));
410
411 ASSERT_TRUE(this->op_->Decode());
412 ASSERT_EQ(0x10, this->op_->cur_op());
413 ASSERT_EQ(4U, this->op_->StackSize());
414 ASSERT_EQ(0x3a22U, this->op_->StackAt(0));
415
416 ASSERT_TRUE(this->op_->Decode());
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
425 ASSERT_TRUE(this->op_->Decode());
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
TYPED_TEST_P(DwarfOpTest,const_sleb)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
461 ASSERT_TRUE(this->op_->Decode());
462 ASSERT_EQ(0x11, this->op_->cur_op());
463 ASSERT_EQ(1U, this->op_->StackSize());
464 ASSERT_EQ(0x22U, this->op_->StackAt(0));
465
466 ASSERT_TRUE(this->op_->Decode());
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
472 ASSERT_TRUE(this->op_->Decode());
473 ASSERT_EQ(0x11, this->op_->cur_op());
474 ASSERT_EQ(3U, this->op_->StackSize());
475 ASSERT_EQ(0x1122U, this->op_->StackAt(0));
476
477 ASSERT_TRUE(this->op_->Decode());
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
482 ASSERT_TRUE(this->op_->Decode());
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
491 ASSERT_TRUE(this->op_->Decode());
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
TYPED_TEST_P(DwarfOpTest,op_dup)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
512 ASSERT_FALSE(this->op_->Decode());
513 ASSERT_EQ(0x12, this->op_->cur_op());
514 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
515
516 ASSERT_TRUE(this->op_->Decode());
517 ASSERT_EQ(1U, this->op_->StackSize());
518 ASSERT_TRUE(this->op_->Decode());
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
524 ASSERT_TRUE(this->op_->Decode());
525 ASSERT_EQ(3U, this->op_->StackSize());
526 ASSERT_TRUE(this->op_->Decode());
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
TYPED_TEST_P(DwarfOpTest,op_drop)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
546 ASSERT_TRUE(this->op_->Decode());
547 ASSERT_EQ(1U, this->op_->StackSize());
548 ASSERT_TRUE(this->op_->Decode());
549 ASSERT_EQ(2U, this->op_->StackSize());
550
551 ASSERT_TRUE(this->op_->Decode());
552 ASSERT_EQ(0x13, this->op_->cur_op());
553 ASSERT_EQ(1U, this->op_->StackSize());
554 ASSERT_EQ(0x10U, this->op_->StackAt(0));
555
556 ASSERT_TRUE(this->op_->Decode());
557 ASSERT_EQ(0x13, this->op_->cur_op());
558 ASSERT_EQ(0U, this->op_->StackSize());
559
560 ASSERT_FALSE(this->op_->Decode());
561 ASSERT_EQ(0x13, this->op_->cur_op());
562 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
563 }
564
TYPED_TEST_P(DwarfOpTest,op_over)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
578 ASSERT_TRUE(this->op_->Decode());
579 ASSERT_EQ(1U, this->op_->StackSize());
580 ASSERT_TRUE(this->op_->Decode());
581 ASSERT_EQ(2U, this->op_->StackSize());
582
583 ASSERT_TRUE(this->op_->Decode());
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
590 ASSERT_TRUE(this->op_->Decode());
591 ASSERT_EQ(2U, this->op_->StackSize());
592 ASSERT_TRUE(this->op_->Decode());
593 ASSERT_EQ(1U, this->op_->StackSize());
594
595 ASSERT_FALSE(this->op_->Decode());
596 ASSERT_EQ(0x14, this->op_->cur_op());
597 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
598 }
599
TYPED_TEST_P(DwarfOpTest,op_pick)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
613 ASSERT_TRUE(this->op_->Decode());
614 ASSERT_EQ(1U, this->op_->StackSize());
615 ASSERT_TRUE(this->op_->Decode());
616 ASSERT_EQ(2U, this->op_->StackSize());
617 ASSERT_TRUE(this->op_->Decode());
618 ASSERT_EQ(3U, this->op_->StackSize());
619
620 ASSERT_TRUE(this->op_->Decode());
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
628 ASSERT_TRUE(this->op_->Decode());
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
637 ASSERT_FALSE(this->op_->Decode());
638 ASSERT_EQ(0x15, this->op_->cur_op());
639 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
640 }
641
TYPED_TEST_P(DwarfOpTest,op_swap)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
653 ASSERT_TRUE(this->op_->Decode());
654 ASSERT_EQ(1U, this->op_->StackSize());
655 ASSERT_TRUE(this->op_->Decode());
656 ASSERT_EQ(2U, this->op_->StackSize());
657 ASSERT_EQ(0xabU, this->op_->StackAt(0));
658 ASSERT_EQ(0x26U, this->op_->StackAt(1));
659
660 ASSERT_TRUE(this->op_->Decode());
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
666 ASSERT_TRUE(this->op_->Decode());
667 ASSERT_EQ(1U, this->op_->StackSize());
668
669 ASSERT_FALSE(this->op_->Decode());
670 ASSERT_EQ(0x16, this->op_->cur_op());
671 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
672 }
673
TYPED_TEST_P(DwarfOpTest,op_rot)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
687 ASSERT_FALSE(this->op_->Decode());
688 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
689
690 ASSERT_TRUE(this->op_->Decode());
691 ASSERT_EQ(1U, this->op_->StackSize());
692
693 ASSERT_FALSE(this->op_->Decode());
694 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
695
696 ASSERT_TRUE(this->op_->Decode());
697 ASSERT_EQ(2U, this->op_->StackSize());
698
699 ASSERT_FALSE(this->op_->Decode());
700 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
701
702 ASSERT_TRUE(this->op_->Decode());
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
708 ASSERT_TRUE(this->op_->Decode());
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
TYPED_TEST_P(DwarfOpTest,op_abs)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
737 ASSERT_FALSE(this->op_->Decode());
738 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
739
740 ASSERT_TRUE(this->op_->Decode());
741 ASSERT_EQ(1U, this->op_->StackSize());
742 ASSERT_EQ(0x10U, this->op_->StackAt(0));
743
744 ASSERT_TRUE(this->op_->Decode());
745 ASSERT_EQ(0x19, this->op_->cur_op());
746 ASSERT_EQ(1U, this->op_->StackSize());
747 ASSERT_EQ(0x10U, this->op_->StackAt(0));
748
749 ASSERT_TRUE(this->op_->Decode());
750 ASSERT_EQ(2U, this->op_->StackSize());
751
752 ASSERT_TRUE(this->op_->Decode());
753 ASSERT_EQ(0x19, this->op_->cur_op());
754 ASSERT_EQ(2U, this->op_->StackSize());
755 ASSERT_EQ(0x1U, this->op_->StackAt(0));
756
757 ASSERT_TRUE(this->op_->Decode());
758 ASSERT_EQ(3U, this->op_->StackSize());
759
760 ASSERT_TRUE(this->op_->Decode());
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
TYPED_TEST_P(DwarfOpTest,op_and)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
789 ASSERT_FALSE(this->op_->Decode());
790 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
791
792 ASSERT_TRUE(this->op_->Decode());
793 ASSERT_EQ(1U, this->op_->StackSize());
794
795 ASSERT_FALSE(this->op_->Decode());
796 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
797
798 // Two positive values.
799 ASSERT_TRUE(this->op_->Decode());
800 ASSERT_EQ(2U, this->op_->StackSize());
801
802 ASSERT_TRUE(this->op_->Decode());
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.
808 ASSERT_TRUE(this->op_->Decode());
809 ASSERT_EQ(2U, this->op_->StackSize());
810
811 ASSERT_TRUE(this->op_->Decode());
812 ASSERT_EQ(3U, this->op_->StackSize());
813
814 ASSERT_TRUE(this->op_->Decode());
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.
820 ASSERT_TRUE(this->op_->Decode());
821 ASSERT_EQ(3U, this->op_->StackSize());
822
823 ASSERT_TRUE(this->op_->Decode());
824 ASSERT_EQ(4U, this->op_->StackSize());
825
826 ASSERT_TRUE(this->op_->Decode());
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.
832 ASSERT_TRUE(this->op_->Decode());
833 ASSERT_EQ(4U, this->op_->StackSize());
834
835 ASSERT_TRUE(this->op_->Decode());
836 ASSERT_EQ(5U, this->op_->StackSize());
837
838 ASSERT_FALSE(this->op_->Decode());
839 ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode());
840 }
841
TYPED_TEST_P(DwarfOpTest,op_div)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
855 ASSERT_FALSE(this->op_->Decode());
856 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
857
858 ASSERT_TRUE(this->op_->Decode());
859 ASSERT_EQ(1U, this->op_->StackSize());
860
861 ASSERT_FALSE(this->op_->Decode());
862 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
863
864 ASSERT_TRUE(this->op_->Decode());
865 ASSERT_EQ(2U, this->op_->StackSize());
866
867 ASSERT_TRUE(this->op_->Decode());
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
TYPED_TEST_P(DwarfOpTest,op_minus)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
886 ASSERT_FALSE(this->op_->Decode());
887 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
888
889 ASSERT_TRUE(this->op_->Decode());
890 ASSERT_EQ(1U, this->op_->StackSize());
891
892 ASSERT_FALSE(this->op_->Decode());
893 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
894
895 ASSERT_TRUE(this->op_->Decode());
896 ASSERT_EQ(2U, this->op_->StackSize());
897
898 ASSERT_TRUE(this->op_->Decode());
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
TYPED_TEST_P(DwarfOpTest,op_mod)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
919 ASSERT_FALSE(this->op_->Decode());
920 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
921
922 ASSERT_TRUE(this->op_->Decode());
923 ASSERT_EQ(1U, this->op_->StackSize());
924
925 ASSERT_FALSE(this->op_->Decode());
926 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
927
928 ASSERT_TRUE(this->op_->Decode());
929 ASSERT_EQ(2U, this->op_->StackSize());
930
931 ASSERT_TRUE(this->op_->Decode());
932 ASSERT_EQ(0x1d, this->op_->cur_op());
933 ASSERT_EQ(1U, this->op_->StackSize());
934 ASSERT_EQ(0x03U, this->op_->StackAt(0));
935
936 ASSERT_TRUE(this->op_->Decode());
937 ASSERT_EQ(2U, this->op_->StackSize());
938 ASSERT_TRUE(this->op_->Decode());
939 ASSERT_EQ(3U, this->op_->StackSize());
940
941 ASSERT_FALSE(this->op_->Decode());
942 ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode());
943 }
944
TYPED_TEST_P(DwarfOpTest,op_mul)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
958 ASSERT_FALSE(this->op_->Decode());
959 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
960
961 ASSERT_TRUE(this->op_->Decode());
962 ASSERT_EQ(1U, this->op_->StackSize());
963
964 ASSERT_FALSE(this->op_->Decode());
965 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
966
967 ASSERT_TRUE(this->op_->Decode());
968 ASSERT_EQ(2U, this->op_->StackSize());
969
970 ASSERT_TRUE(this->op_->Decode());
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
TYPED_TEST_P(DwarfOpTest,op_neg)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
987 ASSERT_FALSE(this->op_->Decode());
988 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
989
990 ASSERT_TRUE(this->op_->Decode());
991 ASSERT_EQ(1U, this->op_->StackSize());
992
993 ASSERT_TRUE(this->op_->Decode());
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
998 ASSERT_TRUE(this->op_->Decode());
999 ASSERT_EQ(2U, this->op_->StackSize());
1000
1001 ASSERT_TRUE(this->op_->Decode());
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
TYPED_TEST_P(DwarfOpTest,op_not)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
1018 ASSERT_FALSE(this->op_->Decode());
1019 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1020
1021 ASSERT_TRUE(this->op_->Decode());
1022 ASSERT_EQ(1U, this->op_->StackSize());
1023
1024 ASSERT_TRUE(this->op_->Decode());
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
1029 ASSERT_TRUE(this->op_->Decode());
1030 ASSERT_EQ(2U, this->op_->StackSize());
1031
1032 ASSERT_TRUE(this->op_->Decode());
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
TYPED_TEST_P(DwarfOpTest,op_or)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
1051 ASSERT_FALSE(this->op_->Decode());
1052 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1053
1054 ASSERT_TRUE(this->op_->Decode());
1055 ASSERT_EQ(1U, this->op_->StackSize());
1056
1057 ASSERT_FALSE(this->op_->Decode());
1058 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1059
1060 ASSERT_TRUE(this->op_->Decode());
1061 ASSERT_EQ(2U, this->op_->StackSize());
1062
1063 ASSERT_TRUE(this->op_->Decode());
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
TYPED_TEST_P(DwarfOpTest,op_plus)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
1082 ASSERT_FALSE(this->op_->Decode());
1083 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1084
1085 ASSERT_TRUE(this->op_->Decode());
1086 ASSERT_EQ(1U, this->op_->StackSize());
1087
1088 ASSERT_FALSE(this->op_->Decode());
1089 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1090
1091 ASSERT_TRUE(this->op_->Decode());
1092 ASSERT_EQ(2U, this->op_->StackSize());
1093
1094 ASSERT_TRUE(this->op_->Decode());
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
TYPED_TEST_P(DwarfOpTest,op_plus_uconst)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
1109 ASSERT_FALSE(this->op_->Decode());
1110 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1111
1112 ASSERT_TRUE(this->op_->Decode());
1113 ASSERT_EQ(1U, this->op_->StackSize());
1114
1115 ASSERT_TRUE(this->op_->Decode());
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
TYPED_TEST_P(DwarfOpTest,op_shl)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
1134 ASSERT_FALSE(this->op_->Decode());
1135 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1136
1137 ASSERT_TRUE(this->op_->Decode());
1138 ASSERT_EQ(1U, this->op_->StackSize());
1139
1140 ASSERT_FALSE(this->op_->Decode());
1141 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1142
1143 ASSERT_TRUE(this->op_->Decode());
1144 ASSERT_EQ(2U, this->op_->StackSize());
1145
1146 ASSERT_TRUE(this->op_->Decode());
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
TYPED_TEST_P(DwarfOpTest,op_shr)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
1165 ASSERT_FALSE(this->op_->Decode());
1166 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1167
1168 ASSERT_TRUE(this->op_->Decode());
1169 ASSERT_EQ(1U, this->op_->StackSize());
1170
1171 ASSERT_FALSE(this->op_->Decode());
1172 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1173
1174 ASSERT_TRUE(this->op_->Decode());
1175 ASSERT_EQ(2U, this->op_->StackSize());
1176
1177 ASSERT_TRUE(this->op_->Decode());
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
TYPED_TEST_P(DwarfOpTest,op_shra)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
1200 ASSERT_FALSE(this->op_->Decode());
1201 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1202
1203 ASSERT_TRUE(this->op_->Decode());
1204 ASSERT_EQ(1U, this->op_->StackSize());
1205
1206 ASSERT_FALSE(this->op_->Decode());
1207 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1208
1209 ASSERT_TRUE(this->op_->Decode());
1210 ASSERT_EQ(2U, this->op_->StackSize());
1211
1212 ASSERT_TRUE(this->op_->Decode());
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
TYPED_TEST_P(DwarfOpTest,op_xor)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
1231 ASSERT_FALSE(this->op_->Decode());
1232 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1233
1234 ASSERT_TRUE(this->op_->Decode());
1235 ASSERT_EQ(1U, this->op_->StackSize());
1236
1237 ASSERT_FALSE(this->op_->Decode());
1238 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1239
1240 ASSERT_TRUE(this->op_->Decode());
1241 ASSERT_EQ(2U, this->op_->StackSize());
1242
1243 ASSERT_TRUE(this->op_->Decode());
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
TYPED_TEST_P(DwarfOpTest,op_bra)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
1264 ASSERT_FALSE(this->op_->Decode());
1265 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1266
1267 // Push on a non-zero value with a positive branch.
1268 ASSERT_TRUE(this->op_->Decode());
1269 ASSERT_EQ(1U, this->op_->StackSize());
1270
1271 uint64_t offset = this->mem_->cur_offset() + 3;
1272 ASSERT_TRUE(this->op_->Decode());
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);
1279 ASSERT_TRUE(this->op_->Decode());
1280 ASSERT_EQ(1U, this->op_->StackSize());
1281
1282 offset = this->mem_->cur_offset() + 3;
1283 ASSERT_TRUE(this->op_->Decode());
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);
1290 ASSERT_TRUE(this->op_->Decode());
1291 ASSERT_EQ(1U, this->op_->StackSize());
1292
1293 offset = this->mem_->cur_offset() + 3;
1294 ASSERT_TRUE(this->op_->Decode());
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);
1301 ASSERT_TRUE(this->op_->Decode());
1302 ASSERT_EQ(1U, this->op_->StackSize());
1303
1304 offset = this->mem_->cur_offset() + 3;
1305 ASSERT_TRUE(this->op_->Decode());
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
TYPED_TEST_P(DwarfOpTest,compare_opcode_stack_error)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
1325 ASSERT_FALSE(this->op_->Eval(0, 1));
1326 ASSERT_EQ(opcode, this->op_->cur_op());
1327 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1328
1329 ASSERT_FALSE(this->op_->Eval(1, 4));
1330 ASSERT_EQ(opcode, this->op_->cur_op());
1331 ASSERT_EQ(1U, this->op_->StackSize());
1332 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1333 }
1334 }
1335
TYPED_TEST_P(DwarfOpTest,compare_opcodes)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
1368 ASSERT_TRUE(this->op_->Eval(0, 15))
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
TYPED_TEST_P(DwarfOpTest,op_skip)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;
1388 ASSERT_TRUE(this->op_->Decode());
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;
1395 ASSERT_TRUE(this->op_->Decode());
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
TYPED_TEST_P(DwarfOpTest,op_lit)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];
1412 ASSERT_TRUE(this->op_->Eval(i, i + 1)) << "Failed op: 0x" << std::hex << op;
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
TYPED_TEST_P(DwarfOpTest,op_reg)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];
1430 ASSERT_TRUE(this->op_->Eval(i, i + 1)) << "Failed op: 0x" << std::hex << op;
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
TYPED_TEST_P(DwarfOpTest,op_regx)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
1444 ASSERT_TRUE(this->op_->Eval(0, 2));
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
1450 ASSERT_TRUE(this->op_->Eval(2, 5));
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
TYPED_TEST_P(DwarfOpTest,op_breg)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
1471 RegsImplFake<TypeParam> regs(32);
1472 for (size_t i = 0; i < 32; i++) {
1473 regs[i] = i + 10;
1474 }
1475 RegsInfo<TypeParam> regs_info(®s);
1476 this->op_->set_regs_info(®s_info);
1477
1478 uint64_t offset = 0;
1479 for (uint32_t op = 0x70; op <= 0x8f; op++) {
1480 // Positive value added to register.
1481 ASSERT_TRUE(this->op_->Eval(offset, offset + 2)) << "Failed op: 0x" << std::hex << op;
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.
1488 ASSERT_TRUE(this->op_->Eval(offset, offset + 2)) << "Failed op: 0x" << std::hex << op;
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
TYPED_TEST_P(DwarfOpTest,op_breg_invalid_register)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
1502 RegsImplFake<TypeParam> regs(16);
1503 for (size_t i = 0; i < 16; i++) {
1504 regs[i] = i + 10;
1505 }
1506 RegsInfo<TypeParam> regs_info(®s);
1507 this->op_->set_regs_info(®s_info);
1508
1509 // Should pass since this references the last regsister.
1510 ASSERT_TRUE(this->op_->Eval(0, 2));
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.
1516 ASSERT_FALSE(this->op_->Eval(2, 4));
1517 ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode());
1518 }
1519
TYPED_TEST_P(DwarfOpTest,op_bregx)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
1529 RegsImplFake<TypeParam> regs(10);
1530 regs[5] = 0x45;
1531 regs[6] = 0x190;
1532 RegsInfo<TypeParam> regs_info(®s);
1533 this->op_->set_regs_info(®s_info);
1534
1535 ASSERT_TRUE(this->op_->Eval(0, 3));
1536 ASSERT_EQ(0x92, this->op_->cur_op());
1537 ASSERT_EQ(1U, this->op_->StackSize());
1538 ASSERT_EQ(0x65U, this->op_->StackAt(0));
1539
1540 ASSERT_TRUE(this->op_->Eval(3, 7));
1541 ASSERT_EQ(0x92, this->op_->cur_op());
1542 ASSERT_EQ(1U, this->op_->StackSize());
1543 ASSERT_EQ(0x90U, this->op_->StackAt(0));
1544
1545 ASSERT_FALSE(this->op_->Eval(7, 12));
1546 ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode());
1547 }
1548
TYPED_TEST_P(DwarfOpTest,op_nop)1549 TYPED_TEST_P(DwarfOpTest, op_nop) {
1550 this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x96});
1551
1552 ASSERT_TRUE(this->op_->Decode());
1553 ASSERT_EQ(0x96, this->op_->cur_op());
1554 ASSERT_EQ(0U, this->op_->StackSize());
1555 }
1556
TYPED_TEST_P(DwarfOpTest,is_dex_pc)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
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);
1582
1583 typedef ::testing::Types<uint32_t, uint64_t> DwarfOpTestTypes;
1584 INSTANTIATE_TYPED_TEST_SUITE_P(Libunwindstack, DwarfOpTest, DwarfOpTestTypes);
1585
1586 } // namespace unwindstack
1587