1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <stdint.h>
18
19 #include <deque>
20 #include <ios>
21 #include <memory>
22 #include <string>
23
24 #include <gtest/gtest.h>
25
26 #include <unwindstack/Log.h>
27 #include <unwindstack/RegsArm.h>
28
29 #include "ArmExidx.h"
30
31 #include "LogFake.h"
32 #include "MemoryFake.h"
33
34 namespace unwindstack {
35
36 class ArmExidxDecodeTest : public ::testing::TestWithParam<std::string> {
37 protected:
Init(Memory * process_memory=nullptr)38 void Init(Memory* process_memory = nullptr) {
39 TearDown();
40
41 if (process_memory == nullptr) {
42 process_memory = &process_memory_;
43 }
44
45 regs_arm_.reset(new RegsArm());
46 for (size_t i = 0; i < regs_arm_->total_regs(); i++) {
47 (*regs_arm_)[i] = 0;
48 }
49 regs_arm_->set_pc(0);
50 regs_arm_->set_sp(0);
51
52 exidx_.reset(new ArmExidx(regs_arm_.get(), &elf_memory_, process_memory));
53 if (log_) {
54 exidx_->set_log(true);
55 exidx_->set_log_indent(0);
56 exidx_->set_log_skip_execution(false);
57 }
58 data_ = exidx_->data();
59 exidx_->set_cfa(0x10000);
60 }
61
SetUp()62 void SetUp() override {
63 if (GetParam() != "no_logging") {
64 log_ = false;
65 } else {
66 log_ = true;
67 }
68 ResetLogs();
69 elf_memory_.Clear();
70 process_memory_.Clear();
71 Init();
72 }
73
74 std::unique_ptr<ArmExidx> exidx_;
75 std::unique_ptr<RegsArm> regs_arm_;
76 std::deque<uint8_t>* data_;
77
78 MemoryFake elf_memory_;
79 MemoryFake process_memory_;
80 bool log_;
81 };
82
TEST_P(ArmExidxDecodeTest,vsp_incr)83 TEST_P(ArmExidxDecodeTest, vsp_incr) {
84 // 00xxxxxx: vsp = vsp + (xxxxxx << 2) + 4
85 data_->push_back(0x00);
86 ASSERT_TRUE(exidx_->Decode());
87 ASSERT_FALSE(exidx_->pc_set());
88 ASSERT_EQ("", GetFakeLogBuf());
89 if (log_) {
90 ASSERT_EQ("4 unwind vsp = vsp + 4\n", GetFakeLogPrint());
91 } else {
92 ASSERT_EQ("", GetFakeLogPrint());
93 }
94 ASSERT_EQ(0x10004U, exidx_->cfa());
95
96 ResetLogs();
97 data_->clear();
98 data_->push_back(0x01);
99 ASSERT_TRUE(exidx_->Decode());
100 ASSERT_FALSE(exidx_->pc_set());
101 ASSERT_EQ("", GetFakeLogBuf());
102 if (log_) {
103 ASSERT_EQ("4 unwind vsp = vsp + 8\n", GetFakeLogPrint());
104 } else {
105 ASSERT_EQ("", GetFakeLogPrint());
106 }
107 ASSERT_EQ(0x1000cU, exidx_->cfa());
108
109 ResetLogs();
110 data_->clear();
111 data_->push_back(0x3f);
112 ASSERT_TRUE(exidx_->Decode());
113 ASSERT_FALSE(exidx_->pc_set());
114 ASSERT_EQ("", GetFakeLogBuf());
115 if (log_) {
116 ASSERT_EQ("4 unwind vsp = vsp + 256\n", GetFakeLogPrint());
117 } else {
118 ASSERT_EQ("", GetFakeLogPrint());
119 }
120 ASSERT_EQ(0x1010cU, exidx_->cfa());
121 }
122
TEST_P(ArmExidxDecodeTest,vsp_decr)123 TEST_P(ArmExidxDecodeTest, vsp_decr) {
124 // 01xxxxxx: vsp = vsp - (xxxxxx << 2) + 4
125 data_->push_back(0x40);
126 ASSERT_TRUE(exidx_->Decode());
127 ASSERT_FALSE(exidx_->pc_set());
128 ASSERT_EQ("", GetFakeLogBuf());
129 if (log_) {
130 ASSERT_EQ("4 unwind vsp = vsp - 4\n", GetFakeLogPrint());
131 } else {
132 ASSERT_EQ("", GetFakeLogPrint());
133 }
134 ASSERT_EQ(0xfffcU, exidx_->cfa());
135
136 ResetLogs();
137 data_->clear();
138 data_->push_back(0x41);
139 ASSERT_TRUE(exidx_->Decode());
140 ASSERT_FALSE(exidx_->pc_set());
141 ASSERT_EQ("", GetFakeLogBuf());
142 if (log_) {
143 ASSERT_EQ("4 unwind vsp = vsp - 8\n", GetFakeLogPrint());
144 } else {
145 ASSERT_EQ("", GetFakeLogPrint());
146 }
147 ASSERT_EQ(0xfff4U, exidx_->cfa());
148
149 ResetLogs();
150 data_->clear();
151 data_->push_back(0x7f);
152 ASSERT_TRUE(exidx_->Decode());
153 ASSERT_FALSE(exidx_->pc_set());
154 ASSERT_EQ("", GetFakeLogBuf());
155 if (log_) {
156 ASSERT_EQ("4 unwind vsp = vsp - 256\n", GetFakeLogPrint());
157 } else {
158 ASSERT_EQ("", GetFakeLogPrint());
159 }
160 ASSERT_EQ(0xfef4U, exidx_->cfa());
161 }
162
TEST_P(ArmExidxDecodeTest,refuse_unwind)163 TEST_P(ArmExidxDecodeTest, refuse_unwind) {
164 // 10000000 00000000: Refuse to unwind
165 data_->push_back(0x80);
166 data_->push_back(0x00);
167 ASSERT_FALSE(exidx_->Decode());
168 ASSERT_EQ("", GetFakeLogBuf());
169 if (log_) {
170 ASSERT_EQ("4 unwind Refuse to unwind\n", GetFakeLogPrint());
171 } else {
172 ASSERT_EQ("", GetFakeLogPrint());
173 }
174 ASSERT_EQ(ARM_STATUS_NO_UNWIND, exidx_->status());
175 }
176
TEST_P(ArmExidxDecodeTest,pop_up_to_12)177 TEST_P(ArmExidxDecodeTest, pop_up_to_12) {
178 // 1000iiii iiiiiiii: Pop up to 12 integer registers
179 data_->push_back(0x88);
180 data_->push_back(0x00);
181 process_memory_.SetData32(0x10000, 0x10);
182 ASSERT_TRUE(exidx_->Decode());
183 ASSERT_TRUE(exidx_->pc_set());
184 ASSERT_EQ("", GetFakeLogBuf());
185 if (log_) {
186 ASSERT_EQ("4 unwind pop {r15}\n", GetFakeLogPrint());
187 } else {
188 ASSERT_EQ("", GetFakeLogPrint());
189 }
190 ASSERT_EQ(0x10004U, exidx_->cfa());
191 ASSERT_EQ(0x10U, (*exidx_->regs())[15]);
192
193 ResetLogs();
194 data_->push_back(0x8f);
195 data_->push_back(0xff);
196 for (size_t i = 0; i < 12; i++) {
197 process_memory_.SetData32(0x10004 + i * 4, i + 0x20);
198 }
199 exidx_->set_pc_set(false);
200 ASSERT_TRUE(exidx_->Decode());
201 ASSERT_TRUE(exidx_->pc_set());
202 ASSERT_EQ("", GetFakeLogBuf());
203 if (log_) {
204 ASSERT_EQ("4 unwind pop {r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15}\n",
205 GetFakeLogPrint());
206 } else {
207 ASSERT_EQ("", GetFakeLogPrint());
208 }
209 // Popping r13 results in a modified cfa.
210 ASSERT_EQ(0x29U, exidx_->cfa());
211
212 ASSERT_EQ(0x20U, (*exidx_->regs())[4]);
213 ASSERT_EQ(0x21U, (*exidx_->regs())[5]);
214 ASSERT_EQ(0x22U, (*exidx_->regs())[6]);
215 ASSERT_EQ(0x23U, (*exidx_->regs())[7]);
216 ASSERT_EQ(0x24U, (*exidx_->regs())[8]);
217 ASSERT_EQ(0x25U, (*exidx_->regs())[9]);
218 ASSERT_EQ(0x26U, (*exidx_->regs())[10]);
219 ASSERT_EQ(0x27U, (*exidx_->regs())[11]);
220 ASSERT_EQ(0x28U, (*exidx_->regs())[12]);
221 ASSERT_EQ(0x29U, (*exidx_->regs())[13]);
222 ASSERT_EQ(0x2aU, (*exidx_->regs())[14]);
223 ASSERT_EQ(0x2bU, (*exidx_->regs())[15]);
224
225 ResetLogs();
226 exidx_->set_cfa(0x10034);
227 data_->push_back(0x81);
228 data_->push_back(0x28);
229 process_memory_.SetData32(0x10034, 0x11);
230 process_memory_.SetData32(0x10038, 0x22);
231 process_memory_.SetData32(0x1003c, 0x33);
232 exidx_->set_pc_set(false);
233 ASSERT_TRUE(exidx_->Decode());
234 ASSERT_FALSE(exidx_->pc_set());
235 ASSERT_EQ("", GetFakeLogBuf());
236 if (log_) {
237 ASSERT_EQ("4 unwind pop {r7, r9, r12}\n", GetFakeLogPrint());
238 } else {
239 ASSERT_EQ("", GetFakeLogPrint());
240 }
241 ASSERT_EQ(0x10040U, exidx_->cfa());
242 ASSERT_EQ(0x11U, (*exidx_->regs())[7]);
243 ASSERT_EQ(0x22U, (*exidx_->regs())[9]);
244 ASSERT_EQ(0x33U, (*exidx_->regs())[12]);
245 }
246
TEST_P(ArmExidxDecodeTest,set_vsp_from_register)247 TEST_P(ArmExidxDecodeTest, set_vsp_from_register) {
248 // 1001nnnn: Set vsp = r[nnnn] (nnnn != 13, 15)
249 exidx_->set_cfa(0x100);
250 for (size_t i = 0; i < 15; i++) {
251 (*regs_arm_)[i] = i + 1;
252 }
253
254 data_->push_back(0x90);
255 ASSERT_TRUE(exidx_->Decode());
256 ASSERT_FALSE(exidx_->pc_set());
257 ASSERT_EQ("", GetFakeLogBuf());
258 if (log_) {
259 ASSERT_EQ("4 unwind vsp = r0\n", GetFakeLogPrint());
260 } else {
261 ASSERT_EQ("", GetFakeLogPrint());
262 }
263 ASSERT_EQ(1U, exidx_->cfa());
264
265 ResetLogs();
266 data_->push_back(0x93);
267 ASSERT_TRUE(exidx_->Decode());
268 ASSERT_FALSE(exidx_->pc_set());
269 ASSERT_EQ("", GetFakeLogBuf());
270 if (log_) {
271 ASSERT_EQ("4 unwind vsp = r3\n", GetFakeLogPrint());
272 } else {
273 ASSERT_EQ("", GetFakeLogPrint());
274 }
275 ASSERT_EQ(4U, exidx_->cfa());
276
277 ResetLogs();
278 data_->push_back(0x9e);
279 ASSERT_TRUE(exidx_->Decode());
280 ASSERT_FALSE(exidx_->pc_set());
281 ASSERT_EQ("", GetFakeLogBuf());
282 if (log_) {
283 ASSERT_EQ("4 unwind vsp = r14\n", GetFakeLogPrint());
284 } else {
285 ASSERT_EQ("", GetFakeLogPrint());
286 }
287 ASSERT_EQ(15U, exidx_->cfa());
288 }
289
TEST_P(ArmExidxDecodeTest,reserved_prefix)290 TEST_P(ArmExidxDecodeTest, reserved_prefix) {
291 // 10011101: Reserved as prefix for ARM register to register moves
292 data_->push_back(0x9d);
293 ASSERT_FALSE(exidx_->Decode());
294 ASSERT_EQ("", GetFakeLogBuf());
295 if (log_) {
296 ASSERT_EQ("4 unwind [Reserved]\n", GetFakeLogPrint());
297 } else {
298 ASSERT_EQ("", GetFakeLogPrint());
299 }
300 ASSERT_EQ(ARM_STATUS_RESERVED, exidx_->status());
301
302 // 10011111: Reserved as prefix for Intel Wireless MMX register to register moves
303 ResetLogs();
304 data_->push_back(0x9f);
305 ASSERT_FALSE(exidx_->Decode());
306 ASSERT_EQ("", GetFakeLogBuf());
307 if (log_) {
308 ASSERT_EQ("4 unwind [Reserved]\n", GetFakeLogPrint());
309 } else {
310 ASSERT_EQ("", GetFakeLogPrint());
311 }
312 ASSERT_EQ(ARM_STATUS_RESERVED, exidx_->status());
313 }
314
TEST_P(ArmExidxDecodeTest,pop_registers)315 TEST_P(ArmExidxDecodeTest, pop_registers) {
316 // 10100nnn: Pop r4-r[4+nnn]
317 data_->push_back(0xa0);
318 process_memory_.SetData32(0x10000, 0x14);
319 ASSERT_TRUE(exidx_->Decode());
320 ASSERT_FALSE(exidx_->pc_set());
321 ASSERT_EQ("", GetFakeLogBuf());
322 if (log_) {
323 ASSERT_EQ("4 unwind pop {r4}\n", GetFakeLogPrint());
324 } else {
325 ASSERT_EQ("", GetFakeLogPrint());
326 }
327 ASSERT_EQ(0x10004U, exidx_->cfa());
328 ASSERT_EQ(0x14U, (*exidx_->regs())[4]);
329
330 ResetLogs();
331 data_->push_back(0xa3);
332 process_memory_.SetData32(0x10004, 0x20);
333 process_memory_.SetData32(0x10008, 0x30);
334 process_memory_.SetData32(0x1000c, 0x40);
335 process_memory_.SetData32(0x10010, 0x50);
336 ASSERT_TRUE(exidx_->Decode());
337 ASSERT_FALSE(exidx_->pc_set());
338 ASSERT_EQ("", GetFakeLogBuf());
339 if (log_) {
340 ASSERT_EQ("4 unwind pop {r4-r7}\n", GetFakeLogPrint());
341 } else {
342 ASSERT_EQ("", GetFakeLogPrint());
343 }
344 ASSERT_EQ(0x10014U, exidx_->cfa());
345 ASSERT_EQ(0x20U, (*exidx_->regs())[4]);
346 ASSERT_EQ(0x30U, (*exidx_->regs())[5]);
347 ASSERT_EQ(0x40U, (*exidx_->regs())[6]);
348 ASSERT_EQ(0x50U, (*exidx_->regs())[7]);
349
350 ResetLogs();
351 data_->push_back(0xa7);
352 process_memory_.SetData32(0x10014, 0x41);
353 process_memory_.SetData32(0x10018, 0x51);
354 process_memory_.SetData32(0x1001c, 0x61);
355 process_memory_.SetData32(0x10020, 0x71);
356 process_memory_.SetData32(0x10024, 0x81);
357 process_memory_.SetData32(0x10028, 0x91);
358 process_memory_.SetData32(0x1002c, 0xa1);
359 process_memory_.SetData32(0x10030, 0xb1);
360 ASSERT_TRUE(exidx_->Decode());
361 ASSERT_FALSE(exidx_->pc_set());
362 ASSERT_EQ("", GetFakeLogBuf());
363 if (log_) {
364 ASSERT_EQ("4 unwind pop {r4-r11}\n", GetFakeLogPrint());
365 } else {
366 ASSERT_EQ("", GetFakeLogPrint());
367 }
368 ASSERT_EQ(0x10034U, exidx_->cfa());
369 ASSERT_EQ(0x41U, (*exidx_->regs())[4]);
370 ASSERT_EQ(0x51U, (*exidx_->regs())[5]);
371 ASSERT_EQ(0x61U, (*exidx_->regs())[6]);
372 ASSERT_EQ(0x71U, (*exidx_->regs())[7]);
373 ASSERT_EQ(0x81U, (*exidx_->regs())[8]);
374 ASSERT_EQ(0x91U, (*exidx_->regs())[9]);
375 ASSERT_EQ(0xa1U, (*exidx_->regs())[10]);
376 ASSERT_EQ(0xb1U, (*exidx_->regs())[11]);
377 }
378
TEST_P(ArmExidxDecodeTest,pop_registers_with_r14)379 TEST_P(ArmExidxDecodeTest, pop_registers_with_r14) {
380 // 10101nnn: Pop r4-r[4+nnn], r14
381 data_->push_back(0xa8);
382 process_memory_.SetData32(0x10000, 0x12);
383 process_memory_.SetData32(0x10004, 0x22);
384 ASSERT_TRUE(exidx_->Decode());
385 ASSERT_FALSE(exidx_->pc_set());
386 ASSERT_EQ("", GetFakeLogBuf());
387 if (log_) {
388 ASSERT_EQ("4 unwind pop {r4, r14}\n", GetFakeLogPrint());
389 } else {
390 ASSERT_EQ("", GetFakeLogPrint());
391 }
392 ASSERT_EQ(0x10008U, exidx_->cfa());
393 ASSERT_EQ(0x12U, (*exidx_->regs())[4]);
394 ASSERT_EQ(0x22U, (*exidx_->regs())[14]);
395
396 ResetLogs();
397 data_->push_back(0xab);
398 process_memory_.SetData32(0x10008, 0x1);
399 process_memory_.SetData32(0x1000c, 0x2);
400 process_memory_.SetData32(0x10010, 0x3);
401 process_memory_.SetData32(0x10014, 0x4);
402 process_memory_.SetData32(0x10018, 0x5);
403 ASSERT_TRUE(exidx_->Decode());
404 ASSERT_FALSE(exidx_->pc_set());
405 ASSERT_EQ("", GetFakeLogBuf());
406 if (log_) {
407 ASSERT_EQ("4 unwind pop {r4-r7, r14}\n", GetFakeLogPrint());
408 } else {
409 ASSERT_EQ("", GetFakeLogPrint());
410 }
411 ASSERT_EQ(0x1001cU, exidx_->cfa());
412 ASSERT_EQ(0x1U, (*exidx_->regs())[4]);
413 ASSERT_EQ(0x2U, (*exidx_->regs())[5]);
414 ASSERT_EQ(0x3U, (*exidx_->regs())[6]);
415 ASSERT_EQ(0x4U, (*exidx_->regs())[7]);
416 ASSERT_EQ(0x5U, (*exidx_->regs())[14]);
417
418 ResetLogs();
419 data_->push_back(0xaf);
420 process_memory_.SetData32(0x1001c, 0x1a);
421 process_memory_.SetData32(0x10020, 0x2a);
422 process_memory_.SetData32(0x10024, 0x3a);
423 process_memory_.SetData32(0x10028, 0x4a);
424 process_memory_.SetData32(0x1002c, 0x5a);
425 process_memory_.SetData32(0x10030, 0x6a);
426 process_memory_.SetData32(0x10034, 0x7a);
427 process_memory_.SetData32(0x10038, 0x8a);
428 process_memory_.SetData32(0x1003c, 0x9a);
429 ASSERT_TRUE(exidx_->Decode());
430 ASSERT_FALSE(exidx_->pc_set());
431 ASSERT_EQ("", GetFakeLogBuf());
432 if (log_) {
433 ASSERT_EQ("4 unwind pop {r4-r11, r14}\n", GetFakeLogPrint());
434 } else {
435 ASSERT_EQ("", GetFakeLogPrint());
436 }
437 ASSERT_EQ(0x10040U, exidx_->cfa());
438 ASSERT_EQ(0x1aU, (*exidx_->regs())[4]);
439 ASSERT_EQ(0x2aU, (*exidx_->regs())[5]);
440 ASSERT_EQ(0x3aU, (*exidx_->regs())[6]);
441 ASSERT_EQ(0x4aU, (*exidx_->regs())[7]);
442 ASSERT_EQ(0x5aU, (*exidx_->regs())[8]);
443 ASSERT_EQ(0x6aU, (*exidx_->regs())[9]);
444 ASSERT_EQ(0x7aU, (*exidx_->regs())[10]);
445 ASSERT_EQ(0x8aU, (*exidx_->regs())[11]);
446 ASSERT_EQ(0x9aU, (*exidx_->regs())[14]);
447 }
448
TEST_P(ArmExidxDecodeTest,finish)449 TEST_P(ArmExidxDecodeTest, finish) {
450 // 10110000: Finish
451 data_->push_back(0xb0);
452 ASSERT_FALSE(exidx_->Decode());
453 ASSERT_EQ("", GetFakeLogBuf());
454 if (log_) {
455 ASSERT_EQ("4 unwind finish\n", GetFakeLogPrint());
456 } else {
457 ASSERT_EQ("", GetFakeLogPrint());
458 }
459 ASSERT_EQ(0x10000U, exidx_->cfa());
460 ASSERT_EQ(ARM_STATUS_FINISH, exidx_->status());
461 }
462
TEST_P(ArmExidxDecodeTest,spare)463 TEST_P(ArmExidxDecodeTest, spare) {
464 // 10110001 00000000: Spare
465 data_->push_back(0xb1);
466 data_->push_back(0x00);
467 ASSERT_FALSE(exidx_->Decode());
468 ASSERT_EQ("", GetFakeLogBuf());
469 if (log_) {
470 ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint());
471 } else {
472 ASSERT_EQ("", GetFakeLogPrint());
473 }
474 ASSERT_EQ(0x10000U, exidx_->cfa());
475 ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status());
476
477 // 10110001 xxxxyyyy: Spare (xxxx != 0000)
478 for (size_t x = 1; x < 16; x++) {
479 for (size_t y = 0; y < 16; y++) {
480 ResetLogs();
481 data_->push_back(0xb1);
482 data_->push_back((x << 4) | y);
483 ASSERT_FALSE(exidx_->Decode()) << "x, y = " << x << ", " << y;
484 ASSERT_EQ("", GetFakeLogBuf()) << "x, y = " << x << ", " << y;
485 if (log_) {
486 ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint()) << "x, y = " << x << ", " << y;
487 } else {
488 ASSERT_EQ("", GetFakeLogPrint());
489 }
490 ASSERT_EQ(0x10000U, exidx_->cfa()) << "x, y = " << x << ", " << y;
491 ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status());
492 }
493 }
494
495 // 101101nn: Spare
496 for (size_t n = 0; n < 4; n++) {
497 ResetLogs();
498 data_->push_back(0xb4 | n);
499 ASSERT_FALSE(exidx_->Decode()) << "n = " << n;
500 ASSERT_EQ("", GetFakeLogBuf()) << "n = " << n;
501 if (log_) {
502 ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint()) << "n = " << n;
503 } else {
504 ASSERT_EQ("", GetFakeLogPrint());
505 }
506 ASSERT_EQ(0x10000U, exidx_->cfa()) << "n = " << n;
507 ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status());
508 }
509
510 // 11000111 00000000: Spare
511 ResetLogs();
512 data_->push_back(0xc7);
513 data_->push_back(0x00);
514 ASSERT_FALSE(exidx_->Decode());
515 ASSERT_EQ("", GetFakeLogBuf());
516 if (log_) {
517 ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint());
518 } else {
519 ASSERT_EQ("", GetFakeLogPrint());
520 }
521 ASSERT_EQ(0x10000U, exidx_->cfa());
522 ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status());
523
524 // 11000111 xxxxyyyy: Spare (xxxx != 0000)
525 for (size_t x = 1; x < 16; x++) {
526 for (size_t y = 0; y < 16; y++) {
527 ResetLogs();
528 data_->push_back(0xc7);
529 data_->push_back(0x10);
530 ASSERT_FALSE(exidx_->Decode()) << "x, y = " << x << ", " << y;
531 ASSERT_EQ("", GetFakeLogBuf()) << "x, y = " << x << ", " << y;
532 if (log_) {
533 ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint()) << "x, y = " << x << ", " << y;
534 } else {
535 ASSERT_EQ("", GetFakeLogPrint());
536 }
537 ASSERT_EQ(0x10000U, exidx_->cfa()) << "x, y = " << x << ", " << y;
538 ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status());
539 }
540 }
541
542 // 11001yyy: Spare (yyy != 000, 001)
543 for (size_t y = 2; y < 8; y++) {
544 ResetLogs();
545 data_->push_back(0xc8 | y);
546 ASSERT_FALSE(exidx_->Decode()) << "y = " << y;
547 ASSERT_EQ("", GetFakeLogBuf()) << "y = " << y;
548 if (log_) {
549 ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint()) << "y = " << y;
550 } else {
551 ASSERT_EQ("", GetFakeLogPrint());
552 }
553 ASSERT_EQ(0x10000U, exidx_->cfa()) << "y = " << y;
554 ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status());
555 }
556
557 // 11xxxyyy: Spare (xxx != 000, 001, 010)
558 for (size_t x = 3; x < 8; x++) {
559 for (size_t y = 0; y < 8; y++) {
560 ResetLogs();
561 data_->push_back(0xc0 | (x << 3) | y);
562 ASSERT_FALSE(exidx_->Decode()) << "x, y = " << x << ", " << y;
563 ASSERT_EQ("", GetFakeLogBuf()) << "x, y = " << x << ", " << y;
564 if (log_) {
565 ASSERT_EQ("4 unwind Spare\n", GetFakeLogPrint()) << "x, y = " << x << ", " << y;
566 } else {
567 ASSERT_EQ("", GetFakeLogPrint());
568 }
569 ASSERT_EQ(0x10000U, exidx_->cfa()) << "x, y = " << x << ", " << y;
570 ASSERT_EQ(ARM_STATUS_SPARE, exidx_->status());
571 }
572 }
573 }
574
TEST_P(ArmExidxDecodeTest,pop_registers_under_mask)575 TEST_P(ArmExidxDecodeTest, pop_registers_under_mask) {
576 // 10110001 0000iiii: Pop integer registers {r0, r1, r2, r3}
577 data_->push_back(0xb1);
578 data_->push_back(0x01);
579 process_memory_.SetData32(0x10000, 0x45);
580 ASSERT_TRUE(exidx_->Decode());
581 ASSERT_FALSE(exidx_->pc_set());
582 ASSERT_EQ("", GetFakeLogBuf());
583 if (log_) {
584 ASSERT_EQ("4 unwind pop {r0}\n", GetFakeLogPrint());
585 } else {
586 ASSERT_EQ("", GetFakeLogPrint());
587 }
588 ASSERT_EQ(0x10004U, exidx_->cfa());
589 ASSERT_EQ(0x45U, (*exidx_->regs())[0]);
590
591 ResetLogs();
592 data_->push_back(0xb1);
593 data_->push_back(0x0a);
594 process_memory_.SetData32(0x10004, 0x23);
595 process_memory_.SetData32(0x10008, 0x24);
596 ASSERT_TRUE(exidx_->Decode());
597 ASSERT_FALSE(exidx_->pc_set());
598 ASSERT_EQ("", GetFakeLogBuf());
599 if (log_) {
600 ASSERT_EQ("4 unwind pop {r1, r3}\n", GetFakeLogPrint());
601 } else {
602 ASSERT_EQ("", GetFakeLogPrint());
603 }
604 ASSERT_EQ(0x1000cU, exidx_->cfa());
605 ASSERT_EQ(0x23U, (*exidx_->regs())[1]);
606 ASSERT_EQ(0x24U, (*exidx_->regs())[3]);
607
608 ResetLogs();
609 data_->push_back(0xb1);
610 data_->push_back(0x0f);
611 process_memory_.SetData32(0x1000c, 0x65);
612 process_memory_.SetData32(0x10010, 0x54);
613 process_memory_.SetData32(0x10014, 0x43);
614 process_memory_.SetData32(0x10018, 0x32);
615 ASSERT_TRUE(exidx_->Decode());
616 ASSERT_FALSE(exidx_->pc_set());
617 ASSERT_EQ("", GetFakeLogBuf());
618 if (log_) {
619 ASSERT_EQ("4 unwind pop {r0, r1, r2, r3}\n", GetFakeLogPrint());
620 } else {
621 ASSERT_EQ("", GetFakeLogPrint());
622 }
623 ASSERT_EQ(0x1001cU, exidx_->cfa());
624 ASSERT_EQ(0x65U, (*exidx_->regs())[0]);
625 ASSERT_EQ(0x54U, (*exidx_->regs())[1]);
626 ASSERT_EQ(0x43U, (*exidx_->regs())[2]);
627 ASSERT_EQ(0x32U, (*exidx_->regs())[3]);
628 }
629
TEST_P(ArmExidxDecodeTest,vsp_large_incr)630 TEST_P(ArmExidxDecodeTest, vsp_large_incr) {
631 // 10110010 uleb128: vsp = vsp + 0x204 + (uleb128 << 2)
632 data_->push_back(0xb2);
633 data_->push_back(0x7f);
634 ASSERT_TRUE(exidx_->Decode());
635 ASSERT_FALSE(exidx_->pc_set());
636 ASSERT_EQ("", GetFakeLogBuf());
637 if (log_) {
638 ASSERT_EQ("4 unwind vsp = vsp + 1024\n", GetFakeLogPrint());
639 } else {
640 ASSERT_EQ("", GetFakeLogPrint());
641 }
642 ASSERT_EQ(0x10400U, exidx_->cfa());
643
644 ResetLogs();
645 data_->push_back(0xb2);
646 data_->push_back(0xff);
647 data_->push_back(0x02);
648 ASSERT_TRUE(exidx_->Decode());
649 ASSERT_FALSE(exidx_->pc_set());
650 ASSERT_EQ("", GetFakeLogBuf());
651 if (log_) {
652 ASSERT_EQ("4 unwind vsp = vsp + 2048\n", GetFakeLogPrint());
653 } else {
654 ASSERT_EQ("", GetFakeLogPrint());
655 }
656 ASSERT_EQ(0x10c00U, exidx_->cfa());
657
658 ResetLogs();
659 data_->push_back(0xb2);
660 data_->push_back(0xff);
661 data_->push_back(0x82);
662 data_->push_back(0x30);
663 ASSERT_TRUE(exidx_->Decode());
664 ASSERT_FALSE(exidx_->pc_set());
665 ASSERT_EQ("", GetFakeLogBuf());
666 if (log_) {
667 ASSERT_EQ("4 unwind vsp = vsp + 3147776\n", GetFakeLogPrint());
668 } else {
669 ASSERT_EQ("", GetFakeLogPrint());
670 }
671 ASSERT_EQ(0x311400U, exidx_->cfa());
672 }
673
TEST_P(ArmExidxDecodeTest,pop_vfp_fstmfdx)674 TEST_P(ArmExidxDecodeTest, pop_vfp_fstmfdx) {
675 // 10110011 sssscccc: Pop VFP double precision registers D[ssss]-D[ssss+cccc] by FSTMFDX
676 data_->push_back(0xb3);
677 data_->push_back(0x00);
678 ASSERT_TRUE(exidx_->Decode());
679 ASSERT_FALSE(exidx_->pc_set());
680 ASSERT_EQ("", GetFakeLogBuf());
681 if (log_) {
682 ASSERT_EQ("4 unwind pop {d0}\n", GetFakeLogPrint());
683 } else {
684 ASSERT_EQ("", GetFakeLogPrint());
685 }
686 ASSERT_EQ(0x1000cU, exidx_->cfa());
687
688 ResetLogs();
689 data_->push_back(0xb3);
690 data_->push_back(0x48);
691 ASSERT_TRUE(exidx_->Decode());
692 ASSERT_FALSE(exidx_->pc_set());
693 ASSERT_EQ("", GetFakeLogBuf());
694 if (log_) {
695 ASSERT_EQ("4 unwind pop {d4-d12}\n", GetFakeLogPrint());
696 } else {
697 ASSERT_EQ("", GetFakeLogPrint());
698 }
699 ASSERT_EQ(0x10058U, exidx_->cfa());
700 }
701
TEST_P(ArmExidxDecodeTest,pop_vfp8_fstmfdx)702 TEST_P(ArmExidxDecodeTest, pop_vfp8_fstmfdx) {
703 // 10111nnn: Pop VFP double precision registers D[8]-D[8+nnn] by FSTMFDX
704 data_->push_back(0xb8);
705 ASSERT_TRUE(exidx_->Decode());
706 ASSERT_FALSE(exidx_->pc_set());
707 ASSERT_EQ("", GetFakeLogBuf());
708 if (log_) {
709 ASSERT_EQ("4 unwind pop {d8}\n", GetFakeLogPrint());
710 } else {
711 ASSERT_EQ("", GetFakeLogPrint());
712 }
713 ASSERT_EQ(0x1000cU, exidx_->cfa());
714
715 ResetLogs();
716 data_->push_back(0xbb);
717 ASSERT_TRUE(exidx_->Decode());
718 ASSERT_FALSE(exidx_->pc_set());
719 ASSERT_EQ("", GetFakeLogBuf());
720 if (log_) {
721 ASSERT_EQ("4 unwind pop {d8-d11}\n", GetFakeLogPrint());
722 } else {
723 ASSERT_EQ("", GetFakeLogPrint());
724 }
725 ASSERT_EQ(0x10030U, exidx_->cfa());
726
727 ResetLogs();
728 data_->push_back(0xbf);
729 ASSERT_TRUE(exidx_->Decode());
730 ASSERT_FALSE(exidx_->pc_set());
731 ASSERT_EQ("", GetFakeLogBuf());
732 if (log_) {
733 ASSERT_EQ("4 unwind pop {d8-d15}\n", GetFakeLogPrint());
734 } else {
735 ASSERT_EQ("", GetFakeLogPrint());
736 }
737 ASSERT_EQ(0x10074U, exidx_->cfa());
738 }
739
TEST_P(ArmExidxDecodeTest,pop_mmx_wr10)740 TEST_P(ArmExidxDecodeTest, pop_mmx_wr10) {
741 // 11000nnn: Intel Wireless MMX pop wR[10]-wR[10+nnn] (nnn != 6, 7)
742 data_->push_back(0xc0);
743 ASSERT_TRUE(exidx_->Decode());
744 ASSERT_FALSE(exidx_->pc_set());
745 ASSERT_EQ("", GetFakeLogBuf());
746 if (log_) {
747 ASSERT_EQ("4 unwind pop {wR10}\n", GetFakeLogPrint());
748 } else {
749 ASSERT_EQ("", GetFakeLogPrint());
750 }
751 ASSERT_EQ(0x10008U, exidx_->cfa());
752
753 ResetLogs();
754 data_->push_back(0xc2);
755 ASSERT_TRUE(exidx_->Decode());
756 ASSERT_FALSE(exidx_->pc_set());
757 ASSERT_EQ("", GetFakeLogBuf());
758 if (log_) {
759 ASSERT_EQ("4 unwind pop {wR10-wR12}\n", GetFakeLogPrint());
760 } else {
761 ASSERT_EQ("", GetFakeLogPrint());
762 }
763 ASSERT_EQ(0x10020U, exidx_->cfa());
764
765 ResetLogs();
766 data_->push_back(0xc5);
767 ASSERT_TRUE(exidx_->Decode());
768 ASSERT_FALSE(exidx_->pc_set());
769 ASSERT_EQ("", GetFakeLogBuf());
770 if (log_) {
771 ASSERT_EQ("4 unwind pop {wR10-wR15}\n", GetFakeLogPrint());
772 } else {
773 ASSERT_EQ("", GetFakeLogPrint());
774 }
775 ASSERT_EQ(0x10050U, exidx_->cfa());
776 }
777
TEST_P(ArmExidxDecodeTest,pop_mmx_wr)778 TEST_P(ArmExidxDecodeTest, pop_mmx_wr) {
779 // 11000110 sssscccc: Intel Wireless MMX pop wR[ssss]-wR[ssss+cccc]
780 data_->push_back(0xc6);
781 data_->push_back(0x00);
782 ASSERT_TRUE(exidx_->Decode());
783 ASSERT_FALSE(exidx_->pc_set());
784 ASSERT_EQ("", GetFakeLogBuf());
785 if (log_) {
786 ASSERT_EQ("4 unwind pop {wR0}\n", GetFakeLogPrint());
787 } else {
788 ASSERT_EQ("", GetFakeLogPrint());
789 }
790 ASSERT_EQ(0x10008U, exidx_->cfa());
791
792 ResetLogs();
793 data_->push_back(0xc6);
794 data_->push_back(0x25);
795 ASSERT_TRUE(exidx_->Decode());
796 ASSERT_FALSE(exidx_->pc_set());
797 ASSERT_EQ("", GetFakeLogBuf());
798 if (log_) {
799 ASSERT_EQ("4 unwind pop {wR2-wR7}\n", GetFakeLogPrint());
800 } else {
801 ASSERT_EQ("", GetFakeLogPrint());
802 }
803 ASSERT_EQ(0x10038U, exidx_->cfa());
804
805 ResetLogs();
806 data_->push_back(0xc6);
807 data_->push_back(0xff);
808 ASSERT_TRUE(exidx_->Decode());
809 ASSERT_FALSE(exidx_->pc_set());
810 ASSERT_EQ("", GetFakeLogBuf());
811 if (log_) {
812 ASSERT_EQ("4 unwind pop {wR15-wR30}\n", GetFakeLogPrint());
813 } else {
814 ASSERT_EQ("", GetFakeLogPrint());
815 }
816 ASSERT_EQ(0x100b8U, exidx_->cfa());
817 }
818
TEST_P(ArmExidxDecodeTest,pop_mmx_wcgr)819 TEST_P(ArmExidxDecodeTest, pop_mmx_wcgr) {
820 // 11000111 0000iiii: Intel Wireless MMX pop wCGR registes {wCGR0,1,2,3}
821 data_->push_back(0xc7);
822 data_->push_back(0x01);
823 ASSERT_TRUE(exidx_->Decode());
824 ASSERT_FALSE(exidx_->pc_set());
825 ASSERT_EQ("", GetFakeLogBuf());
826 if (log_) {
827 ASSERT_EQ("4 unwind pop {wCGR0}\n", GetFakeLogPrint());
828 } else {
829 ASSERT_EQ("", GetFakeLogPrint());
830 }
831 ASSERT_EQ(0x10004U, exidx_->cfa());
832
833 ResetLogs();
834 data_->push_back(0xc7);
835 data_->push_back(0x0a);
836 ASSERT_TRUE(exidx_->Decode());
837 ASSERT_FALSE(exidx_->pc_set());
838 ASSERT_EQ("", GetFakeLogBuf());
839 if (log_) {
840 ASSERT_EQ("4 unwind pop {wCGR1, wCGR3}\n", GetFakeLogPrint());
841 } else {
842 ASSERT_EQ("", GetFakeLogPrint());
843 }
844 ASSERT_EQ(0x1000cU, exidx_->cfa());
845
846 ResetLogs();
847 data_->push_back(0xc7);
848 data_->push_back(0x0f);
849 ASSERT_TRUE(exidx_->Decode());
850 ASSERT_FALSE(exidx_->pc_set());
851 ASSERT_EQ("", GetFakeLogBuf());
852 if (log_) {
853 ASSERT_EQ("4 unwind pop {wCGR0, wCGR1, wCGR2, wCGR3}\n", GetFakeLogPrint());
854 } else {
855 ASSERT_EQ("", GetFakeLogPrint());
856 }
857 ASSERT_EQ(0x1001cU, exidx_->cfa());
858 }
859
TEST_P(ArmExidxDecodeTest,pop_vfp16_vpush)860 TEST_P(ArmExidxDecodeTest, pop_vfp16_vpush) {
861 // 11001000 sssscccc: Pop VFP double precision registers d[16+ssss]-D[16+ssss+cccc] by VPUSH
862 data_->push_back(0xc8);
863 data_->push_back(0x00);
864 ASSERT_TRUE(exidx_->Decode());
865 ASSERT_FALSE(exidx_->pc_set());
866 ASSERT_EQ("", GetFakeLogBuf());
867 if (log_) {
868 ASSERT_EQ("4 unwind pop {d16}\n", GetFakeLogPrint());
869 } else {
870 ASSERT_EQ("", GetFakeLogPrint());
871 }
872 ASSERT_EQ(0x10008U, exidx_->cfa());
873
874 ResetLogs();
875 data_->push_back(0xc8);
876 data_->push_back(0x14);
877 ASSERT_TRUE(exidx_->Decode());
878 ASSERT_FALSE(exidx_->pc_set());
879 ASSERT_EQ("", GetFakeLogBuf());
880 if (log_) {
881 ASSERT_EQ("4 unwind pop {d17-d21}\n", GetFakeLogPrint());
882 } else {
883 ASSERT_EQ("", GetFakeLogPrint());
884 }
885 ASSERT_EQ(0x10030U, exidx_->cfa());
886
887 ResetLogs();
888 data_->push_back(0xc8);
889 data_->push_back(0xff);
890 ASSERT_TRUE(exidx_->Decode());
891 ASSERT_FALSE(exidx_->pc_set());
892 ASSERT_EQ("", GetFakeLogBuf());
893 if (log_) {
894 ASSERT_EQ("4 unwind pop {d31-d46}\n", GetFakeLogPrint());
895 } else {
896 ASSERT_EQ("", GetFakeLogPrint());
897 }
898 ASSERT_EQ(0x100b0U, exidx_->cfa());
899 }
900
TEST_P(ArmExidxDecodeTest,pop_vfp_vpush)901 TEST_P(ArmExidxDecodeTest, pop_vfp_vpush) {
902 // 11001001 sssscccc: Pop VFP double precision registers d[ssss]-D[ssss+cccc] by VPUSH
903 data_->push_back(0xc9);
904 data_->push_back(0x00);
905 ASSERT_TRUE(exidx_->Decode());
906 ASSERT_FALSE(exidx_->pc_set());
907 ASSERT_EQ("", GetFakeLogBuf());
908 if (log_) {
909 ASSERT_EQ("4 unwind pop {d0}\n", GetFakeLogPrint());
910 } else {
911 ASSERT_EQ("", GetFakeLogPrint());
912 }
913 ASSERT_EQ(0x10008U, exidx_->cfa());
914
915 ResetLogs();
916 data_->push_back(0xc9);
917 data_->push_back(0x23);
918 ASSERT_TRUE(exidx_->Decode());
919 ASSERT_FALSE(exidx_->pc_set());
920 ASSERT_EQ("", GetFakeLogBuf());
921 if (log_) {
922 ASSERT_EQ("4 unwind pop {d2-d5}\n", GetFakeLogPrint());
923 } else {
924 ASSERT_EQ("", GetFakeLogPrint());
925 }
926 ASSERT_EQ(0x10028U, exidx_->cfa());
927
928 ResetLogs();
929 data_->push_back(0xc9);
930 data_->push_back(0xff);
931 ASSERT_TRUE(exidx_->Decode());
932 ASSERT_FALSE(exidx_->pc_set());
933 ASSERT_EQ("", GetFakeLogBuf());
934 if (log_) {
935 ASSERT_EQ("4 unwind pop {d15-d30}\n", GetFakeLogPrint());
936 } else {
937 ASSERT_EQ("", GetFakeLogPrint());
938 }
939 ASSERT_EQ(0x100a8U, exidx_->cfa());
940 }
941
TEST_P(ArmExidxDecodeTest,pop_vfp8_vpush)942 TEST_P(ArmExidxDecodeTest, pop_vfp8_vpush) {
943 // 11010nnn: Pop VFP double precision registers D[8]-D[8+nnn] by VPUSH
944 data_->push_back(0xd0);
945 ASSERT_TRUE(exidx_->Decode());
946 ASSERT_FALSE(exidx_->pc_set());
947 ASSERT_EQ("", GetFakeLogBuf());
948 if (log_) {
949 ASSERT_EQ("4 unwind pop {d8}\n", GetFakeLogPrint());
950 } else {
951 ASSERT_EQ("", GetFakeLogPrint());
952 }
953 ASSERT_EQ(0x10008U, exidx_->cfa());
954
955 ResetLogs();
956 data_->push_back(0xd2);
957 ASSERT_TRUE(exidx_->Decode());
958 ASSERT_FALSE(exidx_->pc_set());
959 ASSERT_EQ("", GetFakeLogBuf());
960 if (log_) {
961 ASSERT_EQ("4 unwind pop {d8-d10}\n", GetFakeLogPrint());
962 } else {
963 ASSERT_EQ("", GetFakeLogPrint());
964 }
965 ASSERT_EQ(0x10020U, exidx_->cfa());
966
967 ResetLogs();
968 data_->push_back(0xd7);
969 ASSERT_TRUE(exidx_->Decode());
970 ASSERT_FALSE(exidx_->pc_set());
971 ASSERT_EQ("", GetFakeLogBuf());
972 if (log_) {
973 ASSERT_EQ("4 unwind pop {d8-d15}\n", GetFakeLogPrint());
974 } else {
975 ASSERT_EQ("", GetFakeLogPrint());
976 }
977 ASSERT_EQ(0x10060U, exidx_->cfa());
978 }
979
TEST_P(ArmExidxDecodeTest,expect_truncated)980 TEST_P(ArmExidxDecodeTest, expect_truncated) {
981 // This test verifies that any op that requires extra ops will
982 // fail if the data is not present.
983 data_->push_back(0x80);
984 ASSERT_FALSE(exidx_->Decode());
985 ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status());
986
987 data_->clear();
988 data_->push_back(0xb1);
989 ASSERT_FALSE(exidx_->Decode());
990 ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status());
991
992 data_->clear();
993 data_->push_back(0xb2);
994 ASSERT_FALSE(exidx_->Decode());
995 ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status());
996
997 data_->clear();
998 data_->push_back(0xb3);
999 ASSERT_FALSE(exidx_->Decode());
1000 ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status());
1001
1002 data_->clear();
1003 data_->push_back(0xc6);
1004 ASSERT_FALSE(exidx_->Decode());
1005 ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status());
1006
1007 data_->clear();
1008 data_->push_back(0xc7);
1009 ASSERT_FALSE(exidx_->Decode());
1010 ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status());
1011
1012 data_->clear();
1013 data_->push_back(0xc8);
1014 ASSERT_FALSE(exidx_->Decode());
1015 ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status());
1016
1017 data_->clear();
1018 data_->push_back(0xc9);
1019 ASSERT_FALSE(exidx_->Decode());
1020 ASSERT_EQ(ARM_STATUS_TRUNCATED, exidx_->status());
1021 }
1022
TEST_P(ArmExidxDecodeTest,verify_no_truncated)1023 TEST_P(ArmExidxDecodeTest, verify_no_truncated) {
1024 // This test verifies that no pattern results in a crash or truncation.
1025 MemoryFakeAlwaysReadZero memory_zero;
1026 Init(&memory_zero);
1027
1028 for (size_t x = 0; x < 256; x++) {
1029 if (x == 0xb2) {
1030 // This opcode is followed by an uleb128, so just skip this one.
1031 continue;
1032 }
1033 for (size_t y = 0; y < 256; y++) {
1034 data_->clear();
1035 data_->push_back(x);
1036 data_->push_back(y);
1037 if (!exidx_->Decode()) {
1038 ASSERT_NE(ARM_STATUS_TRUNCATED, exidx_->status())
1039 << "x y = 0x" << std::hex << x << " 0x" << y;
1040 ASSERT_NE(ARM_STATUS_READ_FAILED, exidx_->status())
1041 << "x y = 0x" << std::hex << x << " 0x" << y;
1042 }
1043 }
1044 }
1045 }
1046
TEST_P(ArmExidxDecodeTest,eval_multiple_decodes)1047 TEST_P(ArmExidxDecodeTest, eval_multiple_decodes) {
1048 // vsp = vsp + 4
1049 data_->push_back(0x00);
1050 // vsp = vsp + 8
1051 data_->push_back(0x02);
1052 // Finish
1053 data_->push_back(0xb0);
1054
1055 ASSERT_TRUE(exidx_->Eval());
1056 if (log_) {
1057 ASSERT_EQ("4 unwind vsp = vsp + 4\n"
1058 "4 unwind vsp = vsp + 12\n"
1059 "4 unwind finish\n", GetFakeLogPrint());
1060 } else {
1061 ASSERT_EQ("", GetFakeLogPrint());
1062 }
1063 ASSERT_EQ(0x10010U, exidx_->cfa());
1064 ASSERT_FALSE(exidx_->pc_set());
1065 }
1066
TEST_P(ArmExidxDecodeTest,eval_pc_set)1067 TEST_P(ArmExidxDecodeTest, eval_pc_set) {
1068 // vsp = vsp + 4
1069 data_->push_back(0x00);
1070 // vsp = vsp + 8
1071 data_->push_back(0x02);
1072 // Pop {r15}
1073 data_->push_back(0x88);
1074 data_->push_back(0x00);
1075 // vsp = vsp + 8
1076 data_->push_back(0x02);
1077 // Finish
1078 data_->push_back(0xb0);
1079
1080 process_memory_.SetData32(0x10010, 0x10);
1081
1082 ASSERT_TRUE(exidx_->Eval());
1083 if (log_) {
1084 ASSERT_EQ("4 unwind vsp = vsp + 4\n"
1085 "4 unwind vsp = vsp + 12\n"
1086 "4 unwind pop {r15}\n"
1087 "4 unwind vsp = vsp + 12\n"
1088 "4 unwind finish\n", GetFakeLogPrint());
1089 } else {
1090 ASSERT_EQ("", GetFakeLogPrint());
1091 }
1092 ASSERT_EQ(0x10020U, exidx_->cfa());
1093 ASSERT_TRUE(exidx_->pc_set());
1094 ASSERT_EQ(0x10U, (*exidx_->regs())[15]);
1095 }
1096
1097 INSTANTIATE_TEST_CASE_P(, ArmExidxDecodeTest, ::testing::Values("logging", "no_logging"));
1098
1099 } // namespace unwindstack
1100