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