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