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