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 // Choose a zero index with an empty stack.
603 0x15,
604 0x0,
605 // Push a few values.
606 0x08,
607 0x1a,
608 0x08,
609 0xed,
610 0x08,
611 0x34,
612 // Copy the value at offset 2.
613 0x15,
614 0x01,
615 // Copy the last value in the stack.
616 0x15,
617 0x03,
618 // Choose an invalid index.
619 0x15,
620 0x10,
621 };
622 this->op_memory_.SetMemory(0, opcode_buffer);
623
624 ASSERT_FALSE(this->op_->Decode());
625 ASSERT_EQ(0x15, this->op_->cur_op());
626 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
627
628 ASSERT_TRUE(this->op_->Decode());
629 ASSERT_EQ(1U, this->op_->StackSize());
630 ASSERT_TRUE(this->op_->Decode());
631 ASSERT_EQ(2U, this->op_->StackSize());
632 ASSERT_TRUE(this->op_->Decode());
633 ASSERT_EQ(3U, this->op_->StackSize());
634
635 ASSERT_TRUE(this->op_->Decode());
636 ASSERT_EQ(0x15, this->op_->cur_op());
637 ASSERT_EQ(4U, this->op_->StackSize());
638 ASSERT_EQ(0xedU, this->op_->StackAt(0));
639 ASSERT_EQ(0x34U, this->op_->StackAt(1));
640 ASSERT_EQ(0xedU, this->op_->StackAt(2));
641 ASSERT_EQ(0x1aU, this->op_->StackAt(3));
642
643 ASSERT_TRUE(this->op_->Decode());
644 ASSERT_EQ(0x15, this->op_->cur_op());
645 ASSERT_EQ(5U, this->op_->StackSize());
646 ASSERT_EQ(0x1aU, this->op_->StackAt(0));
647 ASSERT_EQ(0xedU, this->op_->StackAt(1));
648 ASSERT_EQ(0x34U, this->op_->StackAt(2));
649 ASSERT_EQ(0xedU, this->op_->StackAt(3));
650 ASSERT_EQ(0x1aU, this->op_->StackAt(4));
651
652 ASSERT_FALSE(this->op_->Decode());
653 ASSERT_EQ(0x15, this->op_->cur_op());
654 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
655 }
656
TYPED_TEST_P(DwarfOpTest,op_swap)657 TYPED_TEST_P(DwarfOpTest, op_swap) {
658 std::vector<uint8_t> opcode_buffer = {
659 // Push a couple of values.
660 0x08, 0x26, 0x08, 0xab,
661 // Swap values.
662 0x16,
663 // Pop a value to cause a failure.
664 0x13, 0x16,
665 };
666 this->op_memory_.SetMemory(0, opcode_buffer);
667
668 ASSERT_TRUE(this->op_->Decode());
669 ASSERT_EQ(1U, this->op_->StackSize());
670 ASSERT_TRUE(this->op_->Decode());
671 ASSERT_EQ(2U, this->op_->StackSize());
672 ASSERT_EQ(0xabU, this->op_->StackAt(0));
673 ASSERT_EQ(0x26U, this->op_->StackAt(1));
674
675 ASSERT_TRUE(this->op_->Decode());
676 ASSERT_EQ(0x16, this->op_->cur_op());
677 ASSERT_EQ(2U, this->op_->StackSize());
678 ASSERT_EQ(0x26U, this->op_->StackAt(0));
679 ASSERT_EQ(0xabU, this->op_->StackAt(1));
680
681 ASSERT_TRUE(this->op_->Decode());
682 ASSERT_EQ(1U, this->op_->StackSize());
683
684 ASSERT_FALSE(this->op_->Decode());
685 ASSERT_EQ(0x16, this->op_->cur_op());
686 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
687 }
688
TYPED_TEST_P(DwarfOpTest,op_rot)689 TYPED_TEST_P(DwarfOpTest, op_rot) {
690 std::vector<uint8_t> opcode_buffer = {
691 // Rotate that should cause a failure.
692 0x17, 0x08, 0x10,
693 // Only 1 value on stack, should fail.
694 0x17, 0x08, 0x20,
695 // Only 2 values on stack, should fail.
696 0x17, 0x08, 0x30,
697 // Should rotate properly.
698 0x17,
699 };
700 this->op_memory_.SetMemory(0, opcode_buffer);
701
702 ASSERT_FALSE(this->op_->Decode());
703 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
704
705 ASSERT_TRUE(this->op_->Decode());
706 ASSERT_EQ(1U, this->op_->StackSize());
707
708 ASSERT_FALSE(this->op_->Decode());
709 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
710
711 ASSERT_TRUE(this->op_->Decode());
712 ASSERT_EQ(2U, this->op_->StackSize());
713
714 ASSERT_FALSE(this->op_->Decode());
715 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
716
717 ASSERT_TRUE(this->op_->Decode());
718 ASSERT_EQ(3U, this->op_->StackSize());
719 ASSERT_EQ(0x30U, this->op_->StackAt(0));
720 ASSERT_EQ(0x20U, this->op_->StackAt(1));
721 ASSERT_EQ(0x10U, this->op_->StackAt(2));
722
723 ASSERT_TRUE(this->op_->Decode());
724 ASSERT_EQ(0x17, this->op_->cur_op());
725 ASSERT_EQ(3U, this->op_->StackSize());
726 ASSERT_EQ(0x20U, this->op_->StackAt(0));
727 ASSERT_EQ(0x10U, this->op_->StackAt(1));
728 ASSERT_EQ(0x30U, this->op_->StackAt(2));
729 }
730
TYPED_TEST_P(DwarfOpTest,op_abs)731 TYPED_TEST_P(DwarfOpTest, op_abs) {
732 std::vector<uint8_t> opcode_buffer = {
733 // Abs that should fail.
734 0x19,
735 // A value that is already positive.
736 0x08, 0x10, 0x19,
737 // A value that is negative.
738 0x11, 0x7f, 0x19,
739 // A value that is large and negative.
740 0x11, 0x81, 0x80, 0x80, 0x80,
741 };
742 if (sizeof(TypeParam) == 4) {
743 opcode_buffer.push_back(0x08);
744 } else {
745 opcode_buffer.push_back(0x80);
746 opcode_buffer.push_back(0x80);
747 opcode_buffer.push_back(0x01);
748 }
749 opcode_buffer.push_back(0x19);
750 this->op_memory_.SetMemory(0, opcode_buffer);
751
752 ASSERT_FALSE(this->op_->Decode());
753 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
754
755 ASSERT_TRUE(this->op_->Decode());
756 ASSERT_EQ(1U, this->op_->StackSize());
757 ASSERT_EQ(0x10U, this->op_->StackAt(0));
758
759 ASSERT_TRUE(this->op_->Decode());
760 ASSERT_EQ(0x19, this->op_->cur_op());
761 ASSERT_EQ(1U, this->op_->StackSize());
762 ASSERT_EQ(0x10U, this->op_->StackAt(0));
763
764 ASSERT_TRUE(this->op_->Decode());
765 ASSERT_EQ(2U, this->op_->StackSize());
766
767 ASSERT_TRUE(this->op_->Decode());
768 ASSERT_EQ(0x19, this->op_->cur_op());
769 ASSERT_EQ(2U, this->op_->StackSize());
770 ASSERT_EQ(0x1U, this->op_->StackAt(0));
771
772 ASSERT_TRUE(this->op_->Decode());
773 ASSERT_EQ(3U, this->op_->StackSize());
774
775 ASSERT_TRUE(this->op_->Decode());
776 ASSERT_EQ(0x19, this->op_->cur_op());
777 ASSERT_EQ(3U, this->op_->StackSize());
778 if (sizeof(TypeParam) == 4) {
779 ASSERT_EQ(2147483647U, this->op_->StackAt(0));
780 } else {
781 ASSERT_EQ(4398046511105UL, this->op_->StackAt(0));
782 }
783 }
784
TYPED_TEST_P(DwarfOpTest,op_and)785 TYPED_TEST_P(DwarfOpTest, op_and) {
786 std::vector<uint8_t> opcode_buffer = {
787 // No stack, and op will fail.
788 0x1b,
789 // Push a single value.
790 0x08, 0x20,
791 // One element stack, and op will fail.
792 0x1b,
793 // Push another value.
794 0x08, 0x02, 0x1b,
795 // Push on two negative values.
796 0x11, 0x7c, 0x11, 0x7f, 0x1b,
797 // Push one negative, one positive.
798 0x11, 0x10, 0x11, 0x7c, 0x1b,
799 // Divide by zero.
800 0x11, 0x10, 0x11, 0x00, 0x1b,
801 };
802 this->op_memory_.SetMemory(0, opcode_buffer);
803
804 ASSERT_FALSE(this->op_->Decode());
805 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
806
807 ASSERT_TRUE(this->op_->Decode());
808 ASSERT_EQ(1U, this->op_->StackSize());
809
810 ASSERT_FALSE(this->op_->Decode());
811 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
812
813 // Two positive values.
814 ASSERT_TRUE(this->op_->Decode());
815 ASSERT_EQ(2U, this->op_->StackSize());
816
817 ASSERT_TRUE(this->op_->Decode());
818 ASSERT_EQ(0x1b, this->op_->cur_op());
819 ASSERT_EQ(1U, this->op_->StackSize());
820 ASSERT_EQ(0x10U, this->op_->StackAt(0));
821
822 // Two negative values.
823 ASSERT_TRUE(this->op_->Decode());
824 ASSERT_EQ(2U, this->op_->StackSize());
825
826 ASSERT_TRUE(this->op_->Decode());
827 ASSERT_EQ(3U, this->op_->StackSize());
828
829 ASSERT_TRUE(this->op_->Decode());
830 ASSERT_EQ(0x1b, this->op_->cur_op());
831 ASSERT_EQ(2U, this->op_->StackSize());
832 ASSERT_EQ(0x04U, this->op_->StackAt(0));
833
834 // One negative value, one positive value.
835 ASSERT_TRUE(this->op_->Decode());
836 ASSERT_EQ(3U, this->op_->StackSize());
837
838 ASSERT_TRUE(this->op_->Decode());
839 ASSERT_EQ(4U, this->op_->StackSize());
840
841 ASSERT_TRUE(this->op_->Decode());
842 ASSERT_EQ(0x1b, this->op_->cur_op());
843 ASSERT_EQ(3U, this->op_->StackSize());
844 ASSERT_EQ(static_cast<TypeParam>(-4), this->op_->StackAt(0));
845
846 // Divide by zero.
847 ASSERT_TRUE(this->op_->Decode());
848 ASSERT_EQ(4U, this->op_->StackSize());
849
850 ASSERT_TRUE(this->op_->Decode());
851 ASSERT_EQ(5U, this->op_->StackSize());
852
853 ASSERT_FALSE(this->op_->Decode());
854 ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode());
855 }
856
TYPED_TEST_P(DwarfOpTest,op_div)857 TYPED_TEST_P(DwarfOpTest, op_div) {
858 std::vector<uint8_t> opcode_buffer = {
859 // No stack, and op will fail.
860 0x1a,
861 // Push a single value.
862 0x08, 0x48,
863 // One element stack, and op will fail.
864 0x1a,
865 // Push another value.
866 0x08, 0xf0, 0x1a,
867 };
868 this->op_memory_.SetMemory(0, opcode_buffer);
869
870 ASSERT_FALSE(this->op_->Decode());
871 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
872
873 ASSERT_TRUE(this->op_->Decode());
874 ASSERT_EQ(1U, this->op_->StackSize());
875
876 ASSERT_FALSE(this->op_->Decode());
877 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
878
879 ASSERT_TRUE(this->op_->Decode());
880 ASSERT_EQ(2U, this->op_->StackSize());
881
882 ASSERT_TRUE(this->op_->Decode());
883 ASSERT_EQ(0x1a, this->op_->cur_op());
884 ASSERT_EQ(1U, this->op_->StackSize());
885 ASSERT_EQ(0x40U, this->op_->StackAt(0));
886 }
887
TYPED_TEST_P(DwarfOpTest,op_minus)888 TYPED_TEST_P(DwarfOpTest, op_minus) {
889 std::vector<uint8_t> opcode_buffer = {
890 // No stack, and op will fail.
891 0x1c,
892 // Push a single value.
893 0x08, 0x48,
894 // One element stack, and op will fail.
895 0x1c,
896 // Push another value.
897 0x08, 0x04, 0x1c,
898 };
899 this->op_memory_.SetMemory(0, opcode_buffer);
900
901 ASSERT_FALSE(this->op_->Decode());
902 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
903
904 ASSERT_TRUE(this->op_->Decode());
905 ASSERT_EQ(1U, this->op_->StackSize());
906
907 ASSERT_FALSE(this->op_->Decode());
908 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
909
910 ASSERT_TRUE(this->op_->Decode());
911 ASSERT_EQ(2U, this->op_->StackSize());
912
913 ASSERT_TRUE(this->op_->Decode());
914 ASSERT_EQ(0x1c, this->op_->cur_op());
915 ASSERT_EQ(1U, this->op_->StackSize());
916 ASSERT_EQ(0x44U, this->op_->StackAt(0));
917 }
918
TYPED_TEST_P(DwarfOpTest,op_mod)919 TYPED_TEST_P(DwarfOpTest, op_mod) {
920 std::vector<uint8_t> opcode_buffer = {
921 // No stack, and op will fail.
922 0x1d,
923 // Push a single value.
924 0x08, 0x47,
925 // One element stack, and op will fail.
926 0x1d,
927 // Push another value.
928 0x08, 0x04, 0x1d,
929 // Try a mod of zero.
930 0x08, 0x01, 0x08, 0x00, 0x1d,
931 };
932 this->op_memory_.SetMemory(0, opcode_buffer);
933
934 ASSERT_FALSE(this->op_->Decode());
935 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
936
937 ASSERT_TRUE(this->op_->Decode());
938 ASSERT_EQ(1U, this->op_->StackSize());
939
940 ASSERT_FALSE(this->op_->Decode());
941 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
942
943 ASSERT_TRUE(this->op_->Decode());
944 ASSERT_EQ(2U, this->op_->StackSize());
945
946 ASSERT_TRUE(this->op_->Decode());
947 ASSERT_EQ(0x1d, this->op_->cur_op());
948 ASSERT_EQ(1U, this->op_->StackSize());
949 ASSERT_EQ(0x03U, this->op_->StackAt(0));
950
951 ASSERT_TRUE(this->op_->Decode());
952 ASSERT_EQ(2U, this->op_->StackSize());
953 ASSERT_TRUE(this->op_->Decode());
954 ASSERT_EQ(3U, this->op_->StackSize());
955
956 ASSERT_FALSE(this->op_->Decode());
957 ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode());
958 }
959
TYPED_TEST_P(DwarfOpTest,op_mul)960 TYPED_TEST_P(DwarfOpTest, op_mul) {
961 std::vector<uint8_t> opcode_buffer = {
962 // No stack, and op will fail.
963 0x1e,
964 // Push a single value.
965 0x08, 0x48,
966 // One element stack, and op will fail.
967 0x1e,
968 // Push another value.
969 0x08, 0x04, 0x1e,
970 };
971 this->op_memory_.SetMemory(0, opcode_buffer);
972
973 ASSERT_FALSE(this->op_->Decode());
974 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
975
976 ASSERT_TRUE(this->op_->Decode());
977 ASSERT_EQ(1U, this->op_->StackSize());
978
979 ASSERT_FALSE(this->op_->Decode());
980 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
981
982 ASSERT_TRUE(this->op_->Decode());
983 ASSERT_EQ(2U, this->op_->StackSize());
984
985 ASSERT_TRUE(this->op_->Decode());
986 ASSERT_EQ(0x1e, this->op_->cur_op());
987 ASSERT_EQ(1U, this->op_->StackSize());
988 ASSERT_EQ(0x120U, this->op_->StackAt(0));
989 }
990
TYPED_TEST_P(DwarfOpTest,op_neg)991 TYPED_TEST_P(DwarfOpTest, op_neg) {
992 std::vector<uint8_t> opcode_buffer = {
993 // No stack, and op will fail.
994 0x1f,
995 // Push a single value.
996 0x08, 0x48, 0x1f,
997 // Push a negative value.
998 0x11, 0x7f, 0x1f,
999 };
1000 this->op_memory_.SetMemory(0, opcode_buffer);
1001
1002 ASSERT_FALSE(this->op_->Decode());
1003 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1004
1005 ASSERT_TRUE(this->op_->Decode());
1006 ASSERT_EQ(1U, this->op_->StackSize());
1007
1008 ASSERT_TRUE(this->op_->Decode());
1009 ASSERT_EQ(0x1f, this->op_->cur_op());
1010 ASSERT_EQ(1U, this->op_->StackSize());
1011 ASSERT_EQ(static_cast<TypeParam>(-72), this->op_->StackAt(0));
1012
1013 ASSERT_TRUE(this->op_->Decode());
1014 ASSERT_EQ(2U, this->op_->StackSize());
1015
1016 ASSERT_TRUE(this->op_->Decode());
1017 ASSERT_EQ(0x1f, this->op_->cur_op());
1018 ASSERT_EQ(2U, this->op_->StackSize());
1019 ASSERT_EQ(0x01U, this->op_->StackAt(0));
1020 }
1021
TYPED_TEST_P(DwarfOpTest,op_not)1022 TYPED_TEST_P(DwarfOpTest, op_not) {
1023 std::vector<uint8_t> opcode_buffer = {
1024 // No stack, and op will fail.
1025 0x20,
1026 // Push a single value.
1027 0x08, 0x4, 0x20,
1028 // Push a negative value.
1029 0x11, 0x7c, 0x20,
1030 };
1031 this->op_memory_.SetMemory(0, opcode_buffer);
1032
1033 ASSERT_FALSE(this->op_->Decode());
1034 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1035
1036 ASSERT_TRUE(this->op_->Decode());
1037 ASSERT_EQ(1U, this->op_->StackSize());
1038
1039 ASSERT_TRUE(this->op_->Decode());
1040 ASSERT_EQ(0x20, this->op_->cur_op());
1041 ASSERT_EQ(1U, this->op_->StackSize());
1042 ASSERT_EQ(static_cast<TypeParam>(-5), this->op_->StackAt(0));
1043
1044 ASSERT_TRUE(this->op_->Decode());
1045 ASSERT_EQ(2U, this->op_->StackSize());
1046
1047 ASSERT_TRUE(this->op_->Decode());
1048 ASSERT_EQ(0x20, this->op_->cur_op());
1049 ASSERT_EQ(2U, this->op_->StackSize());
1050 ASSERT_EQ(0x03U, this->op_->StackAt(0));
1051 }
1052
TYPED_TEST_P(DwarfOpTest,op_or)1053 TYPED_TEST_P(DwarfOpTest, op_or) {
1054 std::vector<uint8_t> opcode_buffer = {
1055 // No stack, and op will fail.
1056 0x21,
1057 // Push a single value.
1058 0x08, 0x48,
1059 // One element stack, and op will fail.
1060 0x21,
1061 // Push another value.
1062 0x08, 0xf4, 0x21,
1063 };
1064 this->op_memory_.SetMemory(0, opcode_buffer);
1065
1066 ASSERT_FALSE(this->op_->Decode());
1067 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1068
1069 ASSERT_TRUE(this->op_->Decode());
1070 ASSERT_EQ(1U, this->op_->StackSize());
1071
1072 ASSERT_FALSE(this->op_->Decode());
1073 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1074
1075 ASSERT_TRUE(this->op_->Decode());
1076 ASSERT_EQ(2U, this->op_->StackSize());
1077
1078 ASSERT_TRUE(this->op_->Decode());
1079 ASSERT_EQ(0x21, this->op_->cur_op());
1080 ASSERT_EQ(1U, this->op_->StackSize());
1081 ASSERT_EQ(0xfcU, this->op_->StackAt(0));
1082 }
1083
TYPED_TEST_P(DwarfOpTest,op_plus)1084 TYPED_TEST_P(DwarfOpTest, op_plus) {
1085 std::vector<uint8_t> opcode_buffer = {
1086 // No stack, and op will fail.
1087 0x22,
1088 // Push a single value.
1089 0x08, 0xff,
1090 // One element stack, and op will fail.
1091 0x22,
1092 // Push another value.
1093 0x08, 0xf2, 0x22,
1094 };
1095 this->op_memory_.SetMemory(0, opcode_buffer);
1096
1097 ASSERT_FALSE(this->op_->Decode());
1098 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1099
1100 ASSERT_TRUE(this->op_->Decode());
1101 ASSERT_EQ(1U, this->op_->StackSize());
1102
1103 ASSERT_FALSE(this->op_->Decode());
1104 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1105
1106 ASSERT_TRUE(this->op_->Decode());
1107 ASSERT_EQ(2U, this->op_->StackSize());
1108
1109 ASSERT_TRUE(this->op_->Decode());
1110 ASSERT_EQ(0x22, this->op_->cur_op());
1111 ASSERT_EQ(1U, this->op_->StackSize());
1112 ASSERT_EQ(0x1f1U, this->op_->StackAt(0));
1113 }
1114
TYPED_TEST_P(DwarfOpTest,op_plus_uconst)1115 TYPED_TEST_P(DwarfOpTest, op_plus_uconst) {
1116 std::vector<uint8_t> opcode_buffer = {
1117 // No stack, and op will fail.
1118 0x23,
1119 // Push a single value.
1120 0x08, 0x50, 0x23, 0x80, 0x51,
1121 };
1122 this->op_memory_.SetMemory(0, opcode_buffer);
1123
1124 ASSERT_FALSE(this->op_->Decode());
1125 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1126
1127 ASSERT_TRUE(this->op_->Decode());
1128 ASSERT_EQ(1U, this->op_->StackSize());
1129
1130 ASSERT_TRUE(this->op_->Decode());
1131 ASSERT_EQ(0x23, this->op_->cur_op());
1132 ASSERT_EQ(1U, this->op_->StackSize());
1133 ASSERT_EQ(0x28d0U, this->op_->StackAt(0));
1134 }
1135
TYPED_TEST_P(DwarfOpTest,op_shl)1136 TYPED_TEST_P(DwarfOpTest, op_shl) {
1137 std::vector<uint8_t> opcode_buffer = {
1138 // No stack, and op will fail.
1139 0x24,
1140 // Push a single value.
1141 0x08, 0x67,
1142 // One element stack, and op will fail.
1143 0x24,
1144 // Push another value.
1145 0x08, 0x03, 0x24,
1146 };
1147 this->op_memory_.SetMemory(0, opcode_buffer);
1148
1149 ASSERT_FALSE(this->op_->Decode());
1150 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1151
1152 ASSERT_TRUE(this->op_->Decode());
1153 ASSERT_EQ(1U, this->op_->StackSize());
1154
1155 ASSERT_FALSE(this->op_->Decode());
1156 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1157
1158 ASSERT_TRUE(this->op_->Decode());
1159 ASSERT_EQ(2U, this->op_->StackSize());
1160
1161 ASSERT_TRUE(this->op_->Decode());
1162 ASSERT_EQ(0x24, this->op_->cur_op());
1163 ASSERT_EQ(1U, this->op_->StackSize());
1164 ASSERT_EQ(0x338U, this->op_->StackAt(0));
1165 }
1166
TYPED_TEST_P(DwarfOpTest,op_shr)1167 TYPED_TEST_P(DwarfOpTest, op_shr) {
1168 std::vector<uint8_t> opcode_buffer = {
1169 // No stack, and op will fail.
1170 0x25,
1171 // Push a single value.
1172 0x11, 0x70,
1173 // One element stack, and op will fail.
1174 0x25,
1175 // Push another value.
1176 0x08, 0x03, 0x25,
1177 };
1178 this->op_memory_.SetMemory(0, opcode_buffer);
1179
1180 ASSERT_FALSE(this->op_->Decode());
1181 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1182
1183 ASSERT_TRUE(this->op_->Decode());
1184 ASSERT_EQ(1U, this->op_->StackSize());
1185
1186 ASSERT_FALSE(this->op_->Decode());
1187 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1188
1189 ASSERT_TRUE(this->op_->Decode());
1190 ASSERT_EQ(2U, this->op_->StackSize());
1191
1192 ASSERT_TRUE(this->op_->Decode());
1193 ASSERT_EQ(0x25, this->op_->cur_op());
1194 ASSERT_EQ(1U, this->op_->StackSize());
1195 if (sizeof(TypeParam) == 4) {
1196 ASSERT_EQ(0x1ffffffeU, this->op_->StackAt(0));
1197 } else {
1198 ASSERT_EQ(0x1ffffffffffffffeULL, this->op_->StackAt(0));
1199 }
1200 }
1201
TYPED_TEST_P(DwarfOpTest,op_shra)1202 TYPED_TEST_P(DwarfOpTest, op_shra) {
1203 std::vector<uint8_t> opcode_buffer = {
1204 // No stack, and op will fail.
1205 0x26,
1206 // Push a single value.
1207 0x11, 0x70,
1208 // One element stack, and op will fail.
1209 0x26,
1210 // Push another value.
1211 0x08, 0x03, 0x26,
1212 };
1213 this->op_memory_.SetMemory(0, opcode_buffer);
1214
1215 ASSERT_FALSE(this->op_->Decode());
1216 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1217
1218 ASSERT_TRUE(this->op_->Decode());
1219 ASSERT_EQ(1U, this->op_->StackSize());
1220
1221 ASSERT_FALSE(this->op_->Decode());
1222 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1223
1224 ASSERT_TRUE(this->op_->Decode());
1225 ASSERT_EQ(2U, this->op_->StackSize());
1226
1227 ASSERT_TRUE(this->op_->Decode());
1228 ASSERT_EQ(0x26, this->op_->cur_op());
1229 ASSERT_EQ(1U, this->op_->StackSize());
1230 ASSERT_EQ(static_cast<TypeParam>(-2), this->op_->StackAt(0));
1231 }
1232
TYPED_TEST_P(DwarfOpTest,op_xor)1233 TYPED_TEST_P(DwarfOpTest, op_xor) {
1234 std::vector<uint8_t> opcode_buffer = {
1235 // No stack, and op will fail.
1236 0x27,
1237 // Push a single value.
1238 0x08, 0x11,
1239 // One element stack, and op will fail.
1240 0x27,
1241 // Push another value.
1242 0x08, 0x41, 0x27,
1243 };
1244 this->op_memory_.SetMemory(0, opcode_buffer);
1245
1246 ASSERT_FALSE(this->op_->Decode());
1247 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1248
1249 ASSERT_TRUE(this->op_->Decode());
1250 ASSERT_EQ(1U, this->op_->StackSize());
1251
1252 ASSERT_FALSE(this->op_->Decode());
1253 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1254
1255 ASSERT_TRUE(this->op_->Decode());
1256 ASSERT_EQ(2U, this->op_->StackSize());
1257
1258 ASSERT_TRUE(this->op_->Decode());
1259 ASSERT_EQ(0x27, this->op_->cur_op());
1260 ASSERT_EQ(1U, this->op_->StackSize());
1261 ASSERT_EQ(0x50U, this->op_->StackAt(0));
1262 }
1263
TYPED_TEST_P(DwarfOpTest,op_bra)1264 TYPED_TEST_P(DwarfOpTest, op_bra) {
1265 std::vector<uint8_t> opcode_buffer = {
1266 // No stack, and op will fail.
1267 0x28,
1268 // Push on a non-zero value with a positive branch.
1269 0x08, 0x11, 0x28, 0x02, 0x01,
1270 // Push on a zero value with a positive branch.
1271 0x08, 0x00, 0x28, 0x05, 0x00,
1272 // Push on a non-zero value with a negative branch.
1273 0x08, 0x11, 0x28, 0xfc, 0xff,
1274 // Push on a zero value with a negative branch.
1275 0x08, 0x00, 0x28, 0xf0, 0xff,
1276 };
1277 this->op_memory_.SetMemory(0, opcode_buffer);
1278
1279 ASSERT_FALSE(this->op_->Decode());
1280 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1281
1282 // Push on a non-zero value with a positive branch.
1283 ASSERT_TRUE(this->op_->Decode());
1284 ASSERT_EQ(1U, this->op_->StackSize());
1285
1286 uint64_t offset = this->mem_->cur_offset() + 3;
1287 ASSERT_TRUE(this->op_->Decode());
1288 ASSERT_EQ(0x28, this->op_->cur_op());
1289 ASSERT_EQ(0U, this->op_->StackSize());
1290 ASSERT_EQ(offset + 0x102, this->mem_->cur_offset());
1291
1292 // Push on a zero value with a positive branch.
1293 this->mem_->set_cur_offset(offset);
1294 ASSERT_TRUE(this->op_->Decode());
1295 ASSERT_EQ(1U, this->op_->StackSize());
1296
1297 offset = this->mem_->cur_offset() + 3;
1298 ASSERT_TRUE(this->op_->Decode());
1299 ASSERT_EQ(0x28, this->op_->cur_op());
1300 ASSERT_EQ(0U, this->op_->StackSize());
1301 ASSERT_EQ(offset - 5, this->mem_->cur_offset());
1302
1303 // Push on a non-zero value with a negative branch.
1304 this->mem_->set_cur_offset(offset);
1305 ASSERT_TRUE(this->op_->Decode());
1306 ASSERT_EQ(1U, this->op_->StackSize());
1307
1308 offset = this->mem_->cur_offset() + 3;
1309 ASSERT_TRUE(this->op_->Decode());
1310 ASSERT_EQ(0x28, this->op_->cur_op());
1311 ASSERT_EQ(0U, this->op_->StackSize());
1312 ASSERT_EQ(offset - 4, this->mem_->cur_offset());
1313
1314 // Push on a zero value with a negative branch.
1315 this->mem_->set_cur_offset(offset);
1316 ASSERT_TRUE(this->op_->Decode());
1317 ASSERT_EQ(1U, this->op_->StackSize());
1318
1319 offset = this->mem_->cur_offset() + 3;
1320 ASSERT_TRUE(this->op_->Decode());
1321 ASSERT_EQ(0x28, this->op_->cur_op());
1322 ASSERT_EQ(0U, this->op_->StackSize());
1323 ASSERT_EQ(offset + 16, this->mem_->cur_offset());
1324 }
1325
TYPED_TEST_P(DwarfOpTest,compare_opcode_stack_error)1326 TYPED_TEST_P(DwarfOpTest, compare_opcode_stack_error) {
1327 // All of the ops require two stack elements. Loop through all of these
1328 // ops with potential errors.
1329 std::vector<uint8_t> opcode_buffer = {
1330 0xff, // Place holder for compare op.
1331 0x08, 0x11,
1332 0xff, // Place holder for compare op.
1333 };
1334
1335 for (uint8_t opcode = 0x29; opcode <= 0x2e; opcode++) {
1336 opcode_buffer[0] = opcode;
1337 opcode_buffer[3] = opcode;
1338 this->op_memory_.SetMemory(0, opcode_buffer);
1339
1340 ASSERT_FALSE(this->op_->Eval(0, 1));
1341 ASSERT_EQ(opcode, this->op_->cur_op());
1342 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1343
1344 ASSERT_FALSE(this->op_->Eval(1, 4));
1345 ASSERT_EQ(opcode, this->op_->cur_op());
1346 ASSERT_EQ(1U, this->op_->StackSize());
1347 ASSERT_EQ(DWARF_ERROR_STACK_INDEX_NOT_VALID, this->op_->LastErrorCode());
1348 }
1349 }
1350
TYPED_TEST_P(DwarfOpTest,compare_opcodes)1351 TYPED_TEST_P(DwarfOpTest, compare_opcodes) {
1352 // Have three different checks for each compare op:
1353 // - Both values the same.
1354 // - The first value larger than the second.
1355 // - The second value larger than the first.
1356 std::vector<uint8_t> opcode_buffer = {
1357 // Values the same.
1358 0x08, 0x11, 0x08, 0x11,
1359 0xff, // Placeholder.
1360 // First value larger.
1361 0x08, 0x12, 0x08, 0x10,
1362 0xff, // Placeholder.
1363 // Second value larger.
1364 0x08, 0x10, 0x08, 0x12,
1365 0xff, // Placeholder.
1366 };
1367
1368 // Opcode followed by the expected values on the stack.
1369 std::vector<uint8_t> expected = {
1370 0x29, 1, 0, 0, // eq
1371 0x2a, 1, 1, 0, // ge
1372 0x2b, 0, 1, 0, // gt
1373 0x2c, 1, 0, 1, // le
1374 0x2d, 0, 0, 1, // lt
1375 0x2e, 0, 1, 1, // ne
1376 };
1377 for (size_t i = 0; i < expected.size(); i += 4) {
1378 opcode_buffer[4] = expected[i];
1379 opcode_buffer[9] = expected[i];
1380 opcode_buffer[14] = expected[i];
1381 this->op_memory_.SetMemory(0, opcode_buffer);
1382
1383 ASSERT_TRUE(this->op_->Eval(0, 15))
1384 << "Op: 0x" << std::hex << static_cast<uint32_t>(expected[i]) << " failed";
1385
1386 ASSERT_EQ(3U, this->op_->StackSize());
1387 ASSERT_EQ(expected[i + 1], this->op_->StackAt(2));
1388 ASSERT_EQ(expected[i + 2], this->op_->StackAt(1));
1389 ASSERT_EQ(expected[i + 3], this->op_->StackAt(0));
1390 }
1391 }
1392
TYPED_TEST_P(DwarfOpTest,op_skip)1393 TYPED_TEST_P(DwarfOpTest, op_skip) {
1394 std::vector<uint8_t> opcode_buffer = {
1395 // Positive value.
1396 0x2f, 0x10, 0x20,
1397 // Negative value.
1398 0x2f, 0xfd, 0xff,
1399 };
1400 this->op_memory_.SetMemory(0, opcode_buffer);
1401
1402 uint64_t offset = this->mem_->cur_offset() + 3;
1403 ASSERT_TRUE(this->op_->Decode());
1404 ASSERT_EQ(0x2f, this->op_->cur_op());
1405 ASSERT_EQ(0U, this->op_->StackSize());
1406 ASSERT_EQ(offset + 0x2010, this->mem_->cur_offset());
1407
1408 this->mem_->set_cur_offset(offset);
1409 offset = this->mem_->cur_offset() + 3;
1410 ASSERT_TRUE(this->op_->Decode());
1411 ASSERT_EQ(0x2f, this->op_->cur_op());
1412 ASSERT_EQ(0U, this->op_->StackSize());
1413 ASSERT_EQ(offset - 3, this->mem_->cur_offset());
1414 }
1415
TYPED_TEST_P(DwarfOpTest,op_lit)1416 TYPED_TEST_P(DwarfOpTest, op_lit) {
1417 std::vector<uint8_t> opcode_buffer;
1418
1419 // Verify every lit opcode.
1420 for (uint8_t op = 0x30; op <= 0x4f; op++) {
1421 opcode_buffer.push_back(op);
1422 }
1423 this->op_memory_.SetMemory(0, opcode_buffer);
1424
1425 for (size_t i = 0; i < opcode_buffer.size(); i++) {
1426 uint32_t op = opcode_buffer[i];
1427 ASSERT_TRUE(this->op_->Eval(i, i + 1)) << "Failed op: 0x" << std::hex << op;
1428 ASSERT_EQ(op, this->op_->cur_op());
1429 ASSERT_EQ(1U, this->op_->StackSize()) << "Failed op: 0x" << std::hex << op;
1430 ASSERT_EQ(op - 0x30U, this->op_->StackAt(0)) << "Failed op: 0x" << std::hex << op;
1431 }
1432 }
1433
TYPED_TEST_P(DwarfOpTest,op_reg)1434 TYPED_TEST_P(DwarfOpTest, op_reg) {
1435 std::vector<uint8_t> opcode_buffer;
1436
1437 // Verify every reg opcode.
1438 for (uint8_t op = 0x50; op <= 0x6f; op++) {
1439 opcode_buffer.push_back(op);
1440 }
1441 this->op_memory_.SetMemory(0, opcode_buffer);
1442
1443 for (size_t i = 0; i < opcode_buffer.size(); i++) {
1444 uint32_t op = opcode_buffer[i];
1445 ASSERT_TRUE(this->op_->Eval(i, i + 1)) << "Failed op: 0x" << std::hex << op;
1446 ASSERT_EQ(op, this->op_->cur_op());
1447 ASSERT_TRUE(this->op_->is_register()) << "Failed op: 0x" << std::hex << op;
1448 ASSERT_EQ(1U, this->op_->StackSize()) << "Failed op: 0x" << std::hex << op;
1449 ASSERT_EQ(op - 0x50U, this->op_->StackAt(0)) << "Failed op: 0x" << std::hex << op;
1450 }
1451 }
1452
TYPED_TEST_P(DwarfOpTest,op_regx)1453 TYPED_TEST_P(DwarfOpTest, op_regx) {
1454 std::vector<uint8_t> opcode_buffer = {
1455 0x90, 0x02, 0x90, 0x80, 0x15,
1456 };
1457 this->op_memory_.SetMemory(0, opcode_buffer);
1458
1459 ASSERT_TRUE(this->op_->Eval(0, 2));
1460 ASSERT_EQ(0x90, this->op_->cur_op());
1461 ASSERT_TRUE(this->op_->is_register());
1462 ASSERT_EQ(1U, this->op_->StackSize());
1463 ASSERT_EQ(0x02U, this->op_->StackAt(0));
1464
1465 ASSERT_TRUE(this->op_->Eval(2, 5));
1466 ASSERT_EQ(0x90, this->op_->cur_op());
1467 ASSERT_TRUE(this->op_->is_register());
1468 ASSERT_EQ(1U, this->op_->StackSize());
1469 ASSERT_EQ(0xa80U, this->op_->StackAt(0));
1470 }
1471
TYPED_TEST_P(DwarfOpTest,op_breg)1472 TYPED_TEST_P(DwarfOpTest, op_breg) {
1473 std::vector<uint8_t> opcode_buffer;
1474
1475 // Verify every reg opcode.
1476 for (uint8_t op = 0x70; op <= 0x8f; op++) {
1477 // Positive value added to register.
1478 opcode_buffer.push_back(op);
1479 opcode_buffer.push_back(0x12);
1480 // Negative value added to register.
1481 opcode_buffer.push_back(op);
1482 opcode_buffer.push_back(0x7e);
1483 }
1484 this->op_memory_.SetMemory(0, opcode_buffer);
1485
1486 RegsImplFake<TypeParam> regs(32);
1487 for (size_t i = 0; i < 32; i++) {
1488 regs[i] = i + 10;
1489 }
1490 RegsInfo<TypeParam> regs_info(®s);
1491 this->op_->set_regs_info(®s_info);
1492
1493 uint64_t offset = 0;
1494 for (uint32_t op = 0x70; op <= 0x8f; op++) {
1495 // Positive value added to register.
1496 ASSERT_TRUE(this->op_->Eval(offset, offset + 2)) << "Failed op: 0x" << std::hex << op;
1497 ASSERT_EQ(op, this->op_->cur_op());
1498 ASSERT_EQ(1U, this->op_->StackSize()) << "Failed op: 0x" << std::hex << op;
1499 ASSERT_EQ(op - 0x70 + 10 + 0x12, this->op_->StackAt(0)) << "Failed op: 0x" << std::hex << op;
1500 offset += 2;
1501
1502 // Negative value added to register.
1503 ASSERT_TRUE(this->op_->Eval(offset, offset + 2)) << "Failed op: 0x" << std::hex << op;
1504 ASSERT_EQ(op, this->op_->cur_op());
1505 ASSERT_EQ(1U, this->op_->StackSize()) << "Failed op: 0x" << std::hex << op;
1506 ASSERT_EQ(op - 0x70 + 10 - 2, this->op_->StackAt(0)) << "Failed op: 0x" << std::hex << op;
1507 offset += 2;
1508 }
1509 }
1510
TYPED_TEST_P(DwarfOpTest,op_breg_invalid_register)1511 TYPED_TEST_P(DwarfOpTest, op_breg_invalid_register) {
1512 std::vector<uint8_t> opcode_buffer = {
1513 0x7f, 0x12, 0x80, 0x12,
1514 };
1515 this->op_memory_.SetMemory(0, opcode_buffer);
1516
1517 RegsImplFake<TypeParam> regs(16);
1518 for (size_t i = 0; i < 16; i++) {
1519 regs[i] = i + 10;
1520 }
1521 RegsInfo<TypeParam> regs_info(®s);
1522 this->op_->set_regs_info(®s_info);
1523
1524 // Should pass since this references the last regsister.
1525 ASSERT_TRUE(this->op_->Eval(0, 2));
1526 ASSERT_EQ(0x7fU, this->op_->cur_op());
1527 ASSERT_EQ(1U, this->op_->StackSize());
1528 ASSERT_EQ(0x2bU, this->op_->StackAt(0));
1529
1530 // Should fail since this references a non-existent register.
1531 ASSERT_FALSE(this->op_->Eval(2, 4));
1532 ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode());
1533 }
1534
TYPED_TEST_P(DwarfOpTest,op_bregx)1535 TYPED_TEST_P(DwarfOpTest, op_bregx) {
1536 std::vector<uint8_t> opcode_buffer = {// Positive value added to register.
1537 0x92, 0x05, 0x20,
1538 // Negative value added to register.
1539 0x92, 0x06, 0x80, 0x7e,
1540 // Illegal register.
1541 0x92, 0x80, 0x15, 0x80, 0x02};
1542 this->op_memory_.SetMemory(0, opcode_buffer);
1543
1544 RegsImplFake<TypeParam> regs(10);
1545 regs[5] = 0x45;
1546 regs[6] = 0x190;
1547 RegsInfo<TypeParam> regs_info(®s);
1548 this->op_->set_regs_info(®s_info);
1549
1550 ASSERT_TRUE(this->op_->Eval(0, 3));
1551 ASSERT_EQ(0x92, this->op_->cur_op());
1552 ASSERT_EQ(1U, this->op_->StackSize());
1553 ASSERT_EQ(0x65U, this->op_->StackAt(0));
1554
1555 ASSERT_TRUE(this->op_->Eval(3, 7));
1556 ASSERT_EQ(0x92, this->op_->cur_op());
1557 ASSERT_EQ(1U, this->op_->StackSize());
1558 ASSERT_EQ(0x90U, this->op_->StackAt(0));
1559
1560 ASSERT_FALSE(this->op_->Eval(7, 12));
1561 ASSERT_EQ(DWARF_ERROR_ILLEGAL_VALUE, this->op_->LastErrorCode());
1562 }
1563
TYPED_TEST_P(DwarfOpTest,op_nop)1564 TYPED_TEST_P(DwarfOpTest, op_nop) {
1565 this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x96});
1566
1567 ASSERT_TRUE(this->op_->Decode());
1568 ASSERT_EQ(0x96, this->op_->cur_op());
1569 ASSERT_EQ(0U, this->op_->StackSize());
1570 }
1571
TYPED_TEST_P(DwarfOpTest,is_dex_pc)1572 TYPED_TEST_P(DwarfOpTest, is_dex_pc) {
1573 // Special sequence that indicates this is a dex pc.
1574 this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x0c, 'D', 'E', 'X', '1', 0x13});
1575
1576 ASSERT_TRUE(this->op_->Eval(0, 6));
1577 EXPECT_TRUE(this->op_->dex_pc_set());
1578
1579 // Try without the last op.
1580 ASSERT_TRUE(this->op_->Eval(0, 5));
1581 EXPECT_FALSE(this->op_->dex_pc_set());
1582
1583 // Change the constant.
1584 this->op_memory_.SetMemory(0, std::vector<uint8_t>{0x0c, 'D', 'E', 'X', '2', 0x13});
1585 ASSERT_TRUE(this->op_->Eval(0, 6));
1586 EXPECT_FALSE(this->op_->dex_pc_set());
1587 }
1588
1589 REGISTER_TYPED_TEST_SUITE_P(DwarfOpTest, decode, eval, illegal_opcode, not_implemented, op_addr,
1590 op_deref, op_deref_size, const_unsigned, const_signed, const_uleb,
1591 const_sleb, op_dup, op_drop, op_over, op_pick, op_swap, op_rot, op_abs,
1592 op_and, op_div, op_minus, op_mod, op_mul, op_neg, op_not, op_or,
1593 op_plus, op_plus_uconst, op_shl, op_shr, op_shra, op_xor, op_bra,
1594 compare_opcode_stack_error, compare_opcodes, op_skip, op_lit, op_reg,
1595 op_regx, op_breg, op_breg_invalid_register, op_bregx, op_nop,
1596 is_dex_pc);
1597
1598 typedef ::testing::Types<uint32_t, uint64_t> DwarfOpTestTypes;
1599 INSTANTIATE_TYPED_TEST_SUITE_P(Libunwindstack, DwarfOpTest, DwarfOpTestTypes);
1600
1601 } // namespace unwindstack
1602