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