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